パラメータ付きのbefore_filter


84

私はこのようなことをするメソッドを持っています:

before_filter :authenticate_rights, :only => [:show]

def authenticate_rights
  project = Project.find(params[:id])
  redirect_to signin_path unless project.hidden
end

他のいくつかのコントローラーでもこのメソッドを使用したいので、application_controllerに含まれているヘルパーにメソッドをコピーしました。

問題は、一部のコントローラーでは、プロジェクトのIDが:idシンボルではなく、feである:project_id(および:id(別のモデルの場合)aも存在する)ことです。

この問題をどのように解決しますか?before_filterアクションにパラメーターを追加する(正しいパラメーターを渡すための)オプションはありますか?

回答:


86

私はこのようにします:

before_filter { |c| c.authenticate_rights correct_id_here }

def authenticate_rights(project_id)
  project = Project.find(project_id)
  redirect_to signin_path unless project.hidden
end

correct_id_hereアクセスに関連するIDはどこにありますかProject


2
,:only => [:show]シンボルを追加する方法はありますか?試行中にエラーが発生しましたbefore_filter { |c| c.authenticate_rights correct_id_here }, :only => [:show]
2011

27
逆を試してください:before_filter(:only => [:show]) { <block_code_here> }。その他の例:apidock.com/rails/ActionController/Filters/ClassMethods/…– fguillen 2012
1

1
before_filterプライベートメソッドを作成してこれを保護し、おそらくリファクタリング(たとえば、親コントローラー、ApplicationControllerなどに移動)する場合c.send(:filter_name, ...)は、フィルターがコントローラーコンテキストで実行されないため、使用する必要があります。 guides.rubyonrails.org/…–
リチャードマイケル

2
これを行うと、名前(proc)がないためにbefore_filterをオーバーライド/スキップできないようになります。渡したい値はクラスレベルです。それは可能ですか?
oreoshake 2013

1
@ore​​oshake:同じ問題があります。解決策を見つけましたか?
marcus3006 2013

67

いくつかのシンタックスシュガー付き:

before_filter -> { find_campaign params[:id] }, only: [:show, :edit, :update, :destroy]

または、さらに凝ったものにすることにした場合:

before_filter ->(param=params[:id]) { find_campaign param }, only: %i|show edit update destroy|

またbefore_action、の同義語であるRails 4before_filterが導入されたため、次のように記述できます。

before_action ->(param=params[:id]) { find_campaign param }, only: %i|show edit update destroy|

NB

->の略でlambdaラムダリテラルと呼ばれ、Ruby1.9で導入されました

%i シンボルの配列を作成します


5
ラムダはデフォルトでクラスの実行コンテキストに設定されるため、この回答はよりエレガントです。したがって、「。send」を使用せずにプライベートメソッドを呼び出すことができます
David Pelaez 2014年

@Vadym Tyemirov Is find_campaignプライベートメソッド名ですか?でparam=params[:id]、あるparamに引数として渡される新しいローカル変数の名前はfind_campaign?つまり、find_campaignプライベートメソッド自体の中で、使用しparamないということparams{:id]ですか?
ahnbizcad 2014

1
find_campaignどちらでもかまいませんが、消費されていないものを公開しないように非公開にします。paramsはメソッドで使用できるハッシュ変数であり、paramfind_campaignメソッドに渡す必要のある変数です。例before_action ->(campaign_id=params[:id]) { find_campaign(campaign_id) }, only: %i| show edit update destroy |
Vadym Tyemirov 2014


5

do...end最も明確なオプションではなく、中括弧を使用したブロック方法を見つけました

before_action(only: [:show]) { authenticate_rights(id) }

before_action の新しい推奨構文です before_filter


-1

これは機能するはずです:

project = Project.find(params[:project_id] || params[:id])

これはparams[:project_id]、paramsハッシュに存在する場合は返され、存在しparams[:id]ない場合は返されます。


問題は、両方が存在する(ネストされている)場合があり、適切なプロジェクトではないプロジェクトが見つかることです。
2011年

@choise:それは起こらないはずです:project_id存在する場合、or句はこれが使用されることを保証します-project_idが指定されていない場合にのみ、idパラメータが選択されます。言い換えると、両方のパラメーターが指定されている場合、or句は常に優先されるため、正しい値が使用されることを保証しますproject_id。当然、どちらも存在しない場合、または存在しないproject_ididプロジェクトを参照しないメソッドがある場合は、このメソッドを呼び出したくないでしょう。
Ola Tuvesson 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.