【问题标题】:Saving blank nested models issue保存空白嵌套模型问题
【发布时间】:2014-07-20 15:30:36
【问题描述】:

我的 rails 4 应用有 3 个模型:

  1. 商店(has_many :products)
  2. 产品(has_many :product_fields 和 belongs_to :store 和 accept_nested_attributes_for product_fields
  3. Product_fields(有一个 belongs_to :product)

产品只有 store_idid 字段。 Product_fields 有 string_contenttext_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 的情况下创建新商店,模型会正确拒绝它(并且不会创建产品或产品字段)。不幸的是,问题是如果我真的 填写 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,那么是的,这是可能的。如果要使用 product_fields_attributes,请不要忘记为 Porduct 模型定义 Accepts_nested_attributes。

标签: ruby-on-rails ruby validation model


【解决方案1】:

如果您的意思是您的属性中的 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 哈希包含您需要的属性。

【讨论】:

  • 感谢您的回答。但是,如果我不想在所有 product_fields 都为空的情况下创建产品,你该怎么做?
  • 您可以使用 has_many :product_fields, inverse_of: :product 验证关联记录的存在性,请参阅本文了解更多详细信息:guides.rubyonrails.org/active_record_validations.html#presence。它应该可以解决问题
  • 我试过了,但似乎没有什么不同?
  • 您是否在产品模型中添加了 validates :product_fields, presence: true ?
  • 我尝试了编辑,但如果我将其留空(由于 validates 方法),则会出现错误消息。我想允许空白产品(意味着没有错误消息),我只是不想创建它们。
【解决方案2】:

可能是递归验证关联模型?

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

【讨论】:

  • 但我真的不想验证模型,我只是不想将它们保存为空白。
猜你喜欢
  • 1970-01-01
  • 2021-01-15
  • 1970-01-01
  • 2014-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多