在 Rails3 中,链接两个范围(ActiveRelations)时似乎存在问题,每个范围都有不同的包括:
考虑这两个范围,它们都可以自己正常工作:
第一范围:
scope :global_only, lambda { |user|
includes(:country)
.where("countries.area_id <> ?", user.area) }
Work.global_only(user) => (为了便于阅读,从 SQL 中截取字段列表)
SELECT * FROM "works" LEFT OUTER JOIN "countries" ON "countries"."id" = "works"."country_id" WHERE (countries.area_id <> 3)
现在是第二个范围:
scope :not_belonging_to, lambda { |user|
includes(:participants)
.where("participants.user_id <> ? or participants.user_id is null", user) }
Work.not_belonging_to(user) =>(为了便于阅读,从 SQL 中截取字段列表)
SELECT * FROM "works" LEFT OUTER JOIN "participants" ON "participants"."work_id" = "works"."id" WHERE (participants.user_id <> 6 or participants.user_id is null)
因此,这两个都可以单独正常工作。
现在,将它们链接在一起:
Work.global_only(user).not_belonging_to(user)
SQL:
SELECT (list of fields) FROM "works" LEFT OUTER JOIN "countries" ON "countries"."id" = "works"."country_id" WHERE (participants.user_id <> 6 or participants.user_id is null) AND (countries.area_id <> 3)
如您所见,来自第二个作用域的连接完全被忽略了。因此,SQL 在“没有这样的列“participants.user_id”上失败。如果我以相反的顺序链接范围,则将出现“参与者”加入,而“国家”加入将丢失。似乎总是第二次加入丢失。
这看起来像 ActiveRecord 的错误,还是我做错了什么,或者这是一个“功能”:-)
(PS。是的,我知道,我可以创建一个连接两个表的范围,它会正确产生我想要的结果。我已经有了。但我试图制作更小的范围,而不是可以以不同的方式链接在一起,这应该是activerecord优于直接sql的优势。)