2010-12-19 6 views
2

私はモデルがあります(例えばCar)メソッドは、ユーザーがメソッドが実行することを許可されているかどうかを判断するために、current_userにアクセスする必要があります。current_userを知る必要があるビジネスロジックを置く場所はどこですか? (レール)

例えば、方法はこれらの事をしたいかもしれませんが:

  1. チェックCURRENT_USERは、このオブジェクトを所有していることを
  2. チェック
  3. オブジェクトのステータス== 1(アクティブ)ことを確認してください関連オブジェクトこと存在し、それがXフィールドだと、私はありません詐欺にモデルにあるように、このビジネス・ロジックを必要とする

NULLではありませんローラー1つの場所私のビジネスロジックになります。このメソッドは、コントローラ以外の場所から呼び出されることがあります。

私はcancan、declarative_authorizationなどのような宝石があることを知っていますが、私は何をする必要があるのか​​不足しているようです。また、モデルのcurrent_userにアクセスすることは、「正しい方法」とはみなされません。

次に、モデルをチェックしても、どうやって「クリーン」な感じがするのですか?

答えて

1

「current_user」がモデルに緊密に接続されている必要がありますが、コントローラですべて処理したところ、かなりうまく機能しています。ここにいくつかの例があります:

私のモデルは "写真"です。写真はユーザーによって所有されており、写真とのやりとりの仕方は明らかに写真の所有者とは密接に関係しています。人々が写真を作成すると

def show 
    @photo = Photo.find(params[:id]) 
    if user_signed_in?  
    if @rating = current_user.ratings.find_by_photo_id(params[:id]) 
     @rating 
     @current_user_rating = @rating.value 
    else 
     @rating = current_user.ratings.new 
     @current_user_rating = "n/a" 
    end 
    end 
end 

:私は既存のユーザーを評価すると、写真に与えられた(そう、彼らはそれを編集することができます)、またはそれらは新しいものを作成することができたか、ロードする必要がshowアクションで

私はそれらを自動的に現在のユーザーに割り当てるようにします。

def new 
    @photo = Photo.new 
end 

def create 
    @photo = current_user.photos.create(params[:photo]) 
    if @photo.save 
    redirect_to user_path(current_user), :notice => t('photo.notice.created') 
    else 
    render 'new' 
    end 
end 

のみ写真の所有者は、それらを変更することができます。

def edit 
    @photo = Photo.find(params[:id]) 
    if @photo.user == current_user 
    render 'edit' 
    else 
    redirect_to user_path(current_user), :alert => t('application.error.unauthorized') 
    end 
end 

def update 
    @photo = current_user.photos.find_by_id(params[:id]) 
    @photo.update_attributes(params[:photo]) 
    if @photo.save 
    redirect_to user_path(current_user), :notice => t('photo.notice.updated') 
    else 
    render 'edit' 
    end 
end 

このアプローチは、「CURRENT_USER」オブジェクトはコントローラのみが知っているセッションに結び付けられている制約に基づいています。要するに、私はまだ "current_user"をモデルに統合する良い方法を見つける必要はありませんが、モデルとコントローラを結びつけるきれいな方法を見つけることができました。コントローラによって。

コントローラが乱雑になり始めた場合、ロジックのチャンクを取り、モデルのメソッドとして定義することができますが、引数は1つ=ユーザーオブジェクトが必要です。次に、コントローラからそのメソッドに「current_user」を送り、モデルが残りの部分を処理します。

幸運を祈る!また、他の誰かがこれについてのより良いアイデアを持っているなら、私はそれらを聞いてみたい!

+0

あなたの答えをありがとう、ありがとう。あなたのコードはうまくいくでしょうが、それをコントローラーに入れるのは間違いです(私の意見のみ)。私はすべてのビジネスロジックを単一のモジュール/クラスに入れて、それを必要とするモデルと混在させることを考えています。このように、私はすべてのロジックが1つの場所にあることを知っています(偉大)、私はモデルやコントローラーをあまり混乱させません。これについてあなたの考えは何ですか? – Zabba

+0

すべてのロジックを1つの場所にグループ化する理由はありません。あなたが結果に満足している限り、コードは期待どおりに機能し、「どこのコードが再びどこにあるのか」という疑問を避けることができます。しかし、...(文字制限による次のコメントを参照してください) – Andrew

+0

Railsを使用するほど、WebアプリケーションのMVCパターンに存在する「フロー」の種類が増えています。私にとっては、ほとんどのロジックはデータベース内のデータに関連すると考えられ、モデルに属しています。モデルからデータを取り出すためのセッションやHTTP要求を処理するロジックは、コントローラーで正しく認識され、少しのプレゼンテーションロジックが意味を成しています。トリックは、これらのエッジの場合、「current_user」のようなものはデータのように見えますが、実際にはそうではありません.HTTPリクエストに完全に関連しています。 (次のコメント) – Andrew

0

コントローラでのハンドルの認証。

例:認証ロジックを親ApplicationControllerに配置します。

class ApplicationController < ActionController::Base 
protect_from_forgery 

    protected 
    # Returns the currently logged in user or nil if there isn't one 
    def current_user 
     return unless session[:user_id] 
     @current_user ||= User.find_by_id(session[:user_id]) 
    end 

    # Make current_user available in templates as a helper 
    helper_method :current_user 

    # Filter method to enforce a login requirement 
    # Apply as a before_filter on any controller you want to protect 
    def authenticate 
     logged_in? ? true : access_denied 
    end 

    # Predicate method to test for a logged in user  
    def logged_in? 
     current_user.is_a? User 
    end 

    # Make logged_in? available in templates as a helper 
    helper_method :logged_in? 

    def access_denied 
     redirect_to login_path, :notice => "Please log in to continue" and return false 
    end 
end 

今でCURRENT_USERは、ログインしているユーザーとあなたが任意のコントローラにアクセスすることができますが、モデルで何かをする前に、あなたは適切なコントローラであなたの承認ロジックを行うことができますへのアクセサです。

あなたの権利。モデルは認可や誰にアクセスしているかは気にしません。

+0

これは私が必要とするものではありません。私のモデルのビジネスロジックはモデル内にある必要があり、ビジネスロジックのためにはcurrent_userにアクセスする必要があります。 – Zabba

+0

あなたのモデルであなたがしようとしていることの例を教えてください。一般に、この作業はコントローラ内で行われるため、モデルは現在の要求を知るべきではありません。しかし時々あなたは本当にそれを助けることができません。 – danneu

+0

あなたの時間をありがとう..私は何をする必要があるビジネスロジックの種類の質問を更新しました。 – Zabba

関連する問題