试图从 Rails 控制器调用 helper 方法时的 NoMethodError 错误

当试图从控制器类中访问在帮助器模块中定义的方法时,我得到了一个 NoMethodError。我的 Rails 应用程序使用带有 :all符号的 helper类方法,如下所示:

class ApplicationController < ActionController::Base
helper :all
.
.
end

我的理解是,这应该使我的所有控制器类自动包含 app/helpers 目录中的所有 helper 模块,从而将所有方法混合到控制器中。是这样吗?

如果我显式地 include控制器中的助手模块,那么一切都正常工作。

59352 次浏览

助手与模板一起使用。视图,而不是在控制器中。这就是为什么你不能访问这个方法。如果希望在两个控制器之间共享一个方法,那么必须在 ApplicationController 中定义它。Helper: all 表示在 app/helpers 目录中的任何 helper 文件中定义的任何方法都可用于任何模板。

helper :all使视图中的所有助手(是的,所有的助手)都可用,它不将它们包括在控制器中。

如果您希望在 helper 和 controller 之间共享一些代码,这是不太可取的,因为 helper 是 UI 代码,而 controller 是,嗯,控制器代码,您可以将 helper 包含在控制器中,或者创建一个单独的模块,并将其包含在控制器和 helper 中。

当我发现这是最需要的时候,是写的闪光灯,或自定义错误检查器。在某些情况下,在 flash 消息中使用 link _ to helpers 之类的东西是很好的。我使用以下解决方案将 ActionView 帮助程序放入控制器中。请注意,如上所述,这打破了 MVC 分离,所以如果有人有更好的主意,让我知道!

在 ApplicationController 下面添加以下内容:

class Something
include Singleton
include ActionView::Helpers::UrlHelper
end

在 ApplicationController 中,添加

def foo
Something.instance
end

最后,在要访问 helper 代码的控制器中:

messages << "<li class='error'>Your have an Error!<%= foo.link_to('Fix This', some_path) %></li>"

希望能有所帮助!

控制器的辅助方法

获取助手方法的一种方法是简单地包含助手文件。

include LoginHelper
cool_login_helper_method(x,y,z)

这将把来自该助手模块的所有方法都放入控制器的作用域中。这并不总是好事。为了保持作用域独立,创建一个对象,赋予它助手的能力,并使用它来调用方法:

login_helper = Object.new.extend(LoginHelper)
login_helper.cool_login_helper_method(x,y,z)

所有人

helper :all使所有助手模块中的所有助手方法对所有 观点都可用,但是它对控制器没有任何作用。这是因为助手方法是为在视图中使用而设计的,通常不应该从控制器访问。在 Rails 的较新版本中,默认情况下,每个控制器的此选项始终处于打开状态。

如果你需要在控制器和 helper/view 之间共享一个方法,你可以通过控制器顶部的“ helper _ method”来定义:

class ApplicationController < ActionController::Base
helper_method :my_shared_method
...


def my_shared_method
#do stuff
end
end

希望能帮上忙

可以使用控制器中的@template 变量访问任何助手。

@ template. my _ super _ helper

有两种方法可以做到这一点: 要么创建一个模块,要么使用@template 变量。看看这个了解更多细节 Http://www.shanison.com/?p=305

使用模板引擎中已经包含的 helper 方法:

  • Rails 2: 使用 @template变量。
  • Rails 3: 拥有漂亮的控制器方法 view_context

在控制器方法中调用‘ number _ to _ currency’的用法示例:

# rails 3 sample
def controller_action
@price = view_context.number_to_currency( 42.0 )
end


# rails 2 sample
def controller_action
@price = @template.number_to_currency( 42.0 )
end

使用 帮手方法可能更为干净:

class FooController < ActionController::Base
def action
self.class.helpers.helper_method arg
end
end

对于 Rails 3,在控制器中使用 view_context方法:

def foo
view_context.helper_method
...

这里有一个例子: http://www.christopherirish.com/2011/10/13/no-view_context-in-rails-3-1-changes/

控制器不能自动访问辅助方法。我们必须在应用程序控制器中包含它们。

单元应用程式辅助工具

 def hello_message
"Hello World"
end

结束

Class ApplicationController < ActionController: : Base

  include ApplicationHelper


def message
hello_message
end

结束

如果在 app/helpers文件夹中只有 ApplicationHelper,那么必须用 include ApplicationHelper将其加载到控制器中。默认情况下,Rails 只加载与控制器同名的 helper 模块。(例如,ArticlesController 将加载 ArticlesHelper)。如果你有很多模型(比如文章、帖子、分类) ,你必须把它们上传到你的控制器中。那些文件

帮手

module PostsHelper
def find_category(number)
return 'kayak-#{number}'
end
def find_other_sport(number)
"basketball" #specifying 'return' is optional in ruby
end
end


module ApplicationHelper
def check_this_sentence
'hello world'
end


end

示例控制器

class ArticlesController < ApplicationController
include ApplicationHelper
include PostsHelper
#...and so on...


def show#rails 4.1.5
#here I'm using the helper from PostsHelper to use in a Breadcrumb for the view
add_breadcrumb find_other_sport(@articles.type_activite), articles_path, :title => "Back to the Index"
#add_breadcrumb is from a gem ...
respond_with(@articles)
end
end

如果将 application _ controller. rb 文件更改为..。

class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
include SessionsHelper
end

... 那么所有的辅助人员都可以被所有的控制人员使用。

请在应用程序控制器中尝试 include SessionsHelper

class ApplicationController < ActionController::Base
include SessionsHelper
...
end