【问题标题】:Query data from two associated tables从两个关联表中查询数据
【发布时间】:2013-01-11 23:39:39
【问题描述】:

对于我的应用:

  • 用户有_许多图像,图像属于_用户
  • 图像有_一个位置,位置属于图像

也许位置的字段应该只是图像的一部分。但无论如何,我正在尝试在 Rails 中编写此查询:

    SELECT image.caption, location.latitude, location.longitude 
    FROM   image, location 
    WHERE  location.image_id = image.id 
    AND    image.user_id = 5

或者,如果更容易的话:

    SELECT  image.*, location.*
    FROM    image, location
    WHERE   location.image_id = image.id 
    AND     image.user_id = 5

如何将其写为 ActiveRecord 查询?

【问题讨论】:

    标签: sql ruby-on-rails rails-activerecord


    【解决方案1】:

    我想你想了解Eager Loading Associations

    @images = Image.includes(:location).where("images.user_id = ?", 5)
    

    这将找到Image 的实例user_id = 5。然后它运行第二个查询,将 JOIN 并构建关联的 Location 实例(这就是 .includes(:location) 将为您做的)

    这更符合您的替代查询,因为它确实选择了 imageslocation 表中的所有列。

    您可以基于此构建一个数组,其中包含一个仅包含您感兴趣的键的哈希。

    @hash_object = @images.collect { |i| { caption: i.caption, latitude: i.location.latitude, longitude: i.location.longitude } }
    

    如果您只想使用单个查询来构建它,您可以将.joins(:location).includes(:location) 结合使用

    Image.joins(:location).includes(:location).where("images.user_id = ?", 5)
    

    重要提示:这将省略没有关联LocationImage 实例。您可以稍微修改joins() 来帮助解决这个问题,但上面会有这个遗漏。


    如果您真的只想选择特定的列,请在 Selecting Specific Columns 上阅读,尽管有使用该列的警告

    如果使用select方法,所有返回的对象都是只读的。

    请小心,因为这也意味着您正在初始化一个模型对象,其中仅包含您选择的字段。


    在 Rails master 中(不在 3.2.11 中),您可以将 多个列 传递给 .pluck(),但这似乎仅限于单个表 (您不会从Image 采摘时能够获得locations 表的:latitude:longitude。不过很高兴知道。

    【讨论】:

    • 谢谢,这行得通!比之前发生的循环中的查询要好得多。我注意到在日志中它仍然在两个查询中分别查询 Location 和 Image 表;我想知道是否有办法解决这个问题。再次感谢您的帮助!
    • 为您更新了我的答案。如果解决了您的问题,请接受/投票赞成我的回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-23
    • 1970-01-01
    • 1970-01-01
    • 2016-08-04
    • 1970-01-01
    相关资源
    最近更新 更多