it-roy-ru.com

Rails проверка значений в массиве

В моей модели Schedule я хочу добавить некоторую проверку в поле: wdays, которое является int []. Я только хочу, чтобы значения 0..6 были действительными

Действительный

Schedule.wdays = [0,1,6]

Недействительным

Schedule.wdays = [0,1,10]

Я пытался с помощью

validates :wdays, inclusion: { in: [0, 1, 2, 3, 4, 5, 6] }

а также

validates :wdays, inclusion: { in: 0..6 }

но ни один не работает

Как правильно проверить значения в массиве в вашей модели?

21
bsiddiqui

Я не думаю, что валидаторы Rails по умолчанию здесь справятся, но вы можете сделать это:

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

Я не уверен, есть ли более простые способы справиться с этим в существующей структуре валидации Rails. У вас есть странный случай, когда валидаторы не были действительно созданы для обработки. Возможно, вам придется написать собственный валидатор для чего-то подобного (при условии, что существующий гем расширения валидации недоступен). Что-то вроде этого:

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

а затем в вашей модели:

class Schedule < ActiveRecord::Base
    include ActiveModel::Validations

    validates :wdays, :presence => true, :array_in_range => true

    ... other model stuff
end
5
Paul Richter

Я создал этот драгоценный камень: https://github.com/rafaelbiriba/active_model_validates_intersection_of

По сути, вы можете использовать как:

class User < ActiveRecord::Base
   DEFAULT_PERMISSION = ["read", "write", "share"]
   validates_intersection_of :permission, in: DEFAULT_PERMISSION
end

и если вы попробуете:

user = User.new(permission: ["read", "share"])
user.valid? #true

user = User.new(permission: ["read", "admin"])
user.valid? #false

Наслаждайтесь! Комментарии, запросы и отзывы всегда приветствуются.

0
Rafael Biriba