我正在实施一个名为rBoard的论坛系统。代码可在http://github.com/radar/rboard查看。我已经用我一直在努力实现的权限代码陷入了僵局,我决定转向无所不知,持之以常的Stack Overflow来解决这个问题。
因此,相关信息是:
类别模型
class Category < ActiveRecord::Base
has_many :permissions
has_many :groups, :through => :permissions
has_many :forums
end
论坛模型
class Forum < ActiveRecord::Base
has_many :permissions
has_many :groups, :through => :permissions
belongs_to :category
end
群组模型
class Group < ActiveRecord::Base
has_many :group_users
has_many :users, :through => :group_users
belongs_to :owner, :class_name => "User"
end
权限模式
class Permission < ActiveRecord::Base
belongs_to :forum
belongs_to :category
belongs_to :group
end
用户模型
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
权限模块
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
希望有了这个,您应该能够找出权限表中的字段,如can_see_forum
等等。额外字段为forum_id
,category_id
和default
(默认当前未使用)
我想知道的是,我怎样才能找到群组可以看到的所有论坛?通常,如果设置了forum_id,则该权限适用。如果该组只有一个权限而未指定forum_id或category_id,那么它被视为对所有内容都是全局的。我在这里完全不知所措。
答案 0 :(得分:0)
看起来你需要像(虚构的)acts_as_permissible这样的东西。一些mixin可以应用于不同类型的对象 - 在本例中为组和用户 - 允许您测试授权。可能的用法可能是:
class Group
include Acts::Permissible
acts_as_permissible
end
module Acts
module Permissible
def self.acts_as_permissible
begin
Role.find(:all).each do |role|
define_method "can_#{role.access_type}?" do
self.send('has_role?', role.access_type)
end
end
# Since we're possibly running within the scope of Rake, handle the case
# where the roles table doesn't exist
rescue ActiveRecord::StatementInvalid => e
RAILS_DEFAULT_LOGGER.error "Statement invalid while adding Role methods to User. Is the Roles table present in the DB?\n" + e.inspect
end
end
end
end
警告:这是航空代码!从未测试过。但是你可以将这样的东西混合到你的用户中并使用与你的Group模型相同的角色进行授权。