Указание и выполнение правил в Ruby - PullRequest
4 голосов
/ 26 августа 2011

Я ищу инструмент Ruby / Rails, который поможет мне выполнить следующее:

Я хотел бы сохранить следующую строку и подобные ей в моей базе данных. Когда объект создается, обновляется, удаляется и т. Д., Я хочу выполнить все строки, проверить, соответствует ли событие CRUD условиям строки, и, если это так, запустить указанные действия.

When a new ticket is created and it's category=6 then notify user 1234 via email

Я планирую создать интерфейс, который строит эти строки, так что это не обязательно должна быть читаемая человеком строка. Если структура JSONish лучше или у инструмента есть существующий язык, это было бы замечательно. Я вроде думаю что-то вроде:

{
  object_types: ['ticket'],
  events: ['created', 'updated'],
  conditions:'ticket.category=6',
  actions: 'notify user',
  parameters: {
    user:1234,
    type:'email'
  }
}

Итак, мне нужно следующее:

  1. Мониторинг событий CRUD - Было бы неплохо, если бы у инструмента был способ сделать это, но я могу использовать здесь ModelObservers Rails, если инструмент изначально не предоставляет его

  2. Найти все подходящие "правила" - Это мой главный неизвестный ...

  3. Выполнить запрошенный метод / параметры - В идеале это будет определено в моем коде Ruby как классы / методы

Существуют ли какие-либо инструменты, которые я должен исследовать?

Edit:

Спасибо за ответы, ребята! Я действительно ценю, что вы указали мне правильный путь.

В данном случае мы используем много разных клиентов со многими различными бизнес-правилами. Для правил, которые применяются ко всем клиентам, я легко могу создать их в коде (используя что-то вроде Ruleby), но для всех специфичных для клиента я бы хотел сохранить их в базе данных. В идеале правило может быть записано один раз, сохранено либо в коде, либо в БД, а затем запущено (используя что-то Resque для производительности).

На данный момент, похоже, мне придется кататься самостоятельно, поэтому любые мысли о том, как лучше всего это сделать, или любые инструменты, которые я должен исследовать, будут с благодарностью.

Еще раз спасибо!

Ответы [ 3 ]

7 голосов
/ 30 августа 2011

Я не думаю, что было бы важно написать что-то для этого самостоятельно, я не знаю ни одного драгоценного камня, который бы это делал (но было бы хорошо, если бы кто-то написал его!)

Я бы рассмотрел проект следующим образом, я думаю, что вы не хотите выполнять сопоставление правил в тот момент, когда пользователь сохраняет данные, так как это может занять некоторое время и может прервать взаимодействие с пользователем и / илизамедлите работу сервера, так что ...

  1. Используйте наблюдатели для сохранения записи каждый раз, когда происходит событие CRUD, или для упрощения используйте Acts as Audited gem , который делаетэто для вас.

1,5.Используйте задачу rake, запускаемую из вашего crontab, чтобы проходить через последние изменения, возможно каждую минуту, или вы можете использовать Resque , который хорошо справляется с большим количеством заданий

Создайте набор таблиц, которые определяют возможные правила, из которых пользователь может выбрать, например что-то вроде

Таблица: Правило

Имя

ForEvent (например,CRUD)

TableInQuestion

  • FieldOneName

  • FieldOneCondition и т. Д.

MethodToExecute

Вы можете использовать немного метапрограммирования для выполнения вашего метода, и так как ваш метод знает ваше имя таблицы и идентификатор записи, то это можно получить.

Дополнительные примечания

Лучший способ начать это - начать с простого, а затем работать вверх.Чтобы сначала работала простая версия, я бы сделал следующее ...

  1. Установка действует как проверенный
  2. Добавить дополнительное поле в созданную таблицу аудита: when_processed
  3. Создайте в своей папке / lib модуль, называемый чем-то вроде processrules, который примерно делает это

    3.1. Захватывает все необработанные записи аудита. 3.2 Отмечает их как обработанные (возможно, создайте еще одну небольшую таблицу аудита на этом этапе.для записи происходящих событий)

  4. Теперь создайте таблицу правил, в которой просто есть оператор имени и условия, возможно, добавьте несколько примеров для начала работы

    Имя: Первая |Заявление правила: «SELECT 1 WHERE table.value = что-то»

  5. Адаптируйте новый метод processrules для выполнения этого sql для каждой измененной записи (возможно, вы хотите ограничить его только таблицами, которые вы

  6. Если правило соответствует, добавьте его в файл журнала.

Отсюда вы можете экстраполировать дополнительные функции, которые вынужно и, возможно, задать еще один вопрос о стороне метапрограммирования динамически вызываемых методов, так как этот вопрос довольно широк, я более чем рад помочь в дальнейшем.

Я склонен думать, что лучший способ выполнить обработку задач - это настроитьсначала этот процесс хорош, поэтому он будет работать с любой нагрузкой на сервер и ситуацией, затем подключите пользовательские биты.

3 голосов
/ 30 августа 2011

Вы можете сделать это достаточно абстрактным, чтобы вы могли указать произвольные условия и правила, но тогда вы будете разрабатывать фреймворк / движок, а не решать конкретные проблемы вашего приложения.

Есть хорошийвероятность того, что использование ActiveRecord :: Observer решит ваши потребности, поскольку вы можете жестко закодировать все различные типы условий, которые вы ожидаете, а затем только поместить неизвестные в базу данных.Например, скажем, вы знаете, что у вас будут люди, которые следят за категориями, затем создайте ассоциацию, например category_watchers, и используйте следующий наблюдатель:

class TicketObserver < ActiveRecord::Observer
  # observe :ticket # not needed here, since it's inferred by the class name

  def after_create(ticket)
    ticket.category.watchers.each{ |user| notify_user(ticket, user) }
  end

  # def after_update ... (similar)

  private

  def notify_user(ticket, user)
    # lookup the user's stored email preferences
    # send an email if appropriate
  end
end

Если вы хотите сохранить настройки электронной почты вместе стот факт, что пользователь наблюдает за категорией, затем используйте модель соединения с флагом, указывающим на это.

Если вы хотите затем абстрагироваться от этого на шаг дальше, я бы предложил использовать нечто вроде treetop для генерации самих наблюдателей., но я не уверен, что это добавляет больше значения, чем абстрагирование подобных наблюдателей в коде.

2 голосов
/ 30 августа 2011

Есть сообщение Ruby & Rules Engines SO * , в котором может быть некоторая информация, которая может оказаться полезной.Есть еще один движок правил на основе Ruby, который вы также можете изучить - Ruleby .

Надеюсь, что это поможет вам начать расследование.

...