before_filter with parameters

Ruby on-RailsRubyRuby on-Rails-3Before Filter

Ruby on-Rails Problem Overview


I have a method that does something like this:

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

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

I also want to use this method in some other Controllers, so i copied the method to a helper that is included in the application_controller.

the problem is, that in some controllers, the id for the project isn't the :id symbol but f.e. :project_id (and also a :id is present (for another model)

How would you solve this problem? is there an option to add a parameter to the before_filter action (to pass the right param)?

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

I'd do it like this:

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

Where correct_id_here is the relevant id to access a Project.

Solution 2 - Ruby on-Rails

With some syntactic sugar:

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

Or if you decide to get even more fancy:

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

And since Rails 4 before_action, a synonym to before_filter, was introduced, so it can be written as:

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

NB

-> stands for lambda, called lambda literal, introduce in Ruby 1.9

%i will create an array of symbols

Solution 3 - Ruby on-Rails

To continue @alex' answer, if you want to :except or :only some methods, here is the syntax:

before_filter :only => [:edit, :update, :destroy] do |c| c.authenticate_rights params[:id] end 

Found here.

Solution 4 - Ruby on-Rails

I find the block method using curly braces instead of do...end to be the clearest option

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

before_action is just the newer preferred syntax for before_filter

Solution 5 - Ruby on-Rails

This should work:

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

This should return params[:project_id] if it is present in the params hash, or return params[:id] if it isn't.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionchoiseView Question on Stackoverflow
Solution 1 - Ruby on-RailsAlexView Answer on Stackoverflow
Solution 2 - Ruby on-RailsVadym TyemirovView Answer on Stackoverflow
Solution 3 - Ruby on-RailsAugustin RiedingerView Answer on Stackoverflow
Solution 4 - Ruby on-RailsSubtletreeView Answer on Stackoverflow
Solution 5 - Ruby on-RailsMatheus MoreiraView Answer on Stackoverflow