1

我正在尝试创建一个 Rails 3 模型范围,本质上是:

scope :published, where(:published => true)

scope :viewable_by, lambda { |user| where(:user_id => user.id).or(published) }

问题是,我无法找到一种方法来完成这项工作。

我曾希望 arel_table 能工作,但它抱怨它“无法访问 ActiveRecord::Relation”:

where(arel_table[:user_id].eq(user.id)).or(published)

这可以通过将“已发布”范围复制为 Arel 来完成,但随后我将重复代码(在我的项目中,“已发布”范围更深入)。

我能想到的最好的是:

scope :viewable_by, lambda { |user| where("(user_id = ?) OR (#{published.where_values.collect(&:to_sql).join(" AND ")})", user.id) }
4

1 回答 1

0

这是经过一番挖掘后我能想到的最短的:

scope :published, where(:published => true)
scope :viewable_by, lambda { |user| where("user_id = ? OR #{published.where_clauses.first}", user.id) }

(当然它只适用于单个 where 子句;join如果有多个子句,则使用 a。)

我建议使用像MetaWhere这样的 gem,它可以更清楚地展示 Arel 的一些基础。这是上面链接的主页中创建 OR 查询的示例:

Article.where(:title.matches % 'Hello%' | :title.matches % 'Goodbye%').to_sql
 => SELECT "articles".* FROM "articles" WHERE (("articles"."title" LIKE 'Hello%'
    OR "articles"."title" LIKE 'Goodbye%'))
于 2011-03-16T04:42:39.490 回答