我正在使用扩展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