【问题标题】:ActiveRecord multiple joins through associationActiveRecord 通过关联进行多个联接
【发布时间】:2015-03-31 18:38:08
【问题描述】:

我的客户模型有很多视频,视频有很多视频活动。

我想加入视频活动以限制属于具有特定电子邮件域的客户的视频。

此代码将为我提供属于 ID 为 52 的客户的所有视频活动,但由于视频没有客户电子邮件,我需要将客户加入视频,然后执行 .where。

VideoActivity.joins(:video).where(videos: {customer_id: 52})

这是怎么做到的?执行 VideoActivity.joins(:video).joins(:customer) 给我一个错误,说 VideoActivity 没有与之关联的客户。

【问题讨论】:

    标签: sql ruby-on-rails join activerecord


    【解决方案1】:

    VideoActiviy与客户无关,你需要说客户与视频相关,那么使用活动记录的#merge比做哈希where更容易

    VideoActivity.joins(video: :customer).merge(Customer.where('some condition'))
    

    如果您在视频中有一个范围,您也可以使用它,这是一个示例

    VideoActivity.joins(video: :customer).merge(Customer.some_scope)
    

    PS:

    范围可以是

    # customer model
    scope :email_ends_with, ->(string) { where('email ilike ?', "%#{string}") }
    

    那就用吧

    VideoActivity.joins(video: :customer).merge(Customer.email_ends_with('gmail.com'))
    

    【讨论】:

    • 我需要参考客户模型上的电子邮件,而不是视频模型上的客户 ID。这就是我的问题所在。
    • 我需要按属于某个视频的视频活动进行过滤,该视频属于拥有电子邮件的客户,例如“%@gmail.com”。
    • 喜欢VideoActivity.joins(video: :customer).merge(Customer.where(email: 'some email')) ?
    • 你可以将任何返回客户的查询放在合并中,所以你可以这样做merge(Customer.where("email like '%@gmail.com'")
    • @parameter,添加了范围示例
    【解决方案2】:

    有很多方法可以做到这一点,而且都在同一个地方结束,但是使用显式 where 语句可以轻松实现这一目标。

       VideoActivity.joins(:video).where("videos.customer_id = ?", 52)
    

    【讨论】:

      【解决方案3】:

      你可以写普通的sql来获取记录

      activities = VideoActivity.joins('INNER JOIN videos ON video_activities.video_id = videos.id INNER JOIN customers ON videos.customer_id = customers.id')
      activities.where('customers.email = ?', customer_email)
      

      【讨论】:

        猜你喜欢
        • 2012-07-03
        • 2020-03-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-20
        • 1970-01-01
        相关资源
        最近更新 更多