SQL或Rails 3/Arel中的作用域

SQL或Rails 3/Arel中的作用域,sql,ruby-on-rails,ruby-on-rails-3,arel,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_表能够工作,但它抱怨无法访问ActiveRecord::Relation: where(arel_table[:user_id]

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

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

scope :viewable_by, lambda { |user| where(:user_id => user.id).or(published) }
问题是,我找不到一个办法让这一切顺利进行

我曾希望arel_表能够工作,但它抱怨无法访问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) }

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

scope :published, where(:published => true)
scope :viewable_by, lambda { |user| where("user_id = ? OR #{published.where_clauses.first}", user.id) }
当然,它只适用于一个where子句;如果有多个联接,请使用联接

我建议使用像这样的宝石更清楚地暴露一些阿雷尔的基础。下面是上面链接的主页中创建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%'))