I'm implementing a forum system called rBoard. Code is viewable at http://github.com/radar/rboard. I've reached an impasse with the permissions code that I've been trying to implement and I've decided to turn to the all-knowing, ever-caring Stack Overflow to solve this issue.
Relevant information is thusly:
Category model
class Category < ActiveRecord::Base
has_many :permissions
has_many :groups, :through => :permissions
has_many :forums
end
Forum model
class Forum < ActiveRecord::Base
has_many :permissions
has_many :groups, :through => :permissions
belongs_to :category
end
Group model
class Group < ActiveRecord::Base
has_many :group_users
has_many :users, :through => :group_users
belongs_to :owner, :class_name => "User"
end
Permission model
class Permission < ActiveRecord::Base
belongs_to :forum
belongs_to :category
belongs_to :group
end
User model
class User < ActiveRecord::Base
include Rboard::Permissions
has_many :group_users
# Note: I am using nested_has_many_through
has_many :groups, :through => :group_users
has_many :permissions, :through => :groups
end
Permissions module
module Rboard::Permissions
THINGS = ['forum', 'category']
def self.included(klass)
klass.class_eval do
# Here we can pass an object to check if the user or any the user's groups
# has permissions on that particular option.
def overall_permissions(thing = nil)
conditions = if thing.nil?
THINGS.map do |t|
"permissions.#{t}_id " + (thing.nil? ? " IS NULL" : "= #{thing.id}") + " OR permissions.#{t}_id IS NULL"
end.join(" AND ")
else
association = thing.class.to_s.downcase
"permissions.#{association}_id = #{thing.id} OR permissions.#{association}_id IS NULL"
end
permissions.all(:conditions => conditions)
end
def can?(action, thing = nil)
permissions = overall_permissions(thing)
!!permissions.detect { |p| p.send("can_#{action}") }
end
end
end
end
Hopefully with this you should be able to figure out the fields in the permissions table are like can_see_forum
and so on. Extra fields are forum_id
, category_id
and default
(default is currently unused)
What I want to know is, how can I find all the forums a group can see? Generally if a forum_id is set, then that permission applies. If there is only one permission for that group without specifying a forum_id or category_id then it is seen to be global to everything. I'm completely at a loss here.