从 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 中正确使用控制器辅助模块,以及如何连接这些辅助模块?