带参数的 before_filter

我有一个方法可以这样做:

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


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

我还想在其他一些控制器中使用这个方法,所以我将该方法复制到 application _ controller 中包含的一个 helper 中。

问题是,在某些控制器中,项目的 id 不是 :id符号,而是 f.e. :project_id(另外还有一个 :id(对于另一个模型))

你将如何解决这个问题?是否有一个选项可以向 before _ filter 操作添加一个参数(以传递正确的参数) ?

44597 次浏览

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.

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.

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.

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

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