Protecting associations with Protector

101 Views Asked by At

I want to use Protector to control the fields that unauthorized users can see on my models but I'm having trouble using it to hide associations.

I have a project model and a post model. They partially look like this.

class Project < ActiveRecord::Base
  has_many :posts
  protect do
    can :read, %w(title)
    cannot :read, %w(posts)
  end

end

class Post < ActiveRecord::Base
  belongs_to :project
  protect do
    cannot :read
  end
end

Now let's say I create some records that look like this

Project.create(title: 'project one')
User.create(email: '[email protected]')
Post.create(project_id: Project.first.id, title: 'post one')
Post.create(project_id: Project.first.id, title: 'post two')

When I ask for Project.first.restrict!(User.first).posts I get a non-empty ActiveRecord relation. I can't access the titles of the objects in the relation, but I can see their IDs and how many posts there are. I'd rather be able to restrict access to the Project object so that no posts are returned at all. Is this possible with Protector or should I look for another solution?

1

There are 1 best solutions below

0
On

The thing here is that you misuse it :). You shouldn't try to make your association unreadable since it's not realy a value in terms of ActiveRecord. It's a Relation.

So to make things work – you have to use scopes. Add proper scope {} to your Post model. Then when you call .posts on Project it will give you a Relation of Posts restricted by the same user. And the described scope {} of Post model will apply as well.

Again: don't try to describe associated models – use their own protection block to define their independent behavior. This is how encapsulation works for Protector.