开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜