2013-07-11 201 views
9

例:チェックCURRENT_USERは、リソースの所有者であると許可した場合に編集/削除アクション

ユーザー写真リソース

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

を作成しました
(10 = ID)ユーザーの場合 B(id = 20)このURLに移動: /photos/1/editユーザーの写真を編集できます A !!!

Rails + Deviseにはデフォルトで何かが用意されていますか?レール4を、工夫

私はすべてのユーザーが編集することができます/ ONLYそれは使用して(ここで、CURRENT_USER == resource.user)

を作成したリソースを削除することを許可する必要があり

非常に一般的な問題だと思われます

更新:

私はカンカンが、それはあまりにも高度なものだと思います。私は役割が必要かapplication_controllerに

+0

CanCan https://github.com/ryanb/cancanを見てください – tight

+3

cancanはもうよく管理されていません。最後のコミットは2か月前です。 189未解決の問題。これはまた、簡単な認可のための非常に肥大したツールです。個人的には、私はhttps://github.com/elabs/punditを好む – deefour

+0

これを指摘するための@Deefour thx、専門家は偉大に見える – tight

答えて

29

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 
+0

ここではActiveRecord :: RecordNotFound例外を処理する必要があります。 –

+0

@ NiravGandhi AFAIKでは、ActiveRecordメソッドの '!'バージョンだけがその例外をスローします。そうでなければ、結果は単に 'nil'になります。もちろん、これも処理する必要があります。 –

+0

@ChrisCirefice Rails '4.2.8'とActiveRecord' 2.5.1'には 'find! 'はありません。' find'自体は 'ActiveRecord :: RecordNotFound'例外を投げます。 – taylorthurlow

0

書き込みに特定のユーザーに別の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? 

をそして、あなたは、ユーザーが追従できないリンクを示すために、ビューでそれを使用することはできません。

これはもちろん、あなたのニーズに合わせて変更する必要があります。これはrailscasts

+0

これは悪い考えです。許可を処理するには、テスト済みで、より柔軟で、読みやすく、よく書かれた宝石があります。このような壊れやすいもので車輪を再発明する必要はありません。 – deefour

+0

@Deefour、これは単なる例です。いくつかの理由から、あなたがそれを避けることができる場所では宝石を使用しないことに意味があります。最善のアプローチは、DBテーブルのないモデルですが、問題チュートリアル全体では、回答よりも記事の方が適しています。 –

+0

この考えは興味深いようです。@Deefourこれは何かのための宝石ですか? (CanCanはこの問題に対してはあまりにも進んでいます) – sparkle

2

チェック、あなたがに実行されます

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

合併症、

  1. あなたが宝石を考案ユーザーモデルのカンカン認証は、認証

  2. のために使用されたいですロールをデータベースに保存する場合

  3. あなたはWebUIの

  4. と詳細..から管理者としての役割へのアクセス権を割り当てる

あなたはそれらの機能のいずれかをしたい場合、私は幸せになります、コメントしてください助けてください。私は最近、他人からの大きな助けを借りて彼らをしてくれました。

次のように自分のリソースのためのサンプル能力は次のようにすることができ、あなたをPhotosControllerで

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 
+0

1)ユーザーモデルが私のDeviseに使用されています。ちょうどこれ – sparkle

+0

あなたはそれを行う方法を知りたいですか? – beck03076

+0

私はもっと簡単なものが必要だと思っていました。私は、作成したリソース(current_user == resource.user)のみを編集/削除できるようにする必要があります。 Cancanはより高度なものです – sparkle

0

カンカンがあまりにも進んでいる場合は、アクセサのIDを確認するにルーン必要がありますコントローラに...

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

...またはそのような何かを使用して

11

あなたはRailsの団体を利用し、このようにそれを書き込むことができます。付属のIDと一緒に写真が現在のユーザーに属している場合にのみレコードを検索します

def edit 
    @photo = current_user.photos.find(params[:id]) 

    # ... do everything else 
end 

。そうでない場合、RailsはActiveRecord::RecordNotFound例外を発生させます。

もちろん、私はcurrent_userメソッドが利用可能で、Userモデルに文has_many :photosが含まれていると仮定しています。

+1

これは、この単純な問題の最も洗練されたソリューションです。 +1 –

1

したがって、gem deviseを使用しています。

この宝石は、現在ログインしているユーザーのために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つのオブジェクトが既に存在するため、安価です。

1

最も簡単なのはroutes.rbを変更することです。

current_userパスに保存する写真を割り当てます。例えば

devise_for :users 

resources 'users' do 
    resources 'photos' 
end 
1

私はbefore_filterアクション内から例外を捕獲:

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を使っています。

関連する問題