사용자 지정 권한이 예상대로 작동하지 않음

6959 단어 cancan

묘사

사용자 정의 작업이 정상적으로 작동하도록 할 수 없습니다.
나는 무슨 일이 발생할 것이라고 예상한다.
사용자는 자신의 성명을 읽고, 창설하고, 갱신하고, 삭제하고, 제출할 수 있습니다.승인 및 거부 버튼은 사용자가 승인자인 경우에만 표시됩니다.
실제 발생 상황:
승인 및 거부 버튼은 사용자에게 표시되지만 승인자에게는 표시되지 않습니다.이것은 나의 기대와 상반된다.
나는 이미 문서와 각종 기존 문제를 통독했다.나는 모든 사용자가 어떤 권한을 가지고 있는지 명확하게 밝히는 것을 포함해서 (즉, [:read, :create, :update, :destroy, :submit], :manage 몇 가지를 시도했다.이것은 사용자로 하여금 이 단추들을 잊게 하지만, 그것들은 여전히 심사 비준자에게 나타나지 않을 것이다.내가 뭘 놓쳤지?
모델/능력.rb:
class Ability
  include CanCan::Ability

  def initialize(user)
    can :read, Category
    can :manage, Claim, user_id: user.id
    cannot [:approve, :deny], Claim

    if user.has_role? :approver
      can [:read, :approve, :deny], Claim
    end
  end
end
배상 청구 통제원.rb:
class ClaimsController < ApplicationController
  # Restrict access
  load_and_authorize_resource
  skip_authorize_resource only: :new

  def index
    …
  end

  def show
    …
  end

  def new
    …
  end

  def edit
    …
  end

  def create
    …
  end

  def update
    …
  end

  def destroy
    …
  end

  ## STATE MACHINE EVENTS

  def submit
    …
  end

  def approve
    …
  end

  def deny
    …
  end
end
보기/선언/표시html.직원 재교육국
<% if can? [:approve, :deny], @claim %>
<%= link_to 'Approve this claim', approve_claim_path(@claim), class: "button gradient" if @claim.can_approve? %>
<%= link_to 'Deny this claim', deny_claim_path(@claim), class: "button red gradient" if @claim.can_deny? %>
<% end %>

토론 #1

콘솔에서 이 기능 클래스를 테스트해 보셨습니까?이것은 너에게 문제가 거기에 있는지 아니면 다른 곳에 있는지 알려줄 것이다.자세한 내용은 Debugging Abilities쪽.

토론 #2

콘솔에서 Ability 클래스를 테스트한 후에 나는 이 클래스 자체의 행위가 기대에 부합되고 권한의 설정이 응당한 방식으로 진행되는 것을 확인했지만 보기의 행위는 여전히 이상하다.콘솔에서 첫 번째 사용자를 잡았습니다. 승인자입니다.
Loading development environment (Rails 3.2.2)
irb(main):001:0> user = User.first
  User Load (0.1ms)  SELECT "users".* FROM "users" LIMIT 1
=> #<User id: 1, login: "aporter", group_strings: "Wireless, VPN Users, VPN, Wave-HC, Marketing Group,...", name: "Andrew Porter", email: "[email protected]", ou_strings: nil, auth_token: "CxKa5eF1xyEfU8IxhVdsKw", account_balance: #<BigDecimal:7fae4b7c7e18,'0.25E3',9(36)>, vision_balance: nil, created_at: "2012-03-19 21:56:43", updated_at: "2012-03-26 22:37:21">
irb(main):002:0> user.roles.map { |r| r.name }
  Role Load (0.2ms)  SELECT "roles".* FROM "roles" INNER JOIN "roles_users" ON "roles"."id" = "roles_users"."role_id" WHERE "roles_users"."user_id" = 1
=> ["admin", "approver"]
나는 이 사용자가 가지고 있는 성명을 잡았다.
irb(main):003:0> claim = Claim.find(10)
  Claim Load (4.8ms)  SELECT "claims".* FROM "claims" WHERE "claims"."id" = ? LIMIT 1  [["id", 10]]
=> #<Claim id: 10, state: "pending", total: #<BigDecimal:7fae4b1cf7e0,'0.105035E3',18(45)>, user_id: 1, batch_id: nil, created_at: "2012-03-28 20:35:03", updated_at: "2012-03-28 21:18:29">
사용자를 위한 기능 인스턴스를 만들었습니다.
irb(main):004:0> ability = Ability.new(user)
=> #<Ability:0x007fae4b1a6228 @rules=[#<CanCan::Rule:0x007fae4fd1f538 @match_all=false, @base_behavior=true, @actions=[:read], @subjects=[Category(id: integer, name: string, description: text, percentage: decimal, created_at: datetime, updated_at: datetime)], @conditions={}, @block=nil>, #<CanCan::Rule:0x007fae4fd1f2e0 @match_all=false, @base_behavior=true, @actions=[:manage], @subjects=[Claim(id: integer, state: string, total: decimal, user_id: integer, batch_id: integer, created_at: datetime, updated_at: datetime)], @conditions={:user_id=>1}, @block=nil>, #<CanCan::Rule:0x007fae4fd1efe8 @match_all=false, @base_behavior=false, @actions=[:approve, :deny], @subjects=[Claim(id: integer, state: string, total: decimal, user_id: integer, batch_id: integer, created_at: datetime, updated_at: datetime)], @conditions={:user_id=>1}, @block=nil>, #<CanCan::Rule:0x007fae4fd1e598 @match_all=false, @base_behavior=true, @actions=[:read, :approve, :deny], @subjects=[Claim(id: integer, state: string, total: decimal, user_id: integer, batch_id: integer, created_at: datetime, updated_at: datetime)], @conditions={}, @block=nil>]>
다음 권한을 부여합니다.
class Ability
  include CanCan::Ability

  def initialize(user)
    can :read, Category
    can :manage, Claim, user_id: user.id
    cannot [:approve, :deny], Claim, user_id: user.id

    if user.role? :approver
      can [:read, :approve, :deny], Claim
    end

    if user.role? :processor
      can :manage, Batch
    end

    # if user.role? :admin
    #   can :manage, :all
    # end
  end
end
다음은 이 심사 비준자가 자신의 클레임에 대해 할 수 있는 일이다.
irb(main):005:0> ability.can? :manage, claim
=> true
irb(main):006:0> ability.can? :approve, claim
=> true
irb(main):007:0> ability.can? :deny, claim
=> true
만약 내가 비준인이 가지지 못한 성명을 잡았다면:
irb(main):008:0> claim = Claim.find(11)
  Claim Load (0.2ms)  SELECT "claims".* FROM "claims" WHERE "claims"."id" = ? LIMIT 1  [["id", 11]]
=> #<Claim id: 11, state: "pending", total: #<BigDecimal:7fae4fd435f0,'0.105E3',9(36)>, user_id: 3, batch_id: nil, created_at: "2012-03-28 22:17:39", updated_at: "2012-03-28 22:24:38">
체크 아웃 중인 권한:
irb(main):009:0> ability.can? :manage, claim
=> false
irb(main):010:0> ability.can? :read, claim
=> true
irb(main):011:0> ability.can? :approve, claim
=> true
irb(main):012:0> ability.can? :deny, claim
=> true
내가 이런 동작을 결합시키지 않으면:
irb(main):013:0> ability.can? [:approve, :deny], claim
=> false
따라서 각 버튼에 체크를 개별적으로 설정하여 원하는 위치에 도달할 수 있습니다.
<%= link_to 'Approve this claim', approve_claim_path(@claim), class: "button gradient" if @claim.can_approve? && can?(:approve, @claim) %>
<%= link_to 'Deny this claim', deny_claim_path(@claim), class: "button red gradient" if @claim.can_deny? && can?(:deny, @claim) %>
주의: 나는 단추의 표시와 상태기를 연결하기 때문에 클레임이 비준할 수 있는 상태인지, 사용자가 클레임을 비준할 능력이 있는지 검사하고 있습니다.

좋은 웹페이지 즐겨찾기