Devise + CanCan只是阻止其他用户编辑对象
你如何阻止其他用户编辑一个对象,比如一个不属于他们自己的个人资料对象呢?
大多数在线示例都是具有多个用户角色的复合体,我无法使其工作,但必须简单:
def initialize(user) can :update, Profile do |profile| profile.try(:user) == current_user end end
在我的ProfilesController#edit中
authorize! :update, @profile
第一个问题是,您是否为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
这就是你如何让用户只编辑他们自己的个人资料和没人。
其他一些方便的注意事项:确保在Profile
表中有一个user_id
列。 此外,如果您可能需要让猜测用户看到这样的配置文件:
class ProfileController < ApplicationController before_filter :authenticate_user!, :except => :show load_and_authorize_resource end
他们将无法使用任何其他操作,CanCan仍会检查除show
之外的所有其他操作的身份validation。
祝好运!
更新: 制作:用户的角色属性
我所做的是运行一个迁移,将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,请不要让 role
attr_accessible
或每个人都可以编辑他们的角色! Rails 4默认使用强参数 ,不受此问题的影响,因为您可以选择允许的参数。
尝试这样的东西….
can :update, Profile, :user_id => user.id
UPDATE
似乎上面的代码示例正确。 在阅读了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
虽然内部配置文件控制 也许是一个错误