Поиск форумов на основе разрешений пользователя - PullRequest
2 голосов
/ 27 марта 2009

Я внедряю систему форумов под названием rBoard. Код доступен для просмотра в http://github.com/radar/rboard. Я зашел в тупик с кодом разрешений, который я пытался реализовать, и я решил обратиться к всезнающему, постоянно заботящемуся переполнению стека, чтобы решить эту проблему .

Соответствующая информация, таким образом:

Категория модели

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, то оно считается глобальным для всего. Я в полном недоумении.

1 Ответ

0 голосов
/ 28 марта 2009

Похоже, вам нужно что-то вроде (фиктивного) actions_as_perptable. Некоторый миксин, который можно применять к различным типам объектов - в данном случае к группам и пользователям - который позволяет вам проверять авторизацию. Возможное использование может быть:


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

ВНИМАНИЕ: Это код воздуха ! Никогда не проверял. Но вы можете смешать что-то подобное с вашим пользователем и авторизоваться для тех же ролей, что и модель вашей группы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...