Base.save、回调和观察者

发布于 2024-11-25 09:44:30 字数 838 浏览 3 评论 0原文

假设我们有模型 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一个人的夜不怕黑 2024-12-02 09:44:31

在您的示例中,如果您在一个新的且未经修改的 Champ 实例上调用 champ.winner,Champ 的实例将被提交到数据库,并且在数据库:

winner: 'me'
awesome: true
should_watch: true
loser: nil
coach: nil

如果是新记录,则调用 after_create 回调,如果不是,则调用 after_update 回调(这就是为什么 loser 会如果实例是新的则为零)。但是,因为它们只是在实例上调用 setter 方法,所以它们只会更新实例,而不会向数据库提交更多更改。

您可以在观察者或模型方法中使用 update_attribute 来提交更改,但除非您确实需要在数据库中拥有记录然后更新它,否则这是浪费的。在此示例中,如果您希望这些回调在数据库中实际设置 losercoach,那么使用 before_save创建之前

Rails 指南网站此处提供了有关回调的详细概述(如果您还没有)已经读过了。

With your example, if you called champ.winner on a new and unmodified instance of Champ, the instance of Champ would be committed to the DB and would look like this in the database:

winner: 'me'
awesome: true
should_watch: true
loser: nil
coach: nil

The after_create callback would be called if it is a new record, and if not, the after_update callback would (this is why loser 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 set loser and coach in the database, it'd be more efficient to use before_save and before_create.

The Rails guides site has a good overview of callbacks here, if you haven't read it already.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文