新手问题 Activerecord 怎么实现 left join 的 on 后面加更多条件?

fan124 · 2017年06月11日 · 最后由 fan124 回复于 2017年06月11日 · 3410 次阅读

Activerecord 怎么实现 left join 的 on 后面加更多条件?

class Maker < ApplicationRecord
  has_many :cars

  scope :with_cars, -> { eager_load(:cars) }
end

class Car < ApplicationRecord
  bolongs_to :maker
end

当我用 makers = Maker.with_cars 时有没有办法传参数给这个scope,
并且得到类似以下的SQL,我希望能给on多加几个条件

SELECT
     ....
FROM makers
LEFT OUTER JOIN cars
     ON makers.id = cars.maker_id
     AND cars.company_id = '我传的参数1'
     AND cars.status = '我传的参数2'
WHERE
     .....

给自己回复一个、好像 activerecord 不能解决稍微复杂一点的 sql、用 arel 写又太难读、直接写 sql 又不好写动态的 sql、然后找到了一个叫 baby_squeel 的 gem、好像还可以、还没试

A.joins("LEFT JOIN B ON b.id = a.b_id")
Maker.includes(:cars).where(car: {company_id: 'param1', status: 'param2'})

company_id 如果有对应 model 的话还可以

Maker.includes(:cars).where(car: {company: company, status: 'param2'})
qinix 回复

这样条件应该会加在 where 从句上吧

easonlovewan 回复

这个不知道会不会有 N+1 的问题,我回去试试

scope :with_cars, -> (**opt) { eager_load(:cars).where(cars: opt) }

使用:

Maker.with_cars company_id: [1,2,3], status: ['ok']

好像只要是 where,都会加在 where 从句里,不会在 on 条件后面

fan124 回复

ON clause 用来定 join condition,WHERE clause 用来定 filter condition,这才是正确的,你为什么要把 filter 写在 ON 里呢

在 left join 时,加在 on 后面和加在 where 的结果是有区别的,假如说现在业务上有这个需求,activerecord 有没有提供一种写法可以实现,我知道 has many 或 belongs to 后面加 scope 可以实现,但是好像传不了参数.....

需要 登录 后方可回复, 如果你还没有账号请 注册新账号