rails has_many проверка обновления минимального размера коллекции - PullRequest
28 голосов
/ 20 декабря 2010

У меня есть 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, даже если _destroy удаляет все foos.

Как заставить update_attributes вести себя так же, как save?

Ответы [ 3 ]

73 голосов
/ 24 февраля 2011

Лучший способ проверить минимальный размер коллекции:

validates :my_association, :length => { :minimum => Fixnum}
23 голосов
/ 02 апреля 2014

SooDesuNe

Да, validates :foos, :length => {:minimum => 1, :message=>"At least one foo" } лучше, чем оригинал, но такая же проблема все еще возникает.

Чтобы исправить это, мы могли бы использовать метод validate:

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?

Надеюсь, это поможет тем, кто столкнулся с той же проблемой.

10 голосов
/ 21 марта 2016

Создать валидатор:

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}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...