我刚开始使用ruby on rails并且有一个关于更复杂查询的问题。到目前为止,我在查看rails指南时已经完成了简单的查询,并且效果非常好。
现在我正在尝试从数据库中获取一些ID,我会使用这些ID获取真实对象并使用它们执行某些操作。获取它们比简单的Object.find方法复杂一点。
以下是我的查询的样子:
select * from quotas q, requests r
where q.id=r.quota_id
and q.status=3
and r.text is not null
and q.id in
(
select A.id from (
select max(id) as id, name
from quotas
group by name) A
)
order by q.created_at desc
limit 1000;
从sql manager执行此查询时,这会给我1000个ID。我想先获取id列表然后按id找到对象。
有没有办法直接使用此查询获取这些对象?避免ID查找?我用谷歌搜索你可以执行这样的查询:
ActiveRecord::Base.connection.execute(query);
答案 0 :(得分:3)
假设Quota has_many :requests
,
Quota.includes(:requests).
where(status:3).
where('requests.text is not null').
where("quotas.id in (#{subquery_string_here})").
order('quotas.created_at desc').limit(1000)
我绝不是专家,但是大多数基本的SQL功能都融入了ActiveRecord。您可能还想查看#group
和#pluck
方法,以了解消除丑陋字符串子查询的方法。
在关系对象上调用#to_sql
将显示与其等效的SQL命令,并可能有助于您的调试。
答案 1 :(得分:0)
我会使用find_by_sql。我不会发誓这是完全正确的,但是我记得你几乎可以将一个SQL语句发送到find_by_sql中,结果列将作为你调用它的类的对象数组的属性返回:
status = 3
Quota.find_by_sql('
select *
from quotas q, requests r
where q.id=r.quota_id
and q.status= ?
and r.text is not null
and q.id in
(
select A.id from (
select max(id) as id, name
from quotas
group by name) A
)
order by q.created_at desc
limit 1000;', status)
如果你像过去编写原始SQL的人一样来到Rails,你可能最好使用这种语法,而不是将一堆ActiveRecord方法串在一起 - 结果是一样的,所以这只是你发现更多的问题可读的。
顺便说一句,你不应该在SQL查询中使用字符串插值(即#{variable}语法)。使用 '?'而不是语法(参见我的示例)以避免SQL注入潜力。