【问题标题】:belongs_to touch: true not fired on association.build and nested attribute assignmentbelongs_to touch: true 未在关联构建和嵌套属性分配时触发
【发布时间】:2017-09-27 12:39:45
【问题描述】:

OpenProject 应用程序中,我们有两个模型:

CustomField

class CustomField < ActiveRecord::Base
  has_many :custom_options, -> { order(position: :asc) }, dependent: :delete_all
  accepts_nested_attributes_for :custom_options
  ...
end

CustomOption

class CustomOption < ActiveRecord::Base
  belongs_to :custom_field, touch: true
  ...
end

然后在custom field controller我们通过批量赋值修改自定义字段的选项并保存记录:

@custom_field.attributes = get_custom_field_params

if @custom_field.save 
  ...

因为touch: true 是在CustomOption 中的custom_field 关联上配置的,所以我预计自定义字段的updated_at 属性此时会更新,但是这不会发生。该日志没有显示任何类似于UPDATE custom_fields SET update_at = .... 的SQL 请求。对自定义选项本身的更改,无论是添加自定义选项还是修改自定义选项,都会正确保留。

调试显示:

  • 使用custom_field.custom_options.build 和后续custom_field.save 时出现相同的错误行为
  • 使用custom_field.custom_options.create 时的期望行为
  • 使用CustomOption.create custom_field: x 时的期望行为
  • 使用custom_field.custom_option[x].destroy 时的期望行为

我知道我可以通过定义after_save 回调来解决这个问题,但是这种行为真的让我很恼火,因为它是出乎意料的。

上述行为是否需要并记录在案?如果是这样,我在哪里可以找到这些信息?

【问题讨论】:

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


    【解决方案1】:

    问题是,如果父模型有任何after_commit 回调(可能还有其他一些),:touch 在自动保存关联记录时停止工作,即使回调没有做任何事情。

    您的CustomField 模型有来自acts_as_list gem 的after_commit 回调。这打破了:touch

    https://github.com/rails/rails/issues/26726 也有类似的问题。该问题与accepts_nested_attributes_for 有关,但我确信accepts_nested_attributes_for 与它无关,至少在您的情况下是这样。

    由问题作者 (@ulferts) 添加:

    CustomField 中的custom_options 关联上定义inverse_of: 'custom_field' 似乎可以绕过未知原因的问题。

    has_many :custom_options,
             -> { order(position: :asc) }, 
             dependent: :delete_all,
             inverse_of: 'custom_field'
    

    【讨论】:

    • 非常感谢@chumakoff,您的分析很到位。也感谢您的链接。 after_save 回调它,然后。我其实也有同样的怀疑,但只是停用了孩子(CustomOption)上的acts_as_list
    • 发现可以通过在has_many关联上定义inverse_of来规避问题。我向答案发送了一个编辑请求。
    • 谢谢!我批准了请求)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多