Search code examples
ruby-on-railsrubyactiverecordarel

Dynamic query builder stack too deep for Arel query Rails


I am looking for a way to construct a big dynamic query in Rails and applying an update to the given ActiveRecord relationship:

For example:

my_big_set = Set.new(big_array)
to_update_relationship = my_big_set.reduce(none) do |query, values_to_check|
                            where('condition = ? and condition_two = ?', values_to_check[:first], values_to_check[:two]).or(query)
                         end
    
to_update_relationship.update_all(field_to_update: true)

It works well when to_update_relationship is not too big. But if it gets bigger then the reduce output triggers a SystemStackError: stack level too deep error when it constructs the Arel query.

Is there a clever way to workaround it? (other than splitting the input or increasing the ruby system stack size).

Thanks

PS: using rails 6 and ruby 2.7


Solution

  • my solution finally is:

    my_big_set = Set.new(big_array)
    subquery = '(condition = ? and condition_two = ?)'
    query = Array.new(my_big_set, subquery).join(' OR ')
    query_values = my_big_set.map do |values_to_check|
       [values_to_check[:first], values_to_check[:two]]
    end.flatten
    
    where(query, *query_values).update_all(field_to_update: true)
    

    that way, we construct:

    1. the SQL query
    2. the values to pass to where()
    3. we still use active record where() in order to be protected from injection etc...

    And this fixes the limit!