web-dev-qa-db-fra.com

Rails validant des valeurs dans un tableau

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?

21
bsiddiqui

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
24
mechanicalfish

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
5
Paul Richter

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.

0
Rafael Biriba