Defining and Enforcing Rules in Ruby

I am looking for a Ruby / Rails tool to help me do the following:

I would like to save the following line in my database and similar ones. When an object is created, updated, deleted, etc., I want to run all the lines, check if the CRUD event matches the conditions of the line, and if so, run the indicated actions.

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

I plan to create an interface that builds these lines, so it should not be human-readable. If the JSONish framework is better or the tool has an existing language, that would be fantastic. I am thinking a bit about something like:

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

Basically, I need the following:

  • CRUD event monitoring . It would be nice if the tool had a way to do this, but I can use Rails ModelObservers here if the tool does not provide it naturally

  • Finding all the relevant β€œrules” is my main unknown ...

  • Execute the requested method / parameters . Ideally, this will be defined in my Ruby code as classes / methods.

Are there any existing tools that I should research?

Edit:

Thanks for the answers so far guys! I really appreciate you pointing me on the right path.

An example of use here is that we have many different customers with many different business rules. For the rules that apply to all clients, I can easily create them in code (using something like Ruleby), but for all client ones, I would like to store them in a database. Ideally, a rule can be written once, saved either in code or in a database, and then executed (using Resque to improve performance).

At the moment, it seems to me that I will have to turn off on my own, so we will be very grateful for any thoughts on how to do this or what tools I should explore.

Thanks again!

+4
source share
3 answers

I don’t think it would be very important to write something yourself to do it, I don’t know any gems that will do it (but it would be nice if someone wrote one!)

I would consider the project as follows, since I think that you do not want to negotiate the rules at a point that the user saves, as this may take some time and may interrupt the user and / or slow down the server, therefore ...

  • Use observers to keep a record every time a CRUD event occurs, or to simplify the use of the Acts as Audited gem , which does this for you.

1,5. Use the rake task running from your crontab to make the last changes, maybe every minute, or you can use Resque , which does a good job of handling a lot of tasks

  1. Create a set of tables that define the possible rules that the user can choose, perhaps something like

Table: Rule

Name

ForEvent (e.g. CRUD)

Tableinquestion

  • Fieldonenename

  • FieldOneCondition etc.

MethodToExecute

You can use a little metaprogramming to execute your method, and since your method knows your table name and record ID, then you can pick it up.

Additional notes

The best way to achieve this is to start simply and then work up. To do a simple version first, I would do the following ...

  • Set actions as verified
  • Add the added field to the created audit table: when_processed
  • Create yourself a module in the / lib folder, named just like processrules, which roughly does this

    3.1 Captures all unprocessed audit records 3.2 Marks them as processed (perhaps make another small audit table at this point to record events)

  • Now create a rule table that just has a name and condition statement, maybe add some examples to go

    Name: first | Rule: "SELECT 1 WHERE table.value = something"

  • Adapt the new processrules method to execute this sql for each modified record (perhaps you want to limit it to only the tables you work with)

  • If this is a consistent rule, add it to the log file.

From here you can extrapolate the additional functionality that you need, and perhaps ask another question about the metaprogramming side of dynamically calling methods, since this question is quite wide, I am more than happy to help further.

I am inclined to think that the best way to handle task processing is to first set up the process so that it works with any server load and situation, then connect user bits.

+7
source

You can make it abstract enough so that you can specify arbitrary conditions and rules, but then you will develop a framework / engine, and not solve the specific problems of your application.

It is a good possibility that using ActiveRecord :: Observer will solve your needs, as you can hard-code all the different types of conditions that you expect and then put unknowns into the database. For example, say you know that you will have people watching categories, then create an association such as category_watchers and use the following observer:

 class TicketObserver < ActiveRecord::Observer # observe :ticket # not needed here, since it 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 stored email preferences # send an email if appropriate end end 

If you want to keep your email preferences along with the user browsing the category, use the connection model with a flag denoting this.

If you want to distract him even further, I would suggest using something like treetop to generate the observers themselves, but I'm not sure if this adds more value than abstracting such observers in the code.

+3
source

There is a Ruby and Rules Engines SO post , which may contain some information that you may find useful. There is another Ruby-based rule engine that you can also learn, Ruleby .

Hope this helps you start an investigation.

+2
source

Source: https://habr.com/ru/post/1369203/


All Articles