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 を使用します。)

Arel の基盤の一部をより明確に公開するMetaWhereのような gem を使用することをお勧めします。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 に答える