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_createまたはafter_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

何かを変更しても、すでに行われafter_saveているため、保存されません。save介入する唯一のチャンスは、トランザクション全体をロールバックすることです。saveに別のものを追加after_saveすると、無限ループになります。

于 2012-10-11T08:16:50.977 に答える
1

データベースに対して2つのクエリを実行して再帰を心配する代わりに、サーバーに送信する前にデータペイロードを変更することを検討することをお勧めします。

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 に答える