【问题标题】:Triggers/Callbacks in Ruby on RailsRuby on Rails 中的触发器/回调
【发布时间】:2009-12-17 22:24:08
【问题描述】:

我们正在使用 Ruby on Rails 创建一个系统,并且我们希望能够为我们的用户提供一些关于在某些预定义触发器发生时可能发生的通知和操作的控制权。此外,我们计划迭代​​导入的数据,并允许我们的用户根据这些数据配置一些操作和触发器。

让我举几个例子来更好地说明:

Trigger                              - Action
------------------------------------------------------------------------
New Ticket is Created                - User receives an e-mail
New Ticket Parsed for Keyword 'evil' - Ticket gets auto-assigned to a
                                       particular group
User Missed 3 Meetings               - A ticket is automatically created

理想情况下,我们希望某些触发器是可配置的。例如,最后一个示例可能让您配置在操作发生之前错过了多少次会议。

我想知道什么模式可以帮助我在 Ruby on Rails 中处理这种事件/回调情况。此外,触发器和动作可能是可配置的,但它们将是预定义的;那么,它们应该被硬编码还是存储在数据库中?

任何想法将不胜感激。谢谢!

更新 1: 看了之后发现 SO 上的徽章系统有些相似,基于这些标准,我想做这个动作。它略有不同,但我希望能够轻松添加新标准和操作并将它们呈现给用户。对此有什么想法吗?

【问题讨论】:

    标签: ruby-on-rails design-patterns triggers callback


    【解决方案1】:

    我认为您正在寻找的是观察者。 在您的示例中,观察者可以处理第一个和第三个示例(但不能处理第二个示例,因为观察者只观察对象,而不与它交互,即使在技术上是可行的)。

    一些代码来说明我的意思:

    class TicketObserver < ActiveRecord::Observer
      def after_create(ticket)
        UserMailer.deliver_new_ticket_notification
      end
    end
    
    class UserObserver < ActiveRecord::Observer
      def after_update(user)
        Ticket.new if user.recently_missed_a_meeting and user.missed_meetings > 3
      end
    end
    

    然后将观察者添加到 environment.rb

    config.active_record.observers = :user_observer, :ticket_observer
    

    当然,您必须填写missed_meetings 的逻辑,但需要提及一个细节。 由于 after_update 将在每次更新用户后触发,recently_missed_a_meeting 属性很有用。我通常遵循restful-authentication的想法,并且每次我想触发该行时都会设置一个实例变量为true。这可以在回调或某些自定义逻辑中完成,具体取决于您如何跟踪会议。

    对于第二个示例,我会将其放在 before_update 回调中,也许将关键字放在查找表中,以让用户更新哪些词应该触发移动到特定组。

    【讨论】:

    • 谢谢,这是我要找的一半。我还想了解人们对存储这些观察者并将其呈现给用户的想法。有什么想法吗?
    • 据我了解,观察者或多或少是一个模型,因此可以向用户显示某种设置,并查看它们是否启用或禁用。例如,我通常在我的应用程序中有一个设置类,它被称为UserMailer.deliver_new_ticket_notification if Setting['mailer.new_tickets.enabled']
    • 例如,对于最后一个示例,您可以使用user.missed_meetings &gt; Setting['users.allowed_meetings_to_miss'] 代替user.missed_meetings &gt; Setting['users.allowed_meetings_to_miss'],甚至将其存储在用户模型中以允许每个用户进行自定义。
    • 感谢您的信息。我会稍微处理一下并发布我使用的解决方案:-)
    • 不是数据库级别的触发器,而这是应用程序级别的触发器吗?这是否意味着您的应用程序必须通过从数据库中提取数据,然后将其发送回来来完成这项工作。触发器会更有效吗?我错了吗?
    【解决方案2】:

    你应该看看 Rails 中的“回调”方法

    有关文档,请参阅 - Callbacks

    您的第一条规则将通过 after_create 方法实现。

    如果您希望它们是可配置的,我建议使用模型/表来存储可能的操作并在回调中进行查找。

    如果这是大容量,请务必考虑缓存配置,因为它最终会在每个回调上进行数据库查找。

    【讨论】:

      【解决方案3】:

      也许像状态机这样的东西可以提供帮助。为 RoR 尝试 AASM gem。

      【讨论】:

      • 我不确定我是否真的了解状态机如何提供帮助。你能详细说明一下吗?
      • 拥有状态机不是回调的解决方案,而是更多的架构方法。为“Ticket”类定义状态,每个状态都会有一个 pre-和 post- 回调,这些回调会在每次状态更改时执行。这消除了代码中的大量 if/else 语句,并为特定对象的所有“逻辑”转换提供了单一入口点。
      猜你喜欢
      • 2016-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-11
      相关资源
      最近更新 更多