Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Specifying and Executing Rules in Ruby

I am looking for a Ruby/Rails tool that will help me accomplish the following:

I would like to store the following string, and ones similar to it, in my database. When an object is created, updated, deleted, etc., I want to run through all the strings, check to see if the CRUD event matches the conditions of the string, and if so, run the actions specified.

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

I am planning to create an interface that builds these strings, so it doesn't need to be a human-readable string. If a JSONish structure is better, or a tool has an existing language, that would be fantastic. I'm kinda thinking something along the lines of:

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

So basically, I need the following:

  1. Monitor CRUD events - It would be nice if the tool had a way to do this, but Ican use Rails' ModelObservers here if the tool doesn't natively provide it

  2. Find all matching "rules" - This is my major unknown...

  3. Execute the requested method/parameters - Ideally, this would be defined in my Ruby code as classes/methods

Are there any existing tools that I should investigate?

Edit:

Thanks for the responses so far guys! I really appreciate you pointing me down the right paths.

The use case here is that we have many different clients, with many different business rules. For the rules that apply to all clients, I can easily create those in code (using something like Ruleby), but for all of the client-specific ones, I'd like to store them in the database. Ideally, the rule could be written once, stored either in the code, or in the DB, and then run (using something Resque for performance).

At this point, it looks like I'm going to have to roll my own, so any thoughts as to the best way to do that, or any tools I should investigate, would be greatly appreciated.

Thanks again!

like image 740
Topher Fangio Avatar asked Dec 16 '22 10:12

Topher Fangio


1 Answers

I don't think it would be a major thing to write something yourself to do this, I don't know of any gems which would do this (but it would be good if someone wrote one!)

I would tackle the project in the following way, the way I am thinking is that you don't want to do the rule matching at the point the user saves as it may take a while and could interrupt the user experience and/or slow up the server, so...

  1. Use observers to store a record each time a CRUD event happens, or to make things simpler use the Acts as Audited gem which does this for you.

1.5. Use a rake task, running from your crontab to run through the latest changes, perhaps every minute, or you could use Resque which does a good job of handling lots of jobs

  1. Create a set of tables which define the possible rules a user could select from, perhaps something like

Table: Rule

Name

ForEvent (eg. CRUD)

TableInQuestion

  • FieldOneName

  • FieldOneCondition etc.

MethodToExecute

You can use a bit of metaprogramming to execute your method and since your method knows your table name and record id then this can be picked up.

Additional Notes

The best way to get going with this is to start simple then work upwards. To get the simple version working first I'd do the following ...

  1. Install acts as audited
  2. Add an additional field to the created audit table, :when_processed
  3. Create yourself a module in your /lib folder called something like processrules which roughly does this

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

  4. Now create a rules table which simply has a name and condition statement, perhaps add a few sample ones to get going

    Name: First | Rule Statement: 'SELECT 1 WHERE table.value = something'

  5. Adapt your new processrules method to execute that sql for each changed entry (perhaps you want to restrict it to just the tables you are working with)

  6. If the rule matched, add it to your log file.

From here you can extrapolate out the additional functionality you need and perhaps ask another question about the metaprogramaming side of dynamically calling methods as this question is quite broad, am more than happy to help further.

I tend to think the best way to go about task processing is to setup the process nicely first so it will work with any server load and situation then plug in the custom bits.

like image 193
creativetechnologist Avatar answered Dec 31 '22 02:12

creativetechnologist