【问题标题】:accepts_nested_attributes_for, reject_if and has_one relationship not working together?accept_nested_attributes_for、reject_if 和 has_one 关系不能一起工作?
【发布时间】:2014-03-15 13:56:59
【问题描述】:

在我的模型中

has_one :order, dependent: :destroy

accepts_nested_attributes_for :order, reject_if: lambda { |order| order[:description].blank? }, allow_destroy: true

由于某种原因,虽然拒绝_if 被测试并返回 true(我用调试器检查过),但嵌套顺序并没有被破坏。

网上有很多关于这种现象的文章,但我找不到解决办法。

有人知道如何解决这个问题吗?

【问题讨论】:

  • 模型是否触发after_destroy回调?如果是这样,您可以在该回调中销毁相关的order
  • 在没有描述的情况下只销毁订单,而不是对象本身!
  • accepts_nested_attributes_for 不是这样工作的。如果模型具有description,您的代码允许模型设置/更新order 关系。如果您设置_destroy 属性,它还允许销毁order。根据docs,如果您尝试破坏order 关系,它将忽略reject_if。转到您的代码:您是否尝试在Order 模型中设置validates_presence_of :description
  • 我不明白:对于has_many,这就像我现在使用的一样,但是对于has_one,这不起作用? has_one 不被认为是“最多有一个”?
  • 你的Order 模型是什么样的?

标签: ruby-on-rails activerecord ruby-on-rails-3.2


【解决方案1】:

我终于在这个特定场合创建了一个智能的“reject_if”设置销毁标志,如Destroy on blank nested attribute 中所述,但是,按照我自己的规范,这不是很“红宝石”,所以无法想象没有更好的解决方案...

accepts_nested_attributes_for :order, allow_destroy: true, reject_if: lambda { |attributes|
  exists = attributes['id'].present?
  empty = attributes[:description].blank?
  attributes.merge!({_destroy: 1}) if exists and empty
  return (!exists and empty)
}

【讨论】:

  • 没有关于这个主题的消息? 2018年我还是有同样的烦恼has_one
【解决方案2】:

来自nested_attributes API

您还可以设置一个 :reject_if 过程,如果它们未能通过您的标准,则静默忽略任何新记录哈希。

params = { member: {
  name: 'joe', order_attributes: [
    { description: 'Kari, the awesome Ruby documentation browser!' },
    { description: 'The egalitarian assumption of the modern citizen' },
    { description: '', _destroy: '1' } # this will be ignored
  ]
}}

任何带有空白description 的哈希都将被完全忽略,即使它具有_destroy 标志。

如果要删除描述为空白的记录,我可以想到两种解决方案

选项 1:在您的模型中通过回调删除它们:

before_save :remove_orders_without_description

def remove_orders_without_description
  orders.select{|o| o.description.blank?}.each(&:delete)
end

选项2:删除模型定义中的reject_if选项,并在视图中使用JS来适当设置_delete属性

【讨论】:

  • 那么我宁愿使用我自己的回答中描述的非红宝石方式...之前保存,就我自己的感觉而言,在这个过程中为时已晚...
【解决方案3】:

试试这个

accepts_nested_attributes_for :order, reject_if: lambda { |order| order[:_destroy].blank? && order[:description].blank? }, allow_destroy: true

【讨论】:

  • 试过这个,但不起作用......我终于构建了一些“工作”的东西,但根据我的说法不是很红:看看我自己的答案!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
相关资源
最近更新 更多