重构方法不接受属性

Refactored method not accepting attribute

A 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: undefined local variable or method `article' for

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

NoMethodError: undefined method `:article'

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

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

如果你去掉 send() 并使用类似

的东西
ctrl = params["#{attribute}"]
#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。如果不行,我们可以看看重构