如何为用户首选项构建可扩展的解决方案,该解决方案基于域模型的状态更改触发应用程序中的操作

时间:2017-11-19 18:11:12

标签: ruby-on-rails ruby database oop refactoring

在我的Rails应用程序中,我希望能够在存在的各种Active Record模型上监听 tate更改或回调触发器。我选择使用Rails Observer.使用Observer模式,所以我可以这样做

class Product < ActiveRecord; end 

class ProductObserver < ActiveRecord::Observer
  def after_create(product) 
     #do something here
  end

  def after_destroy(product)
    #do something here 
  end 
end 

这太棒了。但是,应用程序中的每个零售商都可以启用一个或多个设置。下面的例子

假设我们有零售商A,B,C和D

创建新产品时

零售商A配置了以下设置

  • 给我发电子邮件
  • 发送所有客户简讯
  • 发送我之前的销售报告

零售商B配置了以下设置

  • 给我发电子邮件

零售商C已配置以下设置

  • 告知我的客户有关新产品的信息

零售商D可能决定他们不希望发生任何事情

注意 ,这些设置都可以通过用户界面进行配置。

此外,我的应用程序中的各种ActiveRecord模型可以在不同的回调触发器或模型状态更改上配置各种设置。

如何对此问题进行建模,使其可扩展,可测试且无耦合?

这是我提出的一些解决方案,但是一位同事建议他们不希望在他们的班级名称中使用动词,但这是我现在看到的最佳解决方案。

class ProductObserver < ActiveRecord::Observer
  def after_create(product)
    retailer = product.retailer 
    #find user settings from db 
    # fetch all methods they want to be triggered 
    # use meta programming to tirgger that method 

    retailer.observable_event_settings.actions.each do|action| 
      klass = "ProductCreate::#{action.camelize}".constantize
      klass.notify(product)
    end 
  end
end


module ObservableEvent 
  module ProductCreate 
    class SendNewsLetter
      def self.notify(observable)
      end 
    end 

    class OfferDiscount
      def self.notify(observable)
      end 
    end 
  end 
end 

#ObservableEvents 
[
  {
    id: 1, 
    model: 'product'
    event: 'create', 
    actions: [:send_news_letter, :offer_discount]
  },
  {
    id: 2, 
    model: 'product', 
    event: 'destroy'
    actions: [:set_product_not_visible, :set_quantity_to_zero]
  }
]

#ObservableEventSettings
[
  {
    retailer_id: 1, 
    observable_event_id: 1,
    actions: [:send_news_letter] 
  },

  {
    retailer_id: 2, 
    observable_event_id: 1, 
    actions: [:send_news_letter, :offer_discount]
  }
]

这是迄今为止我能够想到的最好的。你会怎么回事?非常感谢任何帮助。

0 个答案:

没有答案