带参数的before_filter

cho*_*ise 80 ruby ruby-on-rails before-filter ruby-on-rails-3

我有一个类似这样的方法:

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

def authenticate_rights
  project = Project.find(params[:id])
  redirect_to signin_path unless project.hidden
end
Run Code Online (Sandbox Code Playgroud)

我还想在其他一些控制器中使用此方法,因此我将该方法复制到application_controller中包含的帮助器中.

问题是,在某些控制器中,项目的id不是:id符号,而是fe :project_id(也:id存在a(对于另一个模型)

你会如何解决这个问题?是否可以选择向before_filter操作添加参数(传递右侧参数)?

Ale*_*lex 81

我这样做:

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
Run Code Online (Sandbox Code Playgroud)

correct_id_here访问a的相关ID 在哪里Project.

  • 尝试相反的方法:`before_filter(:only => [:show]){<block_code_here>}`.更多示例:http://apidock.com/rails/ActionController/Filters/ClassMethods/before_filter (26认同)
  • 有没有办法添加`,:only => [:show]`符号?我在尝试`before_filter {| c |时遇到错误 c.authenticate_rights correct_id_here},:only => [:show]` (2认同)
  • 这样做会使得before_filter因为缺少名称(proc)而无法被覆盖/跳过.我想传入的值是类级别.那可能吗? (2认同)

Vad*_*rov 64

用一些语法糖:

before_filter -> { find_campaign params[:id] }, only: [:show, :edit, :update, :destroy]
Run Code Online (Sandbox Code Playgroud)

或者如果你决定变得更加花哨:

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

由于Rails 4 before_action是一个同义词before_filter,所以它可以写成:

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

NB

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

%i 将创建一个符号数组

  • 这个答案更优雅,因为lambda默认为类的执行上下文,因此可以在不使用'.send'的情况下调用私有方法 (4认同)

Aug*_*ger 14

要继续@alex的回答,如果你想要:except:only某些方法,这里是语法:

before_filter :only => [:edit, :update, :destroy] do |c| c.authenticate_rights params[:id] end 
Run Code Online (Sandbox Code Playgroud)

这里找到.


Sub*_*ree 5

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

before_action(only: [:show]) { authenticate_rights(id) }
Run Code Online (Sandbox Code Playgroud)

before_action 只是更新的首选语法 before_filter