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