现在有一个这样的场景 查询属于我或者我所在团队的记录,于是 sql 如下:
select * from contents where publish_status = 1 and (user_id = 2 or team_id in (1,2,3));
因为这块比较通用,于是我封装成了 scope
scope :belong_to_self, ->(user,teams) { where("user_id = ? or team_id in (?) ", user.id, team.map(&:id)) }
在 controller 里 就直接 Content.published.belong_to_self(user,teams) 用了
但是 msyql 对于带有 or 的子句,索引就不起作用了,于是查了查 可以用 union all 来代替 or, 便改成下面这样 sql:
select * from contents where publish_status = 1 and user_id = 2
union
select * from contents where publish_status = 1 and team_id in (1,2,3)
但是 ActiveRecord 对于 union 这种子句支持的不好,只能用类似 find_by_sql 这种方式来查询。 这样带来的问题是 1 没法写成 scope 复用 2 在 controller 里面 用这种方式 感觉很繁琐。
很多时候麻烦都是设计的问题,是否有其他解决思路来处理 or 的这种需求?或者是怎么加索引,or 就不用改成 union?