Ruby on rails Ruby:当相关对象上的某些内容发生变化时,对其进行修改的解决方案

Ruby on rails Ruby:当相关对象上的某些内容发生变化时,对其进行修改的解决方案,ruby-on-rails,ruby,activerecord,associations,message-queue,Ruby On Rails,Ruby,Activerecord,Associations,Message Queue,我正在研究这个需求:我有一个相当大的对象关系模型,其中实体之间有非常强的链接。让我们以这种关系为例:一栋建筑有许多公寓,公寓有许多分区。现在,我想要的是:当任何分区发生变化时,我想“通知”建筑物,或者更好的是,标记建筑物已“更新”或“修改” 当前的解决方案:我们有一个自己编写的实现,其中我们将分区标记为“影响”建筑物,并且每次分区更新时,建筑物的“修改”时间戳都将更新 理想的解决方案:一个已经存在的“开箱即用”实现(可能是一个gem、一个插件、一个God),这将省去我们重构实现的工作 不需要的

我正在研究这个需求:我有一个相当大的对象关系模型,其中实体之间有非常强的链接。让我们以这种关系为例:一栋建筑有许多公寓,公寓有许多分区。现在,我想要的是:当任何分区发生变化时,我想“通知”建筑物,或者更好的是,标记建筑物已“更新”或“修改”

  • 当前的解决方案:我们有一个自己编写的实现,其中我们将分区标记为“影响”建筑物,并且每次分区更新时,建筑物的“修改”时间戳都将更新

  • 理想的解决方案:一个已经存在的“开箱即用”实现(可能是一个gem、一个插件、一个God),这将省去我们重构实现的工作

  • 不需要的解决方案:请不要告诉我用:autosave=>true标记所有这些关联。我想要一个可排队的解决方案

当然,也欢迎不包含所需解决方案,但作为改进当前解决方案性能的建议的解决方案。如果没有理想的解决方案,我们肯定会改进现有的解决方案

小编辑:

这种行为必须是通用的。这不仅适用于建筑案例,任何有关联的模型都可能有这种行为。这将始终是相同的:获取受影响的关联并更新它们。现在,我不想用同一个例程编写不同的观察者

关于性能问题:更新的受影响关联更新还必须触发其受影响关联。现在,让我们想象一个建筑影响100个分区,每个分区影响100把椅子。现在,observer解决方案只在业务级别工作。也就是说,我必须实例化每个AR实例,以便观察者可以采取行动。我认为这是糟糕的表现。如果A影响100个Bs,我用一个DB语句来实现。但是,当我使用SQL完成所有操作时,如何触发这100个观察者呢

因此,回到主要的更新点:这种行为是通用的,最重要的是,性能必须是顶级的(例如,关联可能会触发许多关联的nxn更新)

您可以使用。在
app/models

class AuditObserver < ActiveRecord::Observer
  observe :division

  def after_update(division)
    division.logger.info('Division is updated at #{division.updated_at}')
    ######Your logic goes here 
  end
end
class AuditObserver
您可以使用。在
app/models

class AuditObserver < ActiveRecord::Observer
  observe :division

  def after_update(division)
    division.logger.info('Division is updated at #{division.updated_at}')
    ######Your logic goes here 
  end
end
class AuditObserver
所以,我解决这个问题的方法是混合了关于观察者设计模式实现的各种建议。因此,首先,该模式的基本实现都不适合我。为什么?我想让模型a的概念观察到它的关系B,B被它的关系a观察到,这个观察的例程被定义在其他地方,在一个(我们称之为)通知程序中

为什么我不能使用Ruby'observer'库?理论上我本可以做到这一点,但观察到的对象调用一个名为“changed”的方法来通知其观察者,“changed”是一个被ActiveRecord覆盖的方法,即被“dirty”库覆盖的方法

为什么我不能使用AR“观察者”?因为这里的观察者就是我想要的通知者。该例程没有在模型中实现,但我不能说必须通知哪些其他AR模型。这是一种阻碍

我是怎么解决的?我自己创建了一个库,使用ActiveModel::Observing库,它允许我实现我想要的功能。我设计的目的是我会有这个DSL:

A类
 observes :b, :on => :create, :notifiers => :update_observer
结束

这意味着,当b被创建时,有一个通知程序update_observer可以到达b和a并对其进行处理。因此,在这种情况下:

class UpdateObserverNotifier < Notifier

  def action(observable, observer)
    observer.update_attributes(updated_at: observable.updated_at)
  end
end
class UpdateObserverNotifier
DSL对observer的调用将在相应的类中注入“observer”和“observable”行为。Notifier基类将具有通知行为,并且它将能够访问observable和observer对象,以防来自observable的内容必须镜像到observer中。如果您的操作触发了对观察者的回调,它还将通知潜在的观察者该观察者本身


是的,就是这样。谢谢你的建议,否则我就做不到了

所以,我解决这个问题的方法是混合了关于观察者设计模式实现的各种建议。因此,首先,该模式的基本实现都不适合我。为什么?我想让模型a的概念观察到它的关系B,B被它的关系a观察到,这个观察的例程被定义在其他地方,在一个(我们称之为)通知程序中

为什么我不能使用Ruby'observer'库?理论上我本可以做到这一点,但观察到的对象调用一个名为“changed”的方法来通知其观察者,“changed”是一个被ActiveRecord覆盖的方法,即被“dirty”库覆盖的方法

为什么我不能使用AR“观察者”?因为这里的观察者就是我想要的通知者。该例程没有在模型中实现,但我不能说必须通知哪些其他AR模型。这是一种阻碍

我是怎么解决的?我自己创建了一个库,使用ActiveModel::Observing库,它允许我