Base.save、回调和观察者
假设我们有模型 Champ,具有以下属性,默认值为 nil:winner、lose、coach、awesome、should_watch。
我们假设执行两个单独的操作:(1) 创建一条新记录,(2) 在 Champ 实例上调用 c.the_winner。
根据我的模拟代码和模型上的观察者,这两种情况下将哪些值保存到数据库中?我想要了解的是回调如何在 Base.save 操作的上下文中工作的原理,以及是否以及何时必须多次调用 Base.save 操作才能提交更改。
class Champ
def the_winner
self.winner = 'me'
self.save
end
def the_loser
self.loser = 'you'
end
def the_coach
self.coach = 'Lt Wiggles'
end
def awesome_game(awesome_or_not=false)
self.awesome = awesome_or_not
end
def should_watch_it(should=false)
self.should_watch = should
end
end
class ChampObserver
def after_update(c)
c.the_loser
end
def after_create(c)
c.the_coach
end
def before_create(c)
c.awesome_game(true)
c.should_watch_it(true) if c.awesome_game
end
结尾
Let us say that we have the model Champ, with the following attributes, all with default values of nil: winner, lose, coach, awesome, should_watch.
Let's assume that two separate operations are performed: (1) a new record is created and (2) c.the_winner is called on a instance of Champ.
Based on my mock code, and the observer on the model, what values are saved to the DB for these two scenarios? What I am trying to understand is the principles of how callbacks work within the context of Base.save operation, and if and when the Base.save operation has to be called more than once to commit the changes.
class Champ
def the_winner
self.winner = 'me'
self.save
end
def the_loser
self.loser = 'you'
end
def the_coach
self.coach = 'Lt Wiggles'
end
def awesome_game(awesome_or_not=false)
self.awesome = awesome_or_not
end
def should_watch_it(should=false)
self.should_watch = should
end
end
class ChampObserver
def after_update(c)
c.the_loser
end
def after_create(c)
c.the_coach
end
def before_create(c)
c.awesome_game(true)
c.should_watch_it(true) if c.awesome_game
end
end
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在您的示例中,如果您在一个新的且未经修改的
Champ
实例上调用champ.winner
,Champ 的实例将被提交到数据库,并且在数据库:如果是新记录,则调用
after_create
回调,如果不是,则调用after_update
回调(这就是为什么loser
会如果实例是新的则为零)。但是,因为它们只是在实例上调用 setter 方法,所以它们只会更新实例,而不会向数据库提交更多更改。您可以在观察者或模型方法中使用 update_attribute 来提交更改,但除非您确实需要在数据库中拥有记录然后更新它,否则这是浪费的。在此示例中,如果您希望这些回调在数据库中实际设置
loser
和coach
,那么使用before_save
和创建之前
。Rails 指南网站此处提供了有关回调的详细概述(如果您还没有)已经读过了。
With your example, if you called
champ.winner
on a new and unmodified instance ofChamp
, the instance of Champ would be committed to the DB and would look like this in the database:The
after_create
callback would be called if it is a new record, and if not, theafter_update
callback would (this is whyloser
would be nil if the instance was new). However, because they just call a setter method on the instance, they will only update the instance and will not commit more changes to the DB.You could use
update_attribute
in your observer or model methods to commit the change, but unless you actually need to have the record in the database and then update it, it's wasteful. In this example, if you wanted those callbacks to actually setloser
andcoach
in the database, it'd be more efficient to usebefore_save
andbefore_create
.The Rails guides site has a good overview of callbacks here, if you haven't read it already.