我的rails 4应用程序有3个型号:
产品只有 store_id 和 id 字段。 Product_fields具有 string_content 和 text_content 。基本上,现在我的商店模型看起来像:
class Store < ActiveRecord::Base
has_many :products
accepts_nested_attributes_for :products, :allow_destroy => true, :reject_if => :product_empty
private
def product_empty(a)
a[:product_fields_attributes][:text_content].blank?
end
end
如果我在不填写text_content的情况下创建新商店,则模型会正确拒绝它(并且不会创建任何product或product_fields)。不幸的是,问题是,如果我实际做填写text_content,那么它仍然不会创建它。
我的rails控制台看起来像:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"nFUg4ynXYyg99rPPPoa3uO/iHP4LT1XlOz3Vm3Zm4Z0=", "store"=>{"name"=>"Test", "products_attributes"=>{"0"=>{"type_of"=>"Book", "product_fields_attributes"=>{"0"=>{"text_content"=>"test1"}}}}}, "commit"=>"Create Store"}
我的问题是:如何使用 reject_if 方法处理嵌套模型?所以,要清楚,我不想验证嵌套模型,我只是想保存产品,如果它的关联product_field text_content是空白的吗?。
答案 0 :(得分:2)
如果你的意思是你的属性中的product_fields_attributes,那么是的。
def product_empty(a)
a[:product_fields_attributes].each do |field_id, params|
return true if params[:text_content].blank?
end
return false
end
您的代码无效,因为您尝试引用:product_fields_attributes作为属性的哈希值,但在实践中它是哈希:id =&gt; :params对。因此,params hash包含您需要的属性。
答案 1 :(得分:1)
可能是递归验证关联模型吗?
class Store < ActiveRecord::Base
has_many :products, validate: true
accepts_nested_attributes_for :products, :allow_destroy => true
end
更新1: 如果需要拒绝无效记录:
class Store < ActiveRecord::Base
has_many :products, validate: true
accepts_nested_attributes_for :products, :allow_destroy => true, reject_if: :invalid?
private
def invalid?(attr)
Product.new(attr).invalid?
end
end
class Product < ActiveRecord::Base
belongs_to :store
has_many :product_fields, validate: true
validates :product_fields, :presence => true
accepts_nested_attributes_for :product_fields, :allow_destroy => true
end
class ProductField < ActiveRecord::Base
belongs_to :product
validates :string_content, :presence => true
validates :text_content, :presence => true
end
或ProductField模型中的自定义验证方法,如:
validate :require_all_fields
def require_all_fields
errors.add(:base, "required") unless ....
end