我正在使用擴展ActiveRecord :: Base的幾個模型類來處理Rails應用程序。我已經在這些模型類中的一些模型類上實現了多種方法,可以用來更新數據庫內容,並且這些方法都是按照我希望它們工作的方式工作的。例如,我有一個TeamStats
類存儲各種統計值到數據庫中,我已經定義了允許我通過運用博弈結果來更新這些屬性的方法:對ActiveRecord實例進行更改我從不想提交
class TeamStats < ActiveRecord::Base
belongs_to :team
def << game_result
# Lots of stuff here to update persisted attributes for
# wins, losses, total points scored, etc
end
end
class Team < ActiveRecord::Base
has_one :stats, :class_name => TeamStats, :dependent => destroy
end
現在我發現自己想要重用邏輯但是有一些我從不想提交給數據庫的臨時數據。例如,我想重新計算使用遊戲子集的團隊的統計數據,而不是所有的統計數據。所以,我有代碼,不會是這樣的:
# relevant_game_results is an array containing game results I want considered
teams.each do |team|
new_stats = TeamStats.new(:team => team)
relevent_game_results.each do |results|
new_stats << results
end
end
# Do stuff to choose a team based on these un-persisted stats that have been
# assigned to the team
# After I'm done, through all the team_stats I created and make sure all of the
# related team model objects still reference their original team stats values
我給這家最初的計劃是修改我的模型實例,然後調用這些實例reload
當我完成了。例如:
teams.each do |team|
team.reload
end
我認爲,將工作,但我不得不這樣做對大量的對象,如果我可以,我寧願做一個操作。
看來我真正需要的是一個總是回滾而不是承諾的事務。什麼是最合適的「軌道方式」來做到這一點?我應該在transaction
區塊內做到這一點,然後在我的區塊末尾加註ActiveRecord::Rollback
?換句話說,像這樣的東西?
Team.transaction do
teams.each do |team|
new_stats = TeamStats.new(:team => team)
relevent_game_results.each do |results|
new_stats << results
end
end
# Do stuff to choose a team based on these un-persisted stats that have been
# assigned to the team
raise ActiveRecord::Rollback
end
這似乎有點「髒」我但那只是我的Java背景透進來;) 有沒有一種更簡潔的方法就是更符合Rails的方式行?
更新:事實證明,將此包裝在事務中並回滾不僅是醜陋的,看起來很難使其正常工作。因爲執行此代碼的方法本身可以在另一個事務中,並且由於ActiveRecord關係對象的某些更改傾向被自動保存,所以我不得不跳過許多環節才能使其工作。
基於接受的答案中的建議,我已經完全創建了一個新的TeamStats對象,並且從不保存它。似乎對我更好。
你能提供一個愚蠢的簡單的操作示例嗎? – 2013-03-01 02:51:51