2017-04-19 2 views
1

私のRubyのWebアプリケーションの1ページをSTIモデルタイプの1つにアクセスできないようにしたい。私は、Userから継承するtypeAとtypeBという2つのモデルを持っています。私はSTIを実装するためにUserテーブルのカラムタイプを使用しました。私はUserセッションにDevise gemを使用しています。私は1つのウェブページ 'http://localhost:3000/rate'を自分のtypeA Userにアクセスできないようにします。ユーザーが 'typeA'タイプのユーザーでログインすると、リンクに 'Rate'のオプションが表示されません。しかし、私は彼がリンク 'http://localhost:3000/rate'によってそのページにアクセスできるようにしたくありません。彼がそのリンクを介してアクセスしようとすると、私は彼にサインして再びログインさせたいと思う。 私はこれを、私のコントローラーのコードに「rate」という特定の方法を使って管理しました。Ruby on Railsアプリケーションの特定のページを、STIベースのDevise Userモデルタイプにアクセスできないようにするにはどうすればよいですか?

def rate 
    if current_user.type == "typeA" 
    sign_out(current_user) 
    redirect_to new_user_session_path 
    else 
    #Code for User of typeB 
    end 
end 

これが働いているが、私は、これはbefore_filter使用してより良い方法で行うことができるかどうかを知りたいと思った:authenticate_userを!または何か他の は、今のところ私のbefore_filterの部分は、私はその機能を実現するために、上のコードに変更を加えることができますどのような方法があります。この

before_filter :authenticate_user!, except: [:index, :show] 

のように見えます。
P.S:私がCanCan/Punditのような役割や他の宝石を使っていたら、これはもっとうまくいくかもしれませんが、プロジェクトを提出するまでに時間がかかりません。私はbefore_action(before_filterの新名称)はレンダリングまたはリダイレクトする場合は、アクションが処理されることはありません信じて

class SomeController < ApplicationController 

    before_action :authorize_user!, except: [:index, :show] 

    def top_secret 
     ... 
    end 

end 

:あなたのコントローラと

class ApplicationController 

    before_action :authenticate_user! 

    def authorize_user! 
    if current_user.type == "typeA" 
     sign_out(current_user) 
     redirect_to new_user_session_path 
    end 
    end 

end 

答えて

1

コントローラに別のbefore_filterを追加して、デバイスのauthenticate_user!フィルタをオーバーライドせずにSTIユーザタイプを確認するだけでアクセスを制限することができます。

application_controller.rb

class ApplicationController < ActionController::Base 

    def confirm_user_type(user_type) 
    redirect_to new_user_session_path unless current_user.is_a?(user_type) 
    end 

end 

pages_controller.rb

class PagesController < ApplicationController 
    # must be authenticated to access 
    before_filter :authenticate_user! 
    # must be user of TypeA to access 
    before_filter { |c| c.confirm_user_type(TypeA) } 

    def rate 
    ... 
    end 
end 

その後、あなたはこれが動作しないSTIユーザーtype: 'TypeB'

+0

私は、コントローラ全体がタイプAにアクセスできないようにしたくありません。私は彼に「レート」ページだけにアクセスできないようにしたい。索引、作成、ショーなどの他の方法がありますが、まだ彼にアクセス可能でなければなりません。それを私のコードにどのように入れますか? –

+0

あなたは 'only:'オプションを使って 'before_filter {| c | c.confirm_user_type(タイプA)}、:のみ=> [:率] ' – sa77

+0

が、私は今、取得エラーページが/Users/Suvajit/Documents/Code/Rails/Mckenzie/app/controllers/dishes_controller.rb:4です:構文エラー、予期しない ':'、keyword_end .confirm_user_type(タイプA)を期待}のみ=>:| | C [レート]^ 私が使用しているコードは 'before_filter {ありますc:=> [:rate] ' –

0

はこれを試してみてください。

+0

のために同じフィルタbefore_filter { |c| c.confirm_user_type(TypeB) }を使用することができます。今は、typeAにアクセスが許可されているページにアクセスしようとしているときに、彼は彼に署名しています。また、ログアウトして 'http:// localhost:3000/rate'にアクセスしようとすると、未知の変数 'c​​urrent_user.type'を示すRailsエラーページが表示されます。以前に行ったコードでは、ログアウトして「http:// localhost:3000/rate」にアクセスしようとすると、Deviseのフラッシュメッセージで「サインインする必要があります。続行する前にサインアップしてください。とにかくあなたの答えに感謝します。 –

+0

ああ、authenticate_userを実現しませんでした!標準のDeviseだったので、それを上書きしてはいけません。ここのコードはうまくいくはずだと思います。まず、current_userを設定して認証し、認証します。 – mahemoff

関連する問題