如何组合两个活动记录关系



我有模型User,User有列provider

Provider可为googlefacebooknil

我想使范围,这将输出所有的用户,除了用户的提供者googlesome time

我尝试用两个作用域来做:

scope :not_google_authorised, -> { where(provider: [nil, 'facebook']) }
scope :newest_google, -> { where(provider: 'google').where("created_at < ?", Time.now)}
...
users = User.not_google_authorised
users << User.newest_google

得到了正确的结果,但改变了users的类别。我需要users将是activerecord关系,而不是数组。I tried do:

users = User.not_google_authorised
users.merge(User.newest_google)
#or
users.or(User.newest_google)

但它不适合我。

我怎么能结合这两个范围,所以users将是activerecord关系,或者我怎么能写一个范围,而不是他们?

我使用ruby v3.3.7和rails v4.1

ActiveRecord::QueryMethods#or直到rails 5才存在。

目前稳定的ruby版本是3.0.0,这意味着你不能使用3.3.7,因为它还不存在(可能永远不会存在)。

merge将与AND(交集)合并。

所以你最好的选择是使用原始SQL或Arel,如:

where(
User.arel_table[:provider].eq(nil).or(
User.arel_table[:provider].eq('facebook')
).or(
User.arel_table[:provider].eq('google').and(
User.arel_table[:created_at].lt(Time.now)
)
)
)

结果应该是:

SELECT 
"users".*
FROM 
"users" 
WHERE 
("users"."provider" IS NULL OR "users"."provider" = 'facebook')
OR ( "users"."provider" = 'google' AND "users"."created_at" < [SOME TIME]

一种方法是这样做,不是超级优化,但可以完成工作。

not_google_auth_ids = User.not_google_authorized.ids
newest_ids = User.newest_google.ids
ids = not_google_auth_ids + newest_ids
users = User.where(id: ids)

我们可以在单个作用域中这样做:

scope: not_authorized, ->{where("(provider = ?)和created_at

最新更新