从 Rails 中的控制器调用辅助方法时出现“未定义的方法”

Posted

技术标签:

【中文标题】从 Rails 中的控制器调用辅助方法时出现“未定义的方法”【英文标题】:"undefined method" when calling helper method from controller in Rails 【发布时间】:2011-01-24 05:46:01 【问题描述】:

有人知道我为什么会得到

undefined method `my_method' for #<MyController:0x1043a7410>

当我从我的 ApplicationController 子类中调用 my_method("string") 时?我的控制器看起来像

class MyController < ApplicationController
  def show
    @value = my_method(params[:string])
  end
end

还有我的助手

module ApplicationHelper
  def my_method(string)
    return string
  end
end

最后是应用控制器

class ApplicationController < ActionController::Base
  after_filter :set_content_type
  helper :all
  helper_method :current_user_session, :current_user
  filter_parameter_logging :password
  protect_from_forgery # See ActionController::RequestForgeryProtection for details

【问题讨论】:

NoMethodError when trying to invoke helper method from Rails controller的可能重复 【参考方案1】:

你不能从控制器调用助手。如果需要在多个控制器中使用,最好的办法是在 ApplicationController 中创建方法。

编辑:明确地说,我认为很多混乱(如果我错了,请纠正我)源于helper :all 电话。 helper :all 真的只是包含了所有你在视图端的任何控制器下使用的助手。在更早的 Rails 版本中,助手的命名空间决定了哪些控制器的视图可以使用助手。

我希望这会有所帮助。

【讨论】:

很好的信息。实际上,我已经为我的方法创建了一个模块,正如以下线程中所宣传的那样,因为该方法非常通用(它将字符串转换为 url 安全)并且不应该特定于控制器:***.com/questions/128450/… 这是一个很好的答案,但我会进一步扩展它。当在 Controller 中使用 helper_method 时,会将 在控制器中 中存在的方法添加到相应的帮助器中。即应用程序控制器中的方法被添加到 ApplicationHelper。反之则不行。【参考方案2】:

view_context 是你的朋友,http://apidock.com/rails/AbstractController/Rendering/view_context

如果您想在控制器和视图之间共享方法,您还有更多选择:

使用 view_context 在控制器中定义它并通过helper_method类方法http://apidock.com/rails/ActionController/Helpers/ClassMethods/helper_method在视图中可用 在共享模块中定义它并包含/扩展

【讨论】:

太棒了!不知道那件事。我认为这是正确的答案。 在共享模块中定义方法是一个不错的方法...因为帮助程序自动包含在 Rails 视图中。 它应该被标记为有正确答案,因为这会带来问题的解决方案。但是像@theIV 所做的一点解释也可能有所帮助。 :-)【参考方案3】:

在 application_controller.rb 文件中包含 ApplicationHelper,如下所示:

class ApplicationController < ActionController::Base
  protect_from_forgery       
  include ApplicationHelper  
end

这样,application_helper.rb 文件中定义的所有方法都将在控制器中可用。

您还可以在单​​个控制器中包含单个助手。

【讨论】:

哇,如果有人想在其他控制器中使用 ApplicationHelper 方法或查看只需添加此 include ApplicationHelper ,这是可行的。【参考方案4】:

也许我错了,但助手不只是为了查看吗?通常,如果您需要控制器中的函数,则将其放入 ApplicationController 中,因为每个函数都在其子类中可用。

【讨论】:

嗯,太糟糕了。我希望我可以在控制器和视图中使用方法。哦,好吧。 您可以,有点...您的helper_method 电话使您可以访问视图中的这些方法。 我有一个helper,在用递归树渲染json时必须在视图和控制器中使用,而我不能在控制器中使用它?【参考方案5】:

正如gamecreature 在this post 中所说:

在 Rails 2 中使用 @template 变量。 在 Rails 3 中使用控制器方法view_context

【讨论】:

【参考方案6】:

帮助程序用于视图,但添加一行代码以在 ApplicationController.rb 中包含该帮助程序文件可以解决您的问题。在您的情况下,在 ApplicationController.rb 中插入以下行:

include ApplicationHelper

【讨论】:

【参考方案7】:

据我所知,helper :all 使助手在视图中可用...

【讨论】:

【参考方案8】:

尝试在您的帮助模块中附加module_function(*instance_methods),之后您可以直接在模块本身上调用这些方法。

【讨论】:

【参考方案9】:

虽然在控制器中调用助手不是一个好习惯,因为助手是在视图中使用的 在控制器中使用助手的最好方法是在 application_controller 中创建一个助手方法并将它们调用到控制器, 但即使需要在控制器中调用助手 然后只需将助手包含在控制器中

class ControllerName < ApplicationController
  include HelperName
  ...callback statements..

并直接调用控制器的辅助方法

 module OffersHelper
  def generate_qr_code(text)
    require 'barby'
    require 'barby/barcode'
    require 'barby/barcode/qr_code'
    require 'barby/outputter/png_outputter'
    barcode = Barby::QrCode.new(text, level: :q, size: 5)
    base64_output = Base64.encode64(barcode.to_png( xdim: 5 ))
    "data:image/png;base64,#base64_output"
  end

控制器

class ControllerName < ApplicationController
include OffersHelper

def new
  generate_qr_code('Example Text')
end
end

希望这会有所帮助!

【讨论】:

【参考方案10】:

我遇到了同样的问题...

您可以绕过它,将逻辑放入模型中,或者专门为它创建一个类。与那些讨厌的辅助方法不同,控制器可以访问模型。

这是我的“rag.rb”模型

class Rag < ActiveRecord::Base
  belongs_to :report
  def miaow()
    cat = "catattack"
  end  
end

这是我的“rags_controller.rb”控制器的一部分

def update
  @rag = Rag.find(params[:id])
  puts @rag.miaow()
  ...

在我单击“更新”后,这在终端上造成了攻击。

给定一个实例,模型中的方法可以被调用。用一些代码替换 catattack。 (这是我迄今为止最好的)

:helper all 只打开视图的助手。

这显示了如何创建一个类并调用它。 http://railscasts.com/episodes/101-refactoring-out-helper-object?autoplay=true

【讨论】:

【参考方案11】:

试试这个直接从你的控制器访问帮助函数view_context.helper_name

【讨论】:

【参考方案12】:

您可以使用 helper 关键字语法将您的辅助方法包含到控制器中

class MyController < ApplicationController
  helper ApplicationHelper

end

【讨论】:

以上是关于从 Rails 中的控制器调用辅助方法时出现“未定义的方法”的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Ruby on Rails 的控制台中调用控制器/视图辅助方法?

从 Rails 控制台重新加载帮助程序

如何在 Rails 中正确使用控制器辅助模块,以及如何连接这些辅助模块?

辅助方法不会通过 rails 控制台中的 `reload!` 重新加载

从 Rails 中的其他控制器调用方法

尝试在 Rails 中发布文件时出现 405 错误