2013-02-22 61 views
3

我刚刚开始在轨道上的红宝石,并有一个更复杂的查询一个问题。到目前为止,我在查看导轨指南时做了简单的查询,并且它工作得非常好。从轨道上的ruby执行查询正确的方式

现在我试图从数据库中获取一些Ids,我会使用这些Ids来获得真实的对象并对它们做些什么。获取这些比简单的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管理该查询时,这会给我1000个IDS。我想先获得id列表,然后通过id查找对象。

有没有办法通过使用此查询直接获取这些对象?避免ID查找?我用Google搜索,你可以这样执行查询:

ActiveRecord::Base.connection.execute(query); 

回答

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命令,并可能有助于您的调试。

+0

感谢您的回复我得到这个错误'缺少表的“FROM-clause条目”quotas“'。我在哪里错过了,你能告诉吗? – 2013-02-22 08:41:01

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) 

如果你来的Rails有人用来书写原始SQL,你可能会更好过使用这种语法不是串在一起一堆ActiveRecord的方法 - 的结果是一样的,所以它只是一个你事找到更多可读性。

顺便说一句,你不应该在SQL查询中使用字符串插值(即#{variable}语法)。使用 '?'语法(请参阅我的示例)以避免SQL注入潜力。