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

fan124 · 发布于 2017年06月11日 · 最后由 fan124 回复于 2017年06月11日 · 556 次阅读
B44b1b

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
     .....
共收到 9 条回复
B44b1b

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

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

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

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

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

B44b1b
17671easonlovewan 回复

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

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

使用:

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

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

17727
B44b1bfan124 回复

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

B44b1b

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

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