根据用户的权限查找论坛

时间:2009-03-27 09:12:15

标签: ruby-on-rails ruby

我正在实施一个名为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_idcategory_iddefault(默认当前未使用)

我想知道的是,我怎样才能找到群组可以看到的所有论坛?通常,如果设置了forum_id,则该权限适用。如果该组只有一个权限而未指定forum_id或category_id,那么它被视为对所有内容都是全局的。我在这里完全不知所措。

1 个答案:

答案 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模型相同的角色进行授权。