我的rails 4应用程序有三个模型:
- Store (has_many:products)
- Product (has_many:product_fields and belongs_to:store and accepts_nested_attributes_for product_fields
- Product_fields (has一个belongs_to:product)
Product只有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为空白?
如果您的意思是在您的属性内的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 =>:params对的哈希。因此,params哈希包含您需要的属性。
可以递归验证关联模型吗?
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