2009-03-27 21 views
2

私はrBoardというフォーラムシステムを実装しています。コードはhttp://github.com/radar/rboardに表示されます。私は実装しようとしていたパーミッションコードの難しさに達しました。私は、この問題を解決するために、すべてを知っていて、思いやりのあるスタックオーバーフローに目を向けることに決めました。ユーザーの権限に基づいてフォーラムを見つける

関連情報は以下のようなものを次のとおりです。

Categoryモデル

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 

Hこれをopefullyすれば、パーミッションテーブルのフィールドはcan_see_forumのようになります。余分なフィールドはforum_id,category_idおよびdefaultです(デフォルトは現在使用されていません)

私が知りたいことは、グループが見ることのできるフォーラムをすべて見つけることです。一般に、forum_idが設定されている場合、その権限が適用されます。 forum_idまたはcategory_idを指定せずにそのグループに対して1つのアクセス権しかない場合は、すべてのものに対してグローバルであると見なされます。私は完全にここに迷っています。

答えて

0

(架空の)acts_as_permissibleのようなものが必要なようです。いくつかのミックスインは、異なる種類のオブジェクト(この場合はグループとユーザー)に適用して、承認をテストできるようにします。可能な使用法は次のようになります。


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 

警告:これは空気コードです!決してテストされません。しかし、あなたはこのようなものをあなたのユーザに混ぜて、あなたのグループモデルと同じ役割に対して権限を与えることができます。

関連する問題