view_context
有时想在controller中调用一些view的helper,如raw、j、t之类,可通过view_context来调
看看这个方法来自哪里
[1] pry(main)> ctrl = StudentsController.new
=> #<studentscontroller:0x007f5bfc4a5240 @_action_has_layout="true," @_request="nil," @_response="nil," @_routes="nil">
[2] pry(main)> binding.trace_tree(htmp: 'view_context/vc'){ ctrl.view_context }
=> #<#:0x007f5bfae45bf8
@_assigns={},
@_config={},
@_controller=
#<studentscontroller:0x007f5bfc4a5240 #="" ...<="" code=""></studentscontroller:0x007f5bfc4a5240> </studentscontroller:0x007f5bfc4a5240>
调用栈如下
想知道view_context上有什么方法可用,当然可以直接view_context.methods.sort打印出来,但为了有个系统一点概念,还是看看源码它是怎样定义这些方法的。简单来说,这些方法是分布在actionpack、actionview的各个功能module中的,然后通过继承和mixin而加进来,脉络如下

源码如下
module ActionView
module Rendering
module ClassMethods
def view_context_class
@view_context_class ||= begin
supports_path = supports_path?
routes = respond_to?(:_routes) && _routes
helpers = respond_to?(:_helpers) && _helpers
Class.new(ActionView::Base) do
if routes
include routes.url_helpers(supports_path)
include routes.mounted_helpers
end
if helpers
include helpers
end
end
end
end
end
attr_internal_writer :view_context_class
def view_context_class
@_view_context_class ||= self.class.view_context_class
end
def view_context
view_context_class.new(view_renderer, view_assigns, self)
end
不过一般来说,像url_helpers这些其实controller中本来就有了(mixin到了controller的ancestors的匿名module中),在controller中使用view_context主要还是为了获得ActionView::Base所mixin的那些页面helper(如果真的有必要在controller里干view的活……)