7

declarative_authorization、CanCan、CanTangoを見てきました。それらはすべてアプリケーションに承認を追加するのに優れていますが、モデルの特定のインスタンスに承認を追加するにはどうすればよいのでしょうか。つまり、1つのプロジェクトで管理アクセス権を持ち、制限されているだけです(管理よりも少ない読み取り:制限された更新など)別ので。

もっと良い方法をお願いしますか?私の質問が些細なことのように聞こえたら、お詫びします。RoRが初めてのせいかもしれません。

ありがとう、ジョン

4

2 に答える 2

4

CanCanとdeclarative_authorizationを知っていて、両方でロールベースの承認を実装したので、CanCanをお勧めします。ちょうど私の2セント。

(テストされていませんが、残念ながらここではテストできず、コードにアクセスできません)

したがって、次のような構造があるとしましょう。

class User < ActiveRecord::Base
  belongs_to :role
end

class Role < ActiveRecord::Base
  has_many :users

  # attributes: project_read, project_create, project_update
end

次に、CanCanは次のようになります。

class Ability
  include CanCan::Ability

  def initialize(user)
    @user = user
    @role = user.role

    # user can see a project if he has project_read => true in his role
    can :read, Project if role.project_read? 

    # same, but with create
    can :create, Project if role.project_create?

    # can do everything with projects if he is an admin
    can :manage, Project if user.admin?
  end

end

必要なすべての情報は、githubのCanCanwikiにあります。読むための個人的な推奨事項:

基本的には、上記の例を拡張して、関係を通じて自分の役割を含める必要があります。簡単にするために、で追加のヘルパーメソッドを作成することもできますability.rb

あなたが陥る可能性のある主な平均的な警告(少なくとも私はそうします):ユーザーができないことを定義する前に、ユーザーがモデルで何かをできることを確認ください。そうでなければ、あなたはイライラしてそこに座って、「しかし、なぜですか?私はユーザーにできないことを書いたことがない」と思うでしょう。うん。しかし、あなたは彼ができることを明示的に書いたこともありません...

于 2012-01-18T07:10:42.110 に答える
0
class User < ActiveRecord::Base

  belongs_to :role
  delegate :permissions, :to => :role
  
  def method_missing(method_id, *args)
    if match = matches_dynamic_role_check?(method_id)
      tokenize_roles(match.captures.first).each do |check|
        return true if role.name.downcase == check
      end
      return false
    elsif match = matches_dynamic_perm_check?(method_id)
      return true if permissions.find_by_name(match.captures.first)
    else
      super
    end
  end
  
  
  private

  def matches_dynamic_perm_check?(method_id)
    /^can_([a-zA-Z]\w*)\?$/.match(method_id.to_s)
  end
  
  def matches_dynamic_role_check?(method_id)
    /^is_an?_([a-zA-Z]\w*)\?$/.match(method_id.to_s)
  end
 
  def tokenize_roles(string_to_split)
    string_to_split.split(/_or_/)
  end
  
end

使用法:

user.is_an?管理者

user.can_delete?

于 2012-01-18T21:50:11.900 に答える