Here's what I want to do:
Aquarium
.select(:id, :name, :yr_built, 'fishes.name')
.joins(:fishes)
.where(fishes: {name: "Nemo"})
.order('fishes.bday DESC')
This currently works as intended, because I put in raw SQL code. However, because I was told using raw SQL was a bad practice and leaves you open to vulnerabilities, I would like to refactor the select and order lines using the proper ActiveRecord syntax.
I know that inside a .where
, you can find values from a joined table using the table_name: {column_name: "value"}
syntax. And I know that if I wanted to order by a column in the aquariums table, I can do it like so: .order(col_name: :desc)
, because aquariums is the table that started with. But this doesn't seem to work when I try adding it to .order
like this: .order(fishes: {bday: :desc})
I am also unsure how to convert 'fishes.name'
in .select
from raw SQL, because it is also coming from the joins table.
There is no any risk in your solution. Even while you are using some string parameters for ActiveRecord - there is nowhere to put SQL injection there.
Just change 'fishes.name'
to 'fishes.name AS fish_name'
to preserve both names in results.
However if you prefer SQL-string-free solutions (like I do) you can use Arel to white something like this.
Aquarium
.joins(:fishes)
.select(:id, :name, :yr_built, Fish.arel_table[:name].as('fish_name'))
.where(fishes: { name: 'Nemo'})
.order(Fish.arel_table[:updated_at].desc)