Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if ActiveRecord::Relation alread includes JOIN

I'm inside method that adds filter (user.type) to my query/relation.

Sometimes if grouping by the user (which needs INNER join to users table in another module) is selected before filtering I receive an error:

PostgreSQL: PG::DuplicateAlias: ERROR: table name "users" specified more than once

Before error happen JOIN is already in query -

$ pry> relation.to_sql
SELECT \"posts\".* FROM \"posts\"
INNER JOIN users ON users.id = posts.user_id
WHERE \"posts\".\"created_at\" BETWEEN '2019-05-01 00:00:00'
AND '2020-05-01 23:59:59' AND \"users\".\"type\" = 'Guest'"

I wanna fix it, by checking if the table is already joined inside my ActiveRecord::Relation object. I added:

def join_users
  return relation if /JOIN users/.match? relation.to_sql

  relation.joins('LEFT JOIN users ON users.id = posts.user_id')
end

This solution works, but I wonder - is there any better way to check if JOIN is inside relation?

like image 248
eudaimonia Avatar asked Apr 26 '26 05:04

eudaimonia


2 Answers

Perhaps you can use joins_values, which isn't documented, but is an ActiveRecord_Relation public method that returns an array containing the name of the table the current query (object) is constructed with:

Post.joins(:user).joins_values # [:user]
Post.all.joins_values          # []
like image 127
Sebastian Palma Avatar answered Apr 28 '26 19:04

Sebastian Palma


if simple join

 Post.joins(:user)

you can find via joins_values

so it will look like Post.joins(:user).joins_values # [:user]

if post has left joins

Post.left_joins(:user) 

you can find via left_outer_joins_values

So in this case if you write Post.joins(:user).joins_values # [] so you can fix it by writing Post.joins(:user).left_outer_joins_values # [:user]

like image 40
Arvind Avatar answered Apr 28 '26 17:04

Arvind



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!