cancanを使用してコントローラーのアクションを承認しています。cancan によってアクセスが許可されるクラスの 1 つは、acts_as_ancestryで実装されたツリーです。load_and_authorize_resource
ユーザーがルート レベルへのアクセスを許可されておらず、内部ノードからのアクセスが許可されている場合、使用に問題があります。
関連するクラス定義を次に示します。
class User < ActiveRecord::Base
belongs_to :organization, :inverse_of => :users
end
class Post < ActiveRecord::Base
belongs_to :organization, :inverse_of => :posts
end
class Organization < ActiveRecord::Base
has_ancestry :cache_depth => true
has_many :users, :inverse_of => :organization
has_many :posts, :inverse_of => :organization
end
投稿を管理するためのルールは、「自分の下の組織の投稿を管理できる」です。私のカンカン能力の定義は次のとおりです。
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new
# subtree_ids is added by acts_as_ancestry
can :manage, Post, {:organization_id => user.organization.subtree_ids}
end
end
コントローラーには、これがあります(他のアクションは省略)
class PostsController < ApplicationController
load_and_authorize_resource :post
def index
end
def new
end
end
許可されたユーザーがルート組織に属している場合、すべてが正常に機能します。ただし、内部ノードで承認されたユーザーとしてログインすると、インデックス アクションは正常に動作しますが、新しいアクションが呼び出されると、can-can 承認エラーが発生します。
ログに表示される内容は次のとおりです。
Access denied on new #<Post id: nil, organization_id: 1>
(organization_id 1
ルート)はスキーマから来ています:
create_table "posts", :force => true do |t|
t.integer "organization_id", :default => 1
end
cancan を使用すると、新しいアクションによって新しい が作成され、Post
に割り当てられ@post
ます。これを行うとcan
、Abilities.rb の定義から取得した値ですべての属性が初期化されます。ただし、これらの属性が配列、ハッシュ、または範囲であり、デフォルト値がスキーマから取得される場合は何もしません。
サブツリー内の投稿を管理する権限をユーザーに与えるにはどうすればよいですか?ただし、ユーザーが新しい投稿を作成するときは、デフォルトで組織に設定されますか?