2017-10-30 8 views
0

私は把握しようとしているRails Pundit Policyスコープを持っています。RailsアクティブレコードOR句と祖父母プロパティ

私はこれらの3つのモデルがある場合:

User - has many stories 
Story - belongs to a user and has many chapters 
Chapter - belongs to a story 

を私はすべてのユーザーが任意の公表章またはユーザー(さえ非公表のもの)によって書かれたすべての章を表示できるようにしたいです。

私がストーリーを書いた著者であれば、自分のストーリーだけでなく、自分のストーリーのすべての章も公開することができます。しかし、誰もが私の公開されたストーリーとそれらの公開されたストーリー内の公開されたチャプターを見ることしかできません。

私はこれを試してみました:

class ChapterPolicy < ApplicationPolicy 
    class Scope < Scope 
    def resolve 
    scope.where(published: true).or(scope.where("story.user.id = ?", @user.id)) 
    end 
    end 
end 

たぶん私たちは、使用する必要があります私が読んJOINSので、私もこれを試してみました:

scope.where(published: true).or(scope.joins(:story).where(stories: { user: @user })) 

をしかし、私はエラーを取得:

Relation passed to #or must be structurally compatible. Incompatible values: [:joins, :references] 

どのように私は私が望んだことを行うためにクエリを書くことができますか?

scope.joins(story: :user).where("(stories.published = ? AND chapters.published = ?) OR stories.user_id = ?", true, true, @user.id) 

は、複数の非SQL文の道を期待していたが、まあ、誰かが非SQLの方法を知っている場合を除き、これが行います推測:

答えて

0

私は私が最終的にそれを得たと思います。

0

Arelをご覧になりましたか?

あなたはこのようなものかもしれない:あなたはこれを書くためにAREL式を使用することができます

chapters = Arel::Table.new(:chapter) 
stories = Arel::Table.new(:story) 
rel = chapters.joins(stories) 
    .where(chapters[:published].eq(true) 
    .where(stories[:published].eq(true)) 
    .or(stories[:user_id].eq(@user.id)) 
scope.where(rel) 
0

を:

Chapter.joins(story: :user) 
.where(Chapter.arel_table[:published].eq(true)) 
.where(Story.arel_table[:published].eq(true)) 
.or(Chapter.joins(story: :user).where(Story.arel_table[:user_id].eq(user.id))) 

式は、このクエリを生成すること:

SELECT "chapters".* FROM "chapters" INNER JOIN "stories" ON "stories"."id" = "chapters"."story_id" INNER JOIN "users" ON "users"."id" = "stories"."user_id" WHERE ("chapters"."published" = 't' AND "stories"."published" = 't' OR "stories"."user_id" = 1) 
関連する問題