17

如果我执行以下操作:

@user.name = "John"    
@user.url = "www.john.com"
@user.save

如果我使用after_save

@user.url = "www.johnseena.com"
@user.save

当我这样做时会发生什么?

我相信它应该因为“after_save”回调而保存该值。

4

5 回答 5

37

在我看来,如果你save在回调中调用函数after_save,那么它将陷入递归,除非你在开头放置一个守卫。像这样

class User < AR::Base
      after_save :change_url

      def change_url
          #Check some condition to skip saving
          url = "www.johnseena.com"
          save              #<======= this save will fire the after_save again
      end
end

但是,除了放置警卫之外,您还可以update_column使用

def change_url
    update_column(:url, "www.johnseena.com")
end

在这种情况下,它不会触发after_save。但是,它会火after_update。因此,如果您对该回调有任何更新操作,那么您将再次递归:)

于 2012-10-11T08:51:42.533 回答
7

after_save回调将被触发,无论它是对该对象的保存还是更新。

还,

update_column不会触发任何回调(即 after_update)并且也会跳过验证。请参阅http://apidock.com/rails/ActiveRecord/Persistence/update_column

U 应根据操作及其时间具体使用after_createafter_update 。

after_create :send_mail
def send_x_mail
  #some mail that user has been created
end

after_update :send_y_mail
def send_y_mail
  #some data has been updated
end

after_save :update_some_date
def update_some_data
  ...
  action which doesnt update the current object else will trigger the call_back
end

另请参阅`after_create` 和 `after_save` 之间的区别以及何时使用哪个?对于回调,请参阅http://ar.rubyonrails.org/classes/ActiveRecord/Callbacks.html#M000059

于 2012-10-11T11:19:43.150 回答
4

如果您修改任何 int ,after_save它将不会被保存,因为save它已经发生了。干预的唯一机会是回滚整个事务。如果在 中添加另一个saveafter_save那么它将是一个无限循环。

于 2012-10-11T08:16:50.977 回答
1

无需对数据库执行两次查询并担心递归,您可能需要考虑在数据有效负载进入服务器之前对其进行修改。

class User < AR::Base
      before_save :change_url

      def change_url
          url = "www.johnseena.com"
      end
end
于 2015-10-22T20:29:51.433 回答
0

非常感谢所有在这里帮助我的人。这是解决我的问题的解决方案。我按订单模型修改如下:

class Order < ActiveRecord::Base

  has_and_belongs_to_many :users

  validates :item, presence: true

  def add_order(username, order)
    user = User.where(username: username).first
    if !user.nil?
      user.orders.create(item: order.item)
    end
  end

  def remove_order(order)
  end

end
于 2016-03-28T13:02:52.557 回答