Ответ 1
Лучший способ проверки минимального размера коллекции:
validates :my_association, :length => { :minimum => Fixnum}
У меня есть ассоциация has_many
, которая принимает вложенные атрибуты. Мне нужно, чтобы в коллекции было не менее 1 связанного объекта, поэтому я написал специальный валидатор:
class MinimumCollectionSizeValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
if value.size < options[:size]
record.errors[attribute] << (options[:message] || "must have at least #{options[:size]} line.")
end
end
end
Модель выглядит так:
has_many :foos, :dependent=>:destroy
accepts_nested_attributes_for :foos
validates :foos, :minimum_collection_size=>{:size=>1}
Это отлично работает с созданием модели, но при обновлении не получается. @my_model.update_attributes(params[:my_model])
возвращает true, даже если все foos удалены _destroy.
Как мне заставить update_attributes
вести себя так же, как save
?
Лучший способ проверки минимального размера коллекции:
validates :my_association, :length => { :minimum => Fixnum}
SooDesuNe
Да, validates :foos, :length => {:minimum => 1, :message=>"At least one foo" }
лучше исходного, но эта же проблема все еще происходит.
Чтобы исправить это, мы можем использовать метод проверки:
validate :validate_foos
private
def validate_foos
remaining_foos = foos.reject(&:marked_for_destruction?)
errors.add :foos, "At least one foo" if remaining_foos.empty?
Надеюсь, что это поможет тем, кто столкнулся с одной и той же проблемой.
Создать валидатор:
class CollectionLengthValidator < ActiveModel::Validations::LengthValidator
def validate_each(record, attribute, value)
value = value.respond_to?(:reject) ? value.reject(&:marked_for_destruction?) : value
super(record, attribute, value)
end
end
Это проблема с удалением последней записи в коллекции.
Затем используйте в качестве стандартного средства проверки длины:
validates :foos, :collection_length => {:minimum => 1}