我想这样做:
Aquarium
.select(:id, :name, :yr_built, 'fishes.name')
.joins(:fishes)
.where(fishes: {name: "Nemo"})
.order('fishes.bday DESC')
目前按预期工作,因为我放入了原始SQL代码。然而,因为我被告知使用原始SQL是一个不好的做法,让你打开漏洞,我想用适当的ActiveRecord语法重构选择和订单行。
我知道在.where
中,您可以使用table_name: {column_name: "value"}
语法从连接表中查找值。我知道如果我想按水族箱表中的一列排序,我可以这样做:.order(col_name: :desc)
,因为水族箱是开始的表。但是,当我尝试将其添加到.order
时,这似乎不起作用:.order(fishes: {bday: :desc})
我也不确定如何从原始SQL转换.select
中的'fishes.name'
,因为它也来自join表。
您的解决方案中没有任何风险。即使当你使用一些字符串参数的ActiveRecord -没有地方把SQL注入那里。只需将'fishes.name'
更改为'fishes.name AS fish_name'
,即可在结果中保留两个名称。
然而,如果你喜欢sql字符串自由的解决方案(像我一样),你可以使用Arel来填充这样的东西。
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)