Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails order results with multiple joins to same table

--Edit--

I wanted to simplify this question. With this model structure:

has_one :pickup_job, class_name: 'Job', source: :job
has_one :dropoff_job, class_name: 'Job', source: :job

What I want to do is:

Package.joins(:dropoff_job, :pickup_job).order(pickup_job: {name: :desc})

This is obviously not valid, the actual syntax that should be used is:

.order('jobs.name desc')

However the way that rails joins the tables means that I cannot ensure what the table alias name will be (if anything), and this will order by dropoff_job.name instead of pickup_job.name

irb(main):005:0> Package.joins(:dropoff_job, :pickup_job).order('jobs.name desc').to_sql
=> "SELECT \"packages\".* FROM \"packages\" INNER JOIN \"jobs\" ON \"jobs\".\"id\" = \"packages\".\"dropoff_job_id\" INNER JOIN \"jobs\" \"pickup_jobs_packages\" ON \"pickup_jobs_packages\".\"id\" = \"packages\".\"pickup_job_id\" ORDER BY jobs.name desc"

Also I am not in control of how the tables are joined, so I cannot define the table alias.

--UPDATE--

I have had a play with trying to extract the alias names from the current scope using something like this:

current_scope.join_sources.select { |j| j.left.table_name == 'locations' }

But am still a little stuck and really feel like there should be a MUCH simpler solution.

--UPDATE--

pan's answer works in some scenarios but I am looking for a solution that is a bit more dynamic.

like image 995
Rick Avatar asked Feb 18 '17 00:02

Rick


1 Answers

Use the concatenation of association name in plural and current table name as a table alias name in the order method:

Package.joins(:dropoff_job, :pickup_job).order('pickup_jobs_packages.name desc')
like image 107
pan.goth Avatar answered Nov 16 '22 11:11

pan.goth