Gilad Naaman
Gilad Naaman

Reputation: 6550

Using cancan to let Users manage only some models

I have a simple bulletin-board system built with rails (and devise).

I want to add cancan to the system, but I have a problem defining some rules.

In short, my application has a User model, a Forum model, and a ForumModerationModel. Code (Simplification):

class User < ActiveRecord::Base
  has_many :forum_moderations, dependent: :destroy, foreign_key: 'moderator_id'
  has_many :moderated_forums, through: :forum_moderations, source: 'moderated_forum'

class Forum < ActiveRecord::Base
  has_many :forum_moderations, dependent: :destroy

class ForumModeration < ActiveRecord::Base
  belongs_to :moderated_forum, class_name: 'Forum'
  belongs_to :moderator, class_name: 'User'

  validates_uniqueness_of :moderator_id, :scope => [:moderated_forum_id]
end

As you can see, a user can moderate N forums and a forum can be moderated by N users. My problem is:

How do I define to cancan that a user can only :manage certain forums according to these models?

I've read this article: https://github.com/ryanb/cancan/wiki/Defining-Abilities

But since my User model has no column I can use for this purpose, I'm stuck.

Upvotes: 2

Views: 105

Answers (1)

Lucas
Lucas

Reputation: 2627

As far as I understood you just have to define your condition properly. You will need current_forum variable passed to initialize method, then use it to determine if current_user has access to moderation on this forum.

def initialize(user, current_forum = nil)
  user ||= User.new # guest user (not logged in)
  if user.moderated_forums.include?(current_forum)
    # user is moderator
  else
    # user is not moderator
  end
end

You can define current_forum as before_filter method and put in controllers you want to use it or put in ApplicationController and put skip_before_filter in controllers you don't need this.

Upvotes: 1

Related Questions