Dans mon modèle Schedule, je souhaite ajouter une validation au champ: wdays, qui est un int []. Je veux seulement que les valeurs 0..6 soient valides
Valide
Schedule.wdays = [0,1,6]
Invalide
Schedule.wdays = [0,1,10]
J'ai essayé d'utiliser
validates :wdays, inclusion: { in: [0, 1, 2, 3, 4, 5, 6] }
et
validates :wdays, inclusion: { in: 0..6 }
mais ni fonctionne
Quelle est la manière appropriée de valider les valeurs d'un tableau dans votre modèle?
Je ne pense pas que les validateurs par défaut de Rails feront l'affaire, vous pouvez le faire cependant
validate :validate_wdays
def validate_wdays
if !wdays.is_a?(Array) || wdays.detect{|d| !(0..6).include?(d)}
errors.add(:wdays, :invalid)
end
end
Je ne suis pas certain qu'il existe des moyens plus simples de gérer cela dans la structure de validation Rails existante. Vous avez un cas étrange que les validateurs n'étaient pas vraiment conçus pour gérer. Vous devrez peut-être écrire un validateur personnalisé pour quelque chose comme ceci (en supposant qu'une gem d'extension de validation existante ne soit pas disponible). Quelque chose comme ça:
class ArrayInRangeValidator < ActiveModel::EachValidator
def validate_each(record, attribute, valueArray)
valueArray.each do |value|
record.errors.add "#{attribute} - #{value}", (options[:message] || "is not in the acceptable range") unless (1..6).include?(value)
end
end
end
et ensuite dans votre modèle:
class Schedule < ActiveRecord::Base
include ActiveModel::Validations
validates :wdays, :presence => true, :array_in_range => true
... other model stuff
end
J'ai créé cette gemme: https://github.com/rafaelbiriba/active_model_validates_intersection_of
En gros, vous pouvez utiliser comme:
class User < ActiveRecord::Base
DEFAULT_PERMISSION = ["read", "write", "share"]
validates_intersection_of :permission, in: DEFAULT_PERMISSION
end
et si vous essayez:
user = User.new(permission: ["read", "share"])
user.valid? #true
user = User.new(permission: ["read", "admin"])
user.valid? #false
Prendre plaisir! Les commentaires, demandes d'extraction et commentaires sont toujours les bienvenus.