什么时候放弃积极的记录?

时间:2009-08-29 17:30:25

标签: sql ruby-on-rails ruby activerecord

我不是Rails的新手,但到目前为止我还没有做过这么复杂的事情,所以我很好奇经验丰富的rails开发人员可能分享的内容:

我有一个sql查询,它将4个左右的表连接到一个输出中:

SELECT places.id, places.name, places.email, places.website, places.blurb, external_ratings.rating, photos.data_file_name
    FROM `scannables` 
    INNER JOIN places ON scannables.place_id = places.id
    INNER JOIN locations ON places.location_id = locations.id
    LEFT JOIN external_ratings ON scannables.place_id = external_ratings.place_id
    LEFT JOIN photos ON scannables.place_id = photos.place_id
    WHERE locations.id = 2474 AND scannables.bookdate BETWEEN '2009-08-29' and date_add('2009-08-29', INTERVAL 4 DAY)
    GROUP BY scannables.place_id
    HAVING SUM(scannables.available) >= 4
    ORDER BY SUM(scannables.available) DESC, external_ratings.rating DESC

我在各种模型中定义了所有表关系,并且最初只使用这些定义的关系(使用活动记录)来提取各种数据,并且它工作正常,除了主要查询是最大的是非常慢,执行多个人查询。我的问题是,我应该在这个案例中转储Active Record并使用find_by_sql ......还是我错过了什么?

什么是Rails方式?

由于

4 个答案:

答案 0 :(得分:11)

务实而不是担心维持“Rails纯度”更为重要。我喜欢命名的范围,关联以及与之相关的所有魔法。当然,我更喜欢那些运行原始SQL查询。但是,如果一个复杂的查询调用了find_by_sql,那么我将使用它而不会失去任何睡眠。

如果你需要支持多个数据库,那么你可能想把它变成纯粹的Rails方法,但这个要求很少见。

答案 1 :(得分:4)

其实我不喜欢那些答案所以我做了一点挖掘并且很幸运......

我更喜欢这个......

Place.find(:all, 
        :joins => "INNER JOIN scannables ON scannables.place_id = places.id",
        :conditions => [ "places.location_id = ? and scannables.bookdate BETWEEN ? and ?", 2474, '2009-08-29', '2009-09-02' ],
        :group => 'scannables.place_id',
        :having => 'SUM(scannables.available) >= 4')

它更简单,我仍然可以使用所有漂亮的导轨机械来获得我不需要明确的部件..即少了两个连接!

虽然......我想知道是否有办法更简化它?这个关系在scannables和places之间定义...即has_many,属于......那么为什么我还需要指定INNER JOIN ON?不应该

:joins => :scannable work?

无论如何..它不喜欢那样......

答案 2 :(得分:2)

使用

:joins => :scannables
假设您已经设置了Place#has_many:scannables关联,

应该可以工作(注意复数)。 #find的:join子选项接受字符串和命名关联。

答案 3 :(得分:0)

如果您有多个此类查询,可能需要考虑使用sequel。否则,我同意jdl。