2017-09-27 32 views
2

OpenProject應用程序,我們有兩種型號:belongs_to的摸:真上association.build和嵌套屬性分配沒有被解僱

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被在CustomOptioncustom_field協會我本來期望的自定義​​字段的updated_at屬性在這一點上不發生但更新配置。該日誌不顯示類似於UPDATE custom_fields SET update_at = ....的任何SQL請求。無論是添加自定義選項還是修改自定義選項,自定義選項本身的更改都會正確保留。

調試表明:

  • 相同的錯誤行爲使用時使用CustomOption.create custom_field: x
  • 的期望的行爲時使用custom_field.custom_options.create
  • 的期望的行爲時使用custom_field.custom_options.build和隨後custom_field.save
  • 的期望的行爲時custom_field.custom_option[x].destroy

我知道我可以通過定義after_save回調來解決這個問題,但是這種行爲真的令我感到厭煩,因爲這是意想不到的。

上述行爲是否符合要求並記錄在案?如果是這樣,我在哪裏可以找到這些信息?

回答

2

的問題是,如果父模型有任何after_commit回調(也許有些人),:touch停止自動保存相關記錄時,即使回調沒有做任何事情的工作。

您的CustomField模型有after_commit回調來自acts_as_list寶石。這打破了:touch

有類似問題https://github.com/rails/rails/issues/26726。這個問題與accepts_nested_attributes_for有關,但我相信accepts_nested_attributes_for與它無關,至少在你的情況下。

對這個問題的作者加(@ulferts):

CustomFieldcustom_options協會定義inverse_of: 'custom_field'似乎繞過這個問題,原因不明。

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

非常感謝@chumakoff,你的分析發現上。也感謝您的鏈接。那麼'after_save'回調就是了。我實際上有同樣的懷疑,但只關閉了子節點上的'acts_as_list'('CustomOption')。 – ulferts

+0

發現可以通過在'has_many'關聯上定義'inverse_of'來規避問題。我發送編輯請求到答案。 – ulferts

+0

感謝您的支持!我批准了這個要求) – chumakoff