重构方法不接受属性

时间:2016-01-20 09:36:23

标签: ruby-on-rails ruby ruby-on-rails-4 refactoring

一个before_action曾经工作但在几个控制器中重复。例如,在我的文章控制器中,我有:

before_action :find_author

# Show, edit, etc. methods

def find_author
  @author = Author.find(params[:article][:author_id]) unless (params[:article] == nil || params[:article][:author_id] == nil)
  if @author == nil
    redirect_to root_url
  end
end

因为多个控制器使用了这个before_action,所以我将它放在应用程序控制器中并重构为:

def find_author(attribute)
  controller = send(":#{attribute}")
  @author = Author.find(params[controller][:author_id]) unless (params[controller] == nil || params[controller][:author_id] == nil)
  if @author == nil
    redirect_to root_url
  end
end

在我的文章控制器中,我使用参数添加了before_action:

before_action do
  find_author(article)
end

重构测试失败后出现以下错误(参考文章控制器中的行)。我做错了什么?

  

NameError:未定义的局部变量或

的方法`article'

更新:我将find_author(article)替换为find_author("article")。现在我收到一条新的错误消息,指的是应用程序控制器中的@author行:

  

NoMethodError:未定义的方法`:article'

2 个答案:

答案 0 :(得分:2)

您应该删除send()并尝试干掉您的代码。一种可能的解决方案可能是:

@author = Author.find(ctrl[:author_id]) unless 
    (ctrl == nil || ctrl[:author_id] == nil)

如果你摆脱send()并使用类似

的东西
ctrl = params["#{attribute}"]

答案 1 :(得分:1)

#app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
   before_action :find_author, only: Proc.new {|c| %i(article posts).include? c.controller_name }

   protected

   def find_author
       author  = params[controller_name][:author_id]
       @author = Author.find author if author
       redirect_to root_url if @author.nil?
   end
end

我在这里看到的唯一问题是调用controller_name 可能只加载application。如果它不起作用,我们可以看到重构。