我正在使用Ruby on Rails 3.2.2,我正在试验Squeel gem。我想知道(在某种程度上,通过使用Squeel gem),可以在scope
子句中“直接”“添加”与where
方法相关的SQL子句。也就是说,我有:
class Article < ActiveRecord::Base
# Note: This is a scope method.
def self.created_by(user)
where(:user_id => user.id)
end
# I would like to use a scope method like the following.
#
# Note: Code in the following method doesn't work, but it should help
# understanding what I mean.
def self.scope_method_name(user)
where{ created_by(user) | ... & ... }
end
end
因此,当我运行Article.scope_method_name(@current_user).to_sql
时,它应返回如下内容:
SELECT articles.* FROM articles WHERE articles.user_id = 1 OR ... AND ...
我试过sifters但是那些(至少对我来说)打算在其他Squeel语句中使用 。也就是说,如果我声明了一个sifter,那么我就不能使用它来限定ActiveRecord
的范围,因为该sifter会返回Squeel::Nodes::Predicate
个对象而不是ActiveRecord::Relation
。
答案 0 :(得分:1)
你必须为OR操作下拉到更原始的AREL
def self.scope_method_name(user)
t = arel_table
where(
(t[:user_id].eq(user.id).or(
t[:blah].eq('otherthing')
).and([:bleh].eq('thirdthing'))
)
end
或类似的东西。
答案 1 :(得分:0)
您可以链接Article.by_author(user).by_editor()
之类的范围,但这会加入ANDs的所有条件。因此,为了解决这个问题,您可以使用Squeel编写单独的范围(不链接它们),如:
class Article < ActiveRecord::Base
scope :by_author, ->(user) { where{author_id == user.id} }
scope :by_editor, ->(user) { where{editor_id == user.id} }
scope :by_title, ->(token) { where{title =~ "%#{token}%"} }
scope :by_author_or_editor, ->(user) { where{(author_id == user.id)|(editor_id == user.id)} }
scope :by_author_or_editor_and_title, ->(user, token) { where{((author_id == user.id)|(editor_id == user.id))&(title =~ "%#{token}%")} }
end
或者你可以使用sifters:
class Article < ActiveRecord::Base
sifter :sift_author do |user|
author_id == user.id
end
sifter :sift_editor do |user|
editor_id == user.id
end
sift :sift_title do |token|
title =~ "%#{token}%"
end
scope :by_author, ->(user) { where{sift :sift_author, user} }
scope :by_editor, ->(user) { where{sift :sift_editor, user} }
scope :by_title, ->(token) { where{sift :sift_title, token} }
scope :by_author_or_editor, -> (user) { where{(sift :sift_author, user)|(sift :sift_editor, user)} }
scope :by_author_or_editor_and_title, ->(user, token) { where{((sift :sift_author, user)|(sift :sift_editor, user))&(sift :sift_title, token)} }
end
这为您提供了返回ActiveRecord :: Relation的范围,因此您可以在理论上进一步链接它们。