rails CanCan - Defining a permission for a nested model
I have two models:
Thread (id, title)
ThreadParticipation (id, thread_id, user_id)
I want to define something like:
can :create, ThreadParticipation if the user is a ThreadParticipation
example:
for
开发者_StackOverflow中文版 thread: (1, 'hello world')
thread_participation: (313, 1, 13) -- where 13 is the user_id
I tried:
can :create, ThreadParticipation, :thread_participations => { :user_id => current_user.id }
But that errors. Any ideas?
Thread
in general is just a bad model name, because it will clash with the Thread
class defined in Ruby. I implemented this just recently. In my example, I have forums and topics. A person shouldn't be able to create a new topic in a forum they don't have read access to.
I defined a custom permission on the Forum object called create_topic
for this:
can :create_topic, Forem::Forum do |forum|
can?(:read, forum) && user.can_create_forem_topics?(forum)
end
Where can_create_forem_topics?
is just defined on the User
model like this:
def can_create_forem_topics?(forum)
# code goes here
end
Then I just use this custom :create_topic
ability in the new
and create
actions in my TopicsController
, where @forum
is defined by a before_filter
:
authorize! :create_topic, @forum
And if I need to use it in views:
can? :create_topic, @forum
by defining a custom permission on the parent object,
I'm currently trying to achieve something similiar, but I don't have the whole sight into this. Try this:
can :create, ThreadParticipation => Thread, do |participation, thread|
# your definition here
end
This should also work without a block.
EDIT: drop the part above, that doesn't work yet in CanCan. I implemented my own solution, but it requires you to authorize controller actions manually, which is not as beautify, but more secure in my opinion.
I implemented it this way for my project: https://gist.github.com/822208
Normally you would user
user
not current_user
within ability.rb. Is this your error? As well your ability is specified incorrectly. You want
can :create, ThreadParticipation, :user_id => user.id
Note that :user_id is a property of ThreadParticipation model
精彩评论