保存空白嵌套模型问题

时间:2014-05-30 19:16:48

标签: ruby-on-rails ruby validation model

我的rails 4应用程序有3个型号:

  1. 商店(has_many:产品)
  2. 产品(has_many:product_fields和belongs_to:store和accepts_nested_attributes_for product_fields
  3. Product_fields(拥有belongs_to:product)
  4. 产品只有 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是空白的吗?。

2 个答案:

答案 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