Rails 6.1 | Is there a way to check which associations have already been joined to a scope?

91 Views Asked by At

I have a little framework for dynamically constructing queries in rails (v6.1.7.3) based upon a json request from the front-end. As the use-cases keep growing, one thing that has been a bit of a pain to manage generically is having a way to keep track of which associations have already been joined to a given query scope as well as the alias used for those associations (if applicable)

Is there a built-in mechanism that I can use to determine if a given association has already been joined? And is there a means of determining an association's alias?

Thanks!

scope = MyModel.where(...)
...
scope.joins!(:assoc)
...
# how to determine if :assoc has already been joined to scope?
2

There are 2 best solutions below

1
mechnicov On BEST ANSWER

Rails do it work for you, you don't need to check if some association is already used:

self.joins_values |= args

Here Array#| method is used. It returns the union of arrays, duplicates are removed:

ary = [1]
ary |= [1, 2]
ary |= [2, 3]
ary # => [1, 2, 3]

But you can check it with joins_values or / and left_outer_joins_value method. These methods return array of associations (symbol array) and work such way:

MyModel.joins(:assoc).where(condition).joins_values
# => [:assoc]

MyModel.where(condition).joins_values
# => []

MyModel.left_joins(:assoc).where(condition).left_outer_joins_values
# => [:assoc]

MyModel.where(condition).left_outer_joins_values
# => []

There are also includes_values, eager_load_values, preload_values methods:

MyModel.includes(:assoc).where(condition).includes_values
# => [:assoc]

MyModel.where(condition).includes_values
# => []

MyModel.eager_load(:assoc).where(condition).eager_load_values
# => [:assoc]

MyModel.where(condition).eager_load_values
# => []

MyModel.preload(:assoc).where(condition).preload_values
# => [:assoc]

MyModel.where(condition).preload_values
# => []
1
Eduardo Orestes On

You can use "method_defined?" to check if exists the associations.

  1. Check if User has_one Address Association: User.method_defined?(:address)
  2. Check if User has_many Addresses Association: User.method_defined?(:addresses)

I hope this helps you.