rails has_many最小集合大小更新验证

时间:2010-12-20 03:49:33

标签: ruby-on-rails ruby-on-rails-3

我有一个has_many关联,它接受嵌套属性。我需要在集合中至少有一个关联对象,所以我写了一个自定义验证器:

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}

这在模型创建方面效果很好,但在更新时失败了。即使_destroy删除了所有foos,@my_model.update_attributes(params[:my_model])也会返回true。

如何让update_attributes的行为与save相同?

3 个答案:

答案 0 :(得分:73)

验证集合最小大小的更好方法:

validates :my_association, :length => { :minimum => Fixnum}

答案 1 :(得分:23)

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?

希望遇到同样问题的人有所帮助。

答案 2 :(得分:10)

创建验证器:

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}