【问题标题】:Active Record - Doing a join on a query result [duplicate]Active Record - 对查询结果进行连接 [重复]
【发布时间】:2014-10-02 23:42:27
【问题描述】:

我想做这样的事情,但是没有用。

@events = Event.where(date:'10/10/2014')
@venues = Venue.joins(@events)

我知道正确的语法是Venue.joins(:events),但这会将所有事件与一个venue_id 连接起来,它是每一个事件。我想获取与特定事件子集相关的所有场地。

【问题讨论】:

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


    【解决方案1】:

    根据您的问题,我假设每个Event 都有一个Venue。要查找一组活动的所有场地,请使用:

    @events = Event.where(date: '10/10/2014')
    @venues = Venue.where('id IN(?)', @events.map(&:venue_id))
    

    map 方法将事件集合转换为它们的venue_ids 数组。 如果您想避免在数据库之外提取场地 ID 对性能造成影响,此代码可能会更有帮助:

    @venues = Venue.where('id IN(SELECT events.venue_id FROM events WHERE date = ?)', '10/10/2014')
    

    【讨论】:

      【解决方案2】:

      这是对我刚刚找到的 Arvoreniad 答案的补充。另一个有效,但与这种纯粹的主动记录解决方案相比似乎有点 hacky:

      Venue.joins(:events).where(events: {id: @events})
      

      【讨论】:

        【解决方案3】:

        仅仅为了获得场地而实例化一系列事件是非常低效的。我会这样做:

        @venues = Venue.joins(:events).where(events: {date: '10/10/2014'})
        

        【讨论】:

        • 你是对的。但在我的特定用例中,我将@events 用于几个不同的目的,因此由于它已经实例化,因此将其用于连接是有意义的。为了得到明确的答案,我还简化了问题。 @events 受到多个可变范围的影响,而不是简单地按特定日期查询。
        • 我明白了。如果您知道在加载事件时需要场地,您还可以执行Event.includes(:venue).where("...") 之类的操作来触发相关场地的急切加载。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-02
        • 2011-10-22
        • 2013-02-27
        • 1970-01-01
        • 2013-05-14
        相关资源
        最近更新 更多