gpt4 book ai didi

ruby-on-rails - 如何拒绝_if : :all_blank for accepts_nested_attributes_for work when working with doubly nested associations?

转载 作者:行者123 更新时间:2023-12-04 03:40:32 25 4
gpt4 key购买 nike

我的模型设置如下。一切正常,除了允许空白部分记录,即使所有部分和章节字段都是空白的。

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并添加一些调试。看起来正在发生的事情是该部分的章节属性正在响应 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:哦!更新 1 中有一个错字。这个版本好像可以用。
class Hash
def blank?
empty? || all? { |k,v| v.blank? }
end
end

这是否有太多可能导致意外后果成为可行的选择?如果这是一个不错的选择,那么这段代码应该放在我的应用程序中的哪个位置?

最佳答案

使用时 :all_blankaccepts_nested_attributes_for ,它将检查每个单独的属性以查看它是否为空白。

# From the api documentation
REJECT_ALL_BLANK_PROC = proc do |attributes|
attributes.all? { |key, value| key == "_destroy" || value.blank? }
end

http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

嵌套关联的属性将是一个包含关联属性的哈希。检查属性是否为空将返回 false因为哈希不是空的——它包含关联的每个属性的键。此行为将导致 reject_if: :all_blank返回 false因为嵌套关联。

要解决此问题,您可以将自己的方法添加到 application_record.rb 中,如下所示:
# Add an instance method to application_record.rb / active_record.rb
def all_blank?(attributes)
attributes.all? do |key, value|
key == '_destroy' || value.blank? ||
value.is_a?(Hash) && all_blank?(value)
end
end

# Then modify your model book.rb to call that method
accepts_nested_attributes_for :parts, reject_if: :all_blank?

关于ruby-on-rails - 如何拒绝_if : :all_blank for accepts_nested_attributes_for work when working with doubly nested associations?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19415205/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com