CANCANCAN拥有数据的权限

时间:2016-01-02 12:37:51

标签: ruby-on-rails cancancan

请问一个问题!

我不知道如何只允许用户更新自己的数据:

ability.rb

elsif user.has_role? :user
  can :update, User, id: user.id
else

user_controller.rb

def update
  a = Ability.new(current_user)
  user = User.find params[:id]
  if a.can? :update, User, id: user.id
  ...

对任何ID都返回true。

pry的附加数据:

  [3] pry(main)> a = Ability.new(u)
  Role Load (0.7ms)  SELECT `roles`.* FROM `roles` INNER JOIN `users_roles` ON `roles`.`id` = `users_roles`.`role_id` WHERE `users_roles`.`user_id` = 3 AND (((roles.name = 'admin') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL)))
  Role Load (0.4ms)  SELECT `roles`.* FROM `roles` INNER JOIN `users_roles` ON `roles`.`id` = `users_roles`.`role_id` WHERE `users_roles`.`user_id` = 3 AND (((roles.name = 'user') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL)))
  => #<Ability:0x007f908ba931e8
  @rules=
   [#<CanCan::Rule:0x007f908be9b2b8
     @actions=[:update],
     @base_behavior=true,
     @block=nil,
     @conditions={:id=>3},
     @match_all=false,
     @subjects=
       [User(id: integer, email: string, encrypted_password: string, reset_password_token: string, reset_password_sent_at: datetime, remember_created_at: datetime, sign_in_count: integer, current_sign_in_at: datetime, last_sign_in_at: datetime, current_sign_in_ip: string, last_sign_in_ip: string, created_at: datetime, updated_at: datetime, auth_token: string, name: string, surnames: string)]>],
     @rules_index=
       {User(id: integer, email: string, encrypted_password: string, reset_password_token: string, reset_password_sent_at: datetime, remember_created_at: datetime, sign_in_count: integer, current_sign_in_at: datetime, last_sign_in_at: datetime, current_sign_in_ip: string, last_sign_in_ip: string, created_at: datetime, updated_at: datetime, auth_token: string, name: string, surnames: string)=>
[0]}>
[4] pry(main)> a.can? :update, User, id: 3
 => true
[5] pry(main)> a.can? :update, User, id: 2
 => true

我做错了什么?

谢谢!

1 个答案:

答案 0 :(得分:1)

#app/models/ability.rb
class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new # guest user (not logged in)
    if user.has_role? :user
      can :update, User, id: user.id
    else
      can :read, :all
    end
  end
end

#app/controllers/users_controller.rb
class UsersController < ApplicationController
   def update
      @user = User.find params[:id]
      authorize! :update, @user
      ...
   end
end

来自docs

  

CanCanCan期望控制器中存在current_user方法。

您无需明确调用Ability,而是通过authorize!can?

完成