Search code examples
ruby-on-railsparsingactiverecordlogical-operatorsruby-on-rails-6

How to generate an Active Record query from an expresssion with logical operators and parantheses ? For ex: ((A || B) && C) || !D


I am going to implement a tag system that can be associated to a model (that I'm gonna call Car for the example) as a one to many association.

The project is using Rails 6.0 and ruby 2.7

So a Car has many Tags.

The final purpose of this tag system is to be able to filter out Cars with a logical expression using these tags. For example, you would put something like this in an input:

((red || blue) && sportcar) || !suv

Out of this, i want to generate an activerecord query selecting:

  • all cars that are tagged with (red or blue) and tagged with sportcart
  • or all cars that are not tagged with suv tag

Basically this requires to parse the logical expression with parentheses taken into account and then generate a query from the result of the parsing of this expression.

I'm wondering what are the best solutions to implement that. I guess that the parsing of an expression like this would result in a tree then i would need to parse that tree again an generate my query out of this.

But maybe there is a better solution I'm not seeing here so if anybody has an input on how to do that in a proper way I'm all ears!


Solution

  • I just stumbled upon the Ransack Gem which basically does pretty much what i want.

    The only thing is that it's not parsed as a logical expression but the query is constructed out of a nested form. (see their Advanced Demo to try it out)

    Hope this helps!