Ruby on rails 带参数的前_滤波器

Ruby on rails 带参数的前_滤波器,ruby-on-rails,ruby,ruby-on-rails-3,before-filter,Ruby On Rails,Ruby,Ruby On Rails 3,Before Filter,我有一个方法,它可以做这样的事情: before_filter :authenticate_rights, :only => [:show] def authenticate_rights project = Project.find(params[:id]) redirect_to signin_path unless project.hidden end before_filter { |c| c.authenticate_rights correct_id_here }

我有一个方法,它可以做这样的事情:

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

def authenticate_rights
  project = Project.find(params[:id])
  redirect_to signin_path unless project.hidden
end
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
我还想在其他一些控制器中使用此方法,因此我将此方法复制到应用程序控制器中包含的帮助器中

问题是,在某些控制器中,项目的id不是
:id
符号,而是f.e.
:project\u id
(并且存在
:id
(对于另一个型号)

您将如何解决此问题?是否有向before_filter操作添加参数的选项(以传递正确的参数)?

这应该可以:

project = Project.find(params[:project_id] || params[:id])
如果参数散列中存在,则返回
params[:project\u id]
,如果不存在,则返回
params[:id]

我会这样做:

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

def authenticate_rights
  project = Project.find(params[:id])
  redirect_to signin_path unless project.hidden
end
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\u id\u here
是访问
项目
以继续@alex'回答的相关id,如果您想
:除了
:仅
某些方法,以下是语法:

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

找到。

带有一些语法糖:

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|
由于Rails 4在_action之前引入了_filter之前的同义词,因此它可以写成:

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

->
代表
lambda
,称为lambda literal,在Ruby 1.9中引入


%i
将创建一个符号数组

我发现使用大括号而不是
do…end
的块方法是最清晰的选项

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

before\u action
只是
before\u filter

较新的首选语法问题是,有时两者都存在(嵌套)它会发现一个项目不是正确的。@choise:这不应该发生:如果存在
project\u id
,则
子句将确保使用该项目-只有在未提供
project\u id
的情况下,才会选择
id
参数。换句话说,当提供了这两个参数时,
子句将被删除URE使用正确的值,因为它总是喜欢
project\u id
。当然,当两者都不存在时,或者当没有
project\u id
但有一个
id
不引用项目时,您不希望调用此方法。是否有方法添加
,:only=>[:show]
symbol?我在尝试
before\u filter{c | c.authenticate\u rights correct\u id\u here},:only=>[:show]
尝试另一种方法:
before\u filter(:only=>[:show]){
这里有更多示例:如果您通过将
before\u filter
作为私有方法来确保这一点,那么可能需要重新考虑(例如,将其移动到父控制器、应用程序控制器等),您需要使用
c.send(:filter\u name,…)
,因为过滤器不会在控制器上下文中运行。这样做会使before\u过滤器无法因缺少名称而被覆盖/跳过(proc)。我要传递的值是类级别的。这可能吗?@oreoshake:我也有同样的问题。你找到解决方案了吗?这个答案更优雅,因为lambda默认为类的执行上下文,因此可以调用私有方法,而无需使用“.send”@Vadym Tyemirov Is
find\u campaign
私有方法名称?在
param=params[:id]
中,
param
是将作为参数传递给
find_活动
的新局部变量的名称吗?这意味着在
find_活动
私有方法本身中,我们使用
param
而不是
params{:id]
find_-campaign
也可以,但我会将它设置为私有,以确保我们不会公开未使用的内容。
params
是我们的方法可用的散列变量,
param
是查找_-campaign方法需要传递的任何变量,例如在_-action之前->(campaign_-id=params[:id{])find_-campaign(活动id)},仅:%i |显示编辑更新销毁|