问题:ActiveRecord的(rails3),链接范围与包括 [英] problem: activerecord (rails3), chaining scopes with includes

查看:104
本文介绍了问题:ActiveRecord的(rails3),链接范围与包括的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Rails3链接两个范围(ActiveRelations),每个具有不同的时似乎有一个问题包括:

In Rails3 there seems to be a problem when chaining two scopes (ActiveRelations) that each have a different include:

考虑这两个范围,这两者很好地工作在自己的:

Consider these two scopes, both of which work fine on their own:

一是适用范围:

scope :global_only, lambda { |user|
includes(:country)
.where("countries.area_id <> ?", user.area) }

Work.global_only(用户)=>(从SQL的可读性领域的切割清单)

Work.global_only(user) => (cut list of fields from SQL for legibility)

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(用户)=>(从SQL的可读性领域的切割清单)

Work.not_belonging_to(user) => (cut list of fields from SQL for legibility)

SELECT * FROM "works" LEFT OUTER JOIN "participants" ON "participants"."work_id" = "works"."id" WHERE (participants.user_id <> 6 or participants.user_id is null)

所以,这两方面的正常工作单独。

So both of those work properly individually.

现在,把它们结合在一起:

Now, chain them together:

Work.global_only(用户).not_belonging_to(用户)

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。如果我链中的作用域以相反的顺序,那么'参与者'联结将present和国家加入将会丢失。它总是第二个连接的丢失,它似乎。

As you can see, the join from the second scope is ignored altogether. The SQL therefore fails on 'no such column 'participants.user_id'. If I chain the scopes in the reverse order, then the 'participants' join will be present and the 'countries' join will be lost. It's always the second join that is lost, it seems.

这看起来像ActiveRecord的一个bug,还是我做错了什么,或者这是一个功能:-)

Does this look like a bug with ActiveRecord, or am I doing something wrong, or is this a "feature" :-)

(PS是的,我知道,我可以创建一个作用域联接两个表,它会正确地得到我想要的结果。我已经,但我试图让更小的范围比可以链接在一起,在不同的的方式,这被认为是超过了activerecord直SQL的优点。)

(PS. Yes, I know, I can create a scope that joins both tables and it will correctly yield the result I want. I have that already. But I was trying to make smaller scopes than can be chained together in different ways, which is supposed to be the advantage of activerecord over straight sql.)

推荐答案

作为一般规则,使用:包括的渴望加载和:加入的条件。在第二个范围,连接SQL必须手动写入,因为左连接是必需的。

As a general rule, use :includes for eager-loading and :joins for conditions. In the second scope, the join SQL must be manually written because a left join is required.

不过,试试这个:

scope :global_only, lambda { |user|
  joins(:country).
  where(["countries.area_id != ?", user.area])
}

scope :not_belonging_to, lambda { |user|
  joins("left join participants on participants = #{user.id}").
  where("participants.id is null")
}

Work.global_only(user).not_belonging_to(user)

这篇关于问题:ActiveRecord的(rails3),链接范围与包括的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆