我的模型设置如下。一切正常,除了允许空白部分记录,即使所有部分和章节字段都是空白的。
class Book < ActiveRecord::Base
has_many :parts, inverse_of: :book
accepts_nested_attributes_for :parts, reject_if: :all_blank
end
class Part < ActiveRecord::Base
belongs_to :book, inverse_of: :parts
has_many :chapters, inverse_of: :part
accepts_nested_attributes_for :chapters, reject_if: :all_blank
end
class Chapter < ActiveRecord::Base
belongs_to :part, inverse_of: :chapters
end
探索代码,:all_blank
被替换为proc { |attributes| attributes.all? { |key, value| key == '_destroy' || value.blank? } }
. 所以,我使用它而不是:all_blank
添加一些调试。看起来正在发生的事情是部件的 chapters 属性正在响应blank?
,false
因为它是一个实例化的哈希对象,即使它包含的只是另一个只包含空白值的哈希:
chapters_attributes: !ruby/hash:ActionController::Parameters
'0': !ruby/hash:ActionController::Parameters
title: ''
text: ''
它只是不打算以这种方式工作吗?
我找到了一种解决方法:
accepts_nested_attributes_for :parts, reject_if: proc { |attributes|
attributes.all? do |key, value|
key == '_destroy' || value.blank? ||
(value.is_a?(Hash) && value.all? { |key2, value2| value2.all? { |key3, value3| key3 == '_destroy' || value3.blank? } })
end
}
但我希望我错过了一种更好的方法来处理这个问题。
更新 1:我尝试重新定义blank?
,Hash
但这会导致问题。
class Hash
def blank?
:empty? || all? { |k,v| v.blank? }
end
end
更新 2:这可以:all_blank
像我预期的那样工作,但它很丑陋并且没有经过良好测试。
module ActiveRecord::NestedAttributes::ClassMethods
REJECT_ALL_BLANK_PROC = proc { |attributes| attributes.all? { |k, v| k == '_destroy' || v.valueless? } }
end
class Object
alias_method :valueless?, :blank?
end
class Hash
def valueless?
blank? || all? { |k, v| v.valueless? }
end
end
更新 3: Doh!更新 1 中有一个错字。这个版本似乎确实有效。
class Hash
def blank?
empty? || all? { |k,v| v.blank? }
end
end
这是否有太多可能导致意外后果成为可行的选择?如果这是一个不错的选择,那么这段代码应该在我的应用程序中的哪个位置存在?