How store business logic into database?

889 views Asked by At

I'd like to allow users to define simple business logic such as:

if (x and y) then ...
if (z or w) then ...

Let me put it concretely:

I'm developing a HR module that answers if applicants fulfill some requirements, to be defined by users.

Such requirements can be defined around logical operators:

(Must be 18 years old) or (under 18 years and must have parents permission)

Is putting this kind of logic inside the database ok? I think it is, but I'm afraid of spending time on this and find that its a poor approach.

4

There are 4 answers

0
Marcus Ilgner On

As so often, the answer is "it depends" ;) Since it seems that the logic in this case is user-defined data, putting it into the database is absolutely reasonable.

But if you are looking to model the structure/AST of this input into separate business objects with their and and or control flow reflected in the database records, I would have to say that it's very likely overkill and will - apart from the initial implementation overhead - make future refactoring very hard.

A simple text field that will be evaluated at runtime is the easiest way to go as its contents can be very easily extracted and reasoned about.

Not knowing your definitive requirements, I'd suggest you take a look at Drools, a rules engine for Java, which has in its ecosystem also a rule storage backend and guided editor. Incidentally the example in your question looks a lot like it might benefit from a rules engine but unfortunately I don't have any practical experience with any of the related Ruby libraries.

Otherwise this article on the thougtbot blog - Writing a Domain Specific Language in Ruby - might be helpful in this context, too.

0
Keith Johnson On

I definitely think it's okay. Because the user is defining the business logic or rules, I'd recommended splitting the business logic form field into parts(rule: if/unless, operand1: user.age, operand2: permissions.parental operator1: and, operator2: greater_than...) and then storing each business logic object as a row in a serialized JSON column. This should make them easier to validate and less error prone as compared to a single text field where the user to enter in whatever they like.

0
Hieu Pham On

I would suggest creating a simple table to store the logic if it is predictable.

For example:

Table: business_logics
Attributes:
opt_1: decimal
opt_2: decimal
logic_opt: integer (enum: and|or)
then_statement: string

So this is extendable when you have more logic_opt in someday, btw you can get the advantage in validation & refactoring later on! Allow users to input the free texts is so risky in your case!

0
Nick Roz On

It's ok. It is flexible approach, although time consuming in development.

Furthermore, you don't have to create your own DSL, it's already done, e.g. json-logic-ruby allows to keep complex rules in json.