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 

虽然内部配置文件控制 也许是一个错误