【问题标题】:when to ditch active record?什么时候放弃活动记录?
【发布时间】:2009-08-29 17:30:25
【问题描述】:

我对 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 方式?

谢谢

【问题讨论】:

    标签: sql ruby-on-rails ruby activerecord


    【解决方案1】:

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

    如果您需要支持多个数据库,那么您可能希望将其硬塞到纯 Rails 方法中,但这种要求很少见。

    【讨论】:

    • 听,听! find_by_sql 是有原因的。
    • 我只关心 Rails 的纯度,因为它更好地服务于我的应用程序!这就是为什么我认为这可能是矫枉过正......
    【解决方案2】:

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

    我更喜欢这个……

    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')
    

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

    虽然...我想知道是否有办法进一步简化它?关系是在可扫描对象和地点之间定义的......即has_many,属于......那么为什么我仍然需要指定INNER JOIN ON?不应该

    :joins => :scannable work?
    

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

    【讨论】:

    • 实际上 :have 没有产生适当的效果...至少与上面的原始 sql 效果不同...我还使用了 :order => 'sum(scannables.availables )' 也不能正常工作... ;-(
    【解决方案3】:

    使用

    :joins => :scannables
    

    应该可以工作(注意复数),假设您已经建立了 Place#has_many :scannables 关联。 #find 的 :joins 选项接受字符串和命名关联。

    【讨论】:

    • :joins 和 :includes 的最大区别是什么?
    • :include 允许您指定应该预先加载的关联。 :joins 允许您指定连接发生的方式。
    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-25
      • 2015-07-31
      • 2010-10-24
      • 1970-01-01
      • 1970-01-01
      • 2011-10-14
      • 2017-11-06
      相关资源
      最近更新 更多