检查current_user是否是资源的所有者并允许编辑/删除操作

例:

用户A (id = 10)已创建照片资源

photo: (id: 1 user_id = 10, url: "http://...") 

现在,如果用户B (id = 20)转到此url: /photos/1/edit它可以编辑用户A的照片!!!

Rails + Devise默认为此提供了一些东西? 这似乎是一个非常普遍的问题

我只需要允许任何用户只能编辑/删除它创建的资源(其中current_user == resource.user)

使用: Rails 4,设计

更新:

我想CanCan它太先进了。 我不需要角色或限制某些用户的某些操作

在你的PhotosController中:

 before_filter :require_permission, only: :edit def require_permission if current_user != Photo.find(params[:id]).user redirect_to root_path #Or do something else here end end 

您可以使用Rails的关联并将其写为:

 def edit @photo = current_user.photos.find(params[:id]) # ... do everything else end 

这只会在具有提供的ID的照片属于当前用户时找到记录。 如果没有,Rails将引发ActiveRecord::RecordNotFoundexception。

当然,我假设current_user方法可用,而您的User模型包含语句has_many :photos

检查这个railscast,

http://railscasts.com/episodes/192-authorization-with-cancan

你会遇到的并发症,

  1. 如果您想在Devise gem用于身份validation的用户模型上进行cancan授权

  2. 当您想要将角色存储在数据库中时

  3. 如果要从WebUI将权限分配给角色作为管理员

  4. 和更多 ..

如果您想要任何这些function,请评论,我将很乐意提供帮助,因为我最近在其他人的帮助下做了这些,并且总是让人难以理解。

您的资源的示例能力可以如下所示,

 class Ability include CanCan::Ability def initialize(user) user ||= User.new # guest users send(user.role.name) if user.role.blank? can :read, User #for guest without roles end end def man can :manage, Photo end def boy can :read, Photo end def kid can :read, Article end end 

我从before_filter操作中捕获了exception:

 before_action :set_photo, only: [:edit, :update, :destroy] def set_photo @photo = current_user.photos.find(params[:id]) rescue ActiveRecord::RecordNotFound redirect_to(root_url, :notice => 'Record not found') end 

希望这有助于某人。 我正在使用Rails 4和Ruby 2。

所以你正在使用gem devise

此gem为当前登录的用户提供current_user

在你的PhotosController#edit方法中。 我会做类似下面的事情。

 def edit @photo = Photo.find(params[:id]) redirect_to root_path, notice: 'Thou Shalt Nought duuu dat :(' unless current_user.id == @photo.user_id ... end 

此方法更便宜,因为您已经有2个对象要比较,而不是在比较中运行查询。

最简单的方法是修改routes.rb。

将照片分配到current_user路径中。

例如,

 devise_for :users resources 'users' do resources 'photos' end 

如果CanCan过于先进,你应该使用…来检查控制器中存取器的id。

 if @user.id == @photo.user_id # edit photo details else redirect_to root_path, notice: "You! Shall! Not! Edit!" 

…或类似的东西

在application_controller中写另一个before_filter:

 before_filter :has_permission? has_permission? controllers=["articles", "photos", "..."] actions=["edit", "destroy", "..."] id = params[:id] if (controllers.include?(params[:controller] && actions.include?(params[:action]) end if id && (current_user.id==(params[:controller][0...1].capitalize!+params[:controller].singularize[1...-1] + ".find(#{id}).user_id").send) return true else redirect_to root_url, :notice=>"no permission for this action" end helper_method :has_permission? 

您可以在视图中使用它,而不是向用户显示他们无法关注的链接。

某种,当然你需要修改它以满足你的需要。