【问题标题】:Observing object and associated object观察对象和关联对象
【发布时间】:2013-01-23 17:48:22
【问题描述】:

如何根据关联对象是否已添加或删除来执行操作?

我系统中的每个用户都有一个外部服务的配置文件。配置文件跟踪用户的一些字段。当我的系统上更新这些字段中的一个或多个时,我会调用该服务来更新配置文件。这个电话很贵,所以我只想在必要时拨打。

每个用户都可以拥有一只宠物,在用户中表示为一个字段。用户的服务配置文件有一个标志,表示用户是否有宠物。

class User < ActiveRecord::Base
  attr_accessible :name, :shoe_size
  attr_accessible :unimportant_field1, :unimportant_field2
  has_one :pet
end

class Pet < ActiveRecord::Base
  belongs_to :user
end

class UserObserver < ActiveRecord::Observer
  observe User

  def after_create(user)
    Service.post_user(user)
  end

  def after_update(user)
    if changed(user)
      Service.put_user(user)
    end
  end

  def changed(user)
    user.name_changed? || user.shoe_size_changed? || user.pet_changed?
    # But there is no pet_changed? method!
  end
end

用户可能会像这样获得宠物:

user.build_pet
   # or
user.pet = Pet.new
user.save!

或者像这样:

pet = Pet.create :user => user

问题:

  • 没有user.pet_changed?方法; ActiveRecord::Dirty 不跟踪关联。
  • 如果用户得到了上面第二个代码片段中的宠物,则不会触发用户的观察者。我可以单独观察宠物,只需更新用户个人资料的宠物字段。但是如果我对宠物和用户都有观察者,那么在第一个代码片段中,哪个会先触发?如果宠物先开火,我是做 POST 还是 PUT?

我正在寻找一个可以遵循的好模式。也许我必须自己发明它。

【问题讨论】:

标签: ruby-on-rails ruby observer-pattern rails-activerecord


【解决方案1】:

不要使用user.pet_changed?,而是使用user.pet.changed?

【讨论】:

  • 我想要捕捉的是宠物出现或消失的时间。对象本身的变化可能是另一个问题,但主要是我需要知道 user.pet 何时从 nil 变为 non-nil,反之亦然。想法?
  • 是的。您可以做的一件事就是观察 Pet 模型。如果你只关心用户修改宠物的情况,那么你可以使用new_record?方法来检查宠物是否是新的。所以你可以做user.pet.new_record?。同样,您可以使用destroyed? 来检查对象是否已被销毁。我从未使用过破坏,因此您的里程可能会有所不同。查看 ActiveRecord::Persistence 的 API:apidock.com/rails/ActiveRecord/Persistence
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-30
  • 1970-01-01
  • 2017-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多