私が次のことをした場合:
@user.name = "John"
@user.url = "www.john.com"
@user.save
after_save
を使用する場合
@user.url = "www.johnseena.com"
@user.save
これを行うとどうなりますか?
'after_save'コールバックがあるため、値を保存する必要があると思います。
私の意見では、after_save
コールバックで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
は起動します。したがって、そのコールバックで更新操作がある場合は、再び再帰的になります:)
after_saveコールバックは、saveまたはそのオブジェクトのupdate。
また、
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
after_save
で何かを変更しても、save
はすでに実行されているため、保存されません。介入する唯一のチャンスは、トランザクション全体をロールバックすることです。 after_save
に別のsave
を追加すると、無限ループになります。
データベースに対して2つのクエリを実行して再帰を心配する代わりに、サーバーに送信する前にデータペイロードを変更することを検討することをお勧めします。
class User < AR::Base
before_save :change_url
def change_url
url = "www.johnseena.com"
end
end
ここで私を助けてくれたすべての人に感謝します。これが私の問題を解決した解決策です。注文モデルによって次のように変更しました。
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