你如何阻止其他用户编辑一个对象,比如说一个不属于自己的个人资料对象?
大多数在线示例都是具有多个用户角色的复合体,我无法使其正常工作,但必须简单:
def initialize(user)
can :update, Profile do |profile|
profile.try(:user) == current_user
end
end
在我的ProfilesController#edit
中authorize! :update, @profile
答案 0 :(得分:12)
第一个问题是,您是否为User
?
应用程序/模型/ user.rb
class User < ActiveRecord::Base
attr_accessible :email, :password, :remember_me
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, # regular devise stuff
before_create :setup_default_role_for_new_users
ROLES = %w[admin default banned]
private
def setup_default_role_for_new_users
if self.role.blank?
self.role = "default"
end
end
end
正如您所看到的,我在这里有3个不同的角色,当创建新用户时,他们始终是default
个用户。现在设置了CanCan,假设您希望admin
能够执行所有操作,default
用户可以使用自己的配置文件执行所有操作,banned
用户无法执行任何操作和访客用户可以看到个人资料:
class Ability
include CanCan::Ability
# Remember that CanCan is for a resource, meaning it must have a class(model).
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.role == "admin"
can :manage, :all
elsif user.role == "default"
can :manage, Profile, :user_id => user.id
elsif user.role == "banned"
cannot :manage, :all
else
can :read, Profile # guest user
end
end
end
这样你就可以让用户只编辑他们自己的个人资料和无人资格了。
其他一些便利说明:确保user_id
表中有Profile
列。此外,如果您可能需要让猜测用户看到如下配置文件:
class ProfileController < ApplicationController
before_filter :authenticate_user!, :except => :show
load_and_authorize_resource
end
他们无法使用任何其他操作,CanCan仍会检查除show
以外的所有其他操作的身份验证。
更新:制作:用户的角色属性
我所做的是运行迁移,将role
列添加到Devise users
表中:
rails generate migration add_role_to_users role:string
然后rake db:migrate
。新的迁移文件应如下所示,并检查 db / schema.rb 文件,以确保正确区分其用户表。如果它不是rake db:drop
,那么rake db:create
然后再次rake db:migrate
。
class AddRoleToUsers < ActiveRecord::Migration
def self.up
add_column :users, :role, :string
end
def self.down
remove_column :users, :role
end
end
这是您成功完成user.role
工作的方式。
注意:请务必保留以下行:can :manage, Profile, :user_id => user.id
,不做任何更改。将role
列添加到user
后,它应该可以正常工作。
重要!如果您使用Rails 3,请不 MAKE role
attr_accessible
或者每个人都可以编辑他们的角色! Rails 4默认使用Strong Parameters,不受此问题的影响,因为您可以选择允许的参数。
答案 1 :(得分:4)
尝试这样的事情......
can :update, Profile, :user_id => user.id
答案 2 :(得分:0)
<强>更新强>
似乎上面的代码示例正确。在阅读了cancan rtfm的所有文档后,我发现了你需要添加的角色列。
由于我的个人资料更新操作的组织方式,似乎CanCan无效!我解决了如下:
def edit
@profile = Profile.find params[:id]
what = params[:what]
if can? :update, @profile
if ["basics", "location", "details", "photos", "interests"].member?(what)
render :action => "edit_#{what}"
else
render :action => "edit_basics"
end
else
raise CanCan::AccessDenied.new("Not authorized!", :update, Profile)
end
end
也许不是最干净的方式,而是让它发挥作用的唯一方法。欢迎任何有关改进的建议,我确实有
load_and_authorize_resource
内部配置文件控制器虽然!也许是一个错误