当我尝试从我的一个控制器类访问我的一个辅助模块中定义的方法时,我得到NoMethodError
。我的Rails应用程序使用helper
类方法和:all
符号,如下所示:
class ApplicationController < ActionController::Base
helper :all
.
.
end
我的理解是,这应该使我的所有控制器类自动包含app / helpers目录中的所有辅助模块,因此将所有方法混合到控制器中。这是对的吗?
如果我在控制器中明确include
辅助模块,那么一切正常。
答案 0 :(得分:134)
使用模板引擎中已包含的辅助方法:
@template
变量。 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
答案 1 :(得分:49)
helper :all
使视图中的所有助手(是的,所有助手)都可用,它不会将它们包含在控制器中。
如果你想在helper和controller之间共享一些代码,这不是很理想,因为helper是UI代码而控制器是控制器代码,你可以在控制器中包含帮助器,或者创建一个单独的模块和包括控制器和助手中的那些。
答案 2 :(得分:30)
如果你需要在控制器和助手/视图之间共享一个方法,你可以通过控制器顶部的'helper_method'进行定义:
class ApplicationController < ActionController::Base
helper_method :my_shared_method
...
def my_shared_method
#do stuff
end
end
希望有所帮助
答案 3 :(得分:28)
获取辅助方法的一种方法就是包含辅助文件。
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中,默认情况下,此选项始终为每个控制器启用。
答案 4 :(得分:7)
对于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/
答案 5 :(得分:5)
我觉得最需要的时候是写flash或自定义错误检查器。在某些情况下,很高兴在flash消息中使用link_to helpers之类的东西。我使用以下解决方案将ActionView助手添加到控制器中。请注意,如上所述,这打破了MVC分离,所以如果其他人有更好的想法,请告诉我!
在ApplicationController下面添加:
class Something
include Singleton
include ActionView::Helpers::UrlHelper
end
并在ApplicationController内添加
def foo
Something.instance
end
最后,在您要访问帮助程序代码的控制器中:
messages << "<li class='error'>Your have an Error!<%= foo.link_to('Fix This', some_path) %></li>"
希望以某种方式有所帮助!
答案 6 :(得分:5)
使用helpers方法可能更简洁:
class FooController < ActionController::Base
def action
self.class.helpers.helper_method arg
end
end
答案 7 :(得分:4)
可以使用控制器中的@template变量访问任何帮助程序。
@ template.my_super_helper
答案 8 :(得分:3)
Controller无法自动访问辅助方法。我们必须将它们包含在app控制器中。
模块ApplicationHelper
def hello_message
"Hello World"
end
端
class ApplicationController&lt;的ActionController ::基
include ApplicationHelper
def message
hello_message
end
端
答案 9 :(得分:2)
助手将与模板一起使用,即。视图,而不是控制器。这就是你无法访问该方法的原因。如果您想在两个控制器之间共享方法,则必须在ApplicationController中定义它。 helper:all表示你在app / helpers目录中的任何helper文件中定义的任何方法都可用于任何模板。
答案 10 :(得分:1)
有两种方法可以做到这一点:创建模块或使用@template变量。查看更多详细信息 http://www.shanison.com/?p=305
答案 11 :(得分:0)
如果您的app/helpers
文件夹中只有ApplicationHelper,则必须使用include ApplicationHelper
将其加载到控制器中。默认情况下,Rails仅加载与控制器同名的辅助模块。 (例如,ArticlesController将加载ArticlesHelper)。如果您有许多模型(例如文章;帖子;类别),那么您必须在控制器中上传每个模型。 the docs
辅助
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
答案 12 :(得分:0)
如果您将application_controller.rb文件更改为此...
{{1}}
...然后所有控制器都可以使用所有助手。
答案 13 :(得分:0)
请在ApplicationController中尝试include SessionsHelper
class ApplicationController < ActionController::Base
include SessionsHelper
...
end