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?
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 yourPost
model. Then when you call.posts
onProject
it will give you a Relation ofPost
s restricted by the same user. And the describedscope {}
ofPost
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.