SQL OR在Rails 3 / Arel中的范围

时间:2011-03-16 02:29:41

标签: sql ruby-on-rails ruby-on-rails-3 arel

我正在尝试创建一个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) }

1 个答案:

答案 0 :(得分:0)

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

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

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

我建议使用像MetaWhere这样的宝石更清楚地暴露一些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%'))