I've got a Rails Pundit Policy scope which I'm trying to figure out.
If I have these 3 models:
User - has many stories
Story - belongs to a user and has many chapters
Chapter - belongs to a story
I want any user to be able to view any published chapters or any chapters which were written by the user (even non-published ones).
Obviously if I am an author who wrote a story, I should be able to view my own stories as well as all my chapters for my stories, even if they are not published. Everyone else though, can only view my published stories and published chapters within those published stories.
I have tried this:
class ChapterPolicy < ApplicationPolicy
class Scope < Scope
def resolve
scope.where(published: true).or(scope.where("story.user.id = ?", @user.id))
end
end
end
Supposedly we need to use JOINS I read, so I have also tried this:
scope.where(published: true).or(scope.joins(:story).where(stories: { user: @user }))
but I get error:
Relation passed to #or must be structurally compatible. Incompatible values: [:joins, :references]
Any ideas how I can write the query to do what I wanted?
I think I finally got it:
scope.joins(story: :user).where("(stories.published = ? AND chapters.published = ?) OR stories.user_id = ?", true, true, @user.id)
Was hoping for a more non SQL statement way, but oh well, guess this will do unless someone know's the non-sql way.