我有一个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
相同?
答案 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}