【问题标题】:Why before_save/after_save is not triggered when attribute updates to nil? And how to trigger it?为什么属性更新为 nil 时不会触发 before_save/after_save?以及如何触发它?
【发布时间】:2011-04-13 00:07:12
【问题描述】:

更新:

好的。我有另一种方式来描述这一点。我正在保存一个项目,并在该项目及其所有子项上调用 Base.save。而且由于其中一些不再是这个项目的孩子,因为我没有选中它们,save 不会被调用。听起来稍微清楚一点。但这仍然是用另一个词描述的同一个问题。为什么如果记录被更新(虽然有些奇怪)并且它的 parent_id 被改变,rails 不会让它像更新一样?

================================================ ========================

我的项目与其自身具有多对一的关联。当项目更改其父项目时,我想为项目创建 cmets。当item.superitem_id 从 nil 变为某个 id 或从某个 id 变为另一个 id 时,一切正常。但是,当item.superitem_id 从某个 id 变为 nil 时,什么也没有发生。


第一种情况日志显示:

UPDATE "items" SET "superitem_id" = 3, "updated_at" = '2011-04-12 23:07:05.566609' WHERE "items"."id" = 5

在第二个中:

UPDATE "items" SET "superitem_id" = NULL WHERE "items"."superitem_id" = 3 AND "items"."id"



所以。项目肯定改变了。但是为什么它没有更新并且没有调用 before_save 呢?


型号:

class Item < ActiveRecord::Base

  before_save :generate_comments

  has_many :subitems, :class_name => "Item", :foreign_key => "superitem_id"
  belongs_to :superitem, :class_name => "Item"

  private
    def generate_comments
      @comment = self.comments.build(:content => "Test: #{self.superitem_id}")
      @comment.save
    end

end

使用“HABTM 复选框”railscast 中的复选框查看:

<% for subitem in @potential_subitems %>
  <%= check_box_tag "item[subitem_ids][]", subitem.id, @item.subitems.include?(subitem) %>
<% end %>

和控制器:

def update
  params[:item][:subitem_ids] ||= []
  @item = Item.find(params[:id])
  @item.update_attributes(params[:item])
end

【问题讨论】:

    标签: ruby-on-rails activerecord callback


    【解决方案1】:

    我的猜测是,在第二种情况下,您的 关联已保存(即使它是同一张表),因此 rails 不会将其视为“自我”的更新。检查此帖子以使用“触摸”强制对 belongs_to 进行回调:

    "Before Save" callback on associations

    【讨论】:

    • 对于 Rails 4 及以下版本,您的回调必须返回 true... 在 Rails 5 中,如果您的回调失败,您必须显式引发异常,因此回调链中止。
    猜你喜欢
    • 2015-03-23
    • 2023-03-13
    • 1970-01-01
    • 2014-06-02
    • 1970-01-01
    • 1970-01-01
    • 2012-10-18
    • 1970-01-01
    • 2014-07-20
    相关资源
    最近更新 更多