跳至内容 跳至搜索
命名空间
方法
#
A
R

常量

RENDERERS = Set.new
 

包含对应于可用渲染器 proc 的渲染器名称的集合。默认值为 `:json`、`:js`、`:xml`。

类公共方法

_render_with_renderer_method_name(key)

# File actionpack/lib/action_controller/metal/renderers.rb, line 89
def self._render_with_renderer_method_name(key)
  "_render_with_renderer_#{key}"
end

add(key, &block)

在控制器动作中添加一个新的渲染器以进行调用。渲染器通过将它的名称作为选项传递给 AbstractController::Rendering#render 来调用。要创建渲染器,请传递一个名称和一个块。块接收两个参数,第一个参数是与其键配对的值,第二个参数是传递给 render 的其余选项哈希。

创建一个 csv 渲染器

ActionController::Renderers.add :csv do |obj, options|
  filename = options[:filename] || 'data'
  str = obj.respond_to?(:to_csv) ? obj.to_csv : obj.to_s
  send_data str, type: Mime[:csv],
    disposition: "attachment; filename=#{filename}.csv"
end

注意,我们使用了 Mime 作为 csv 的 mime 类型,因为它与 Rails 一起提供。对于自定义渲染器,您需要使用 Mime::Type.register 注册一个 mime 类型。

在控制器动作中使用 csv 渲染器

def show
  @csvable = Csvable.find(params[:id])
  respond_to do |format|
    format.html
    format.csv { render csv: @csvable, filename: @csvable.name }
  end
end
# File actionpack/lib/action_controller/metal/renderers.rb, line 73
def self.add(key, &block)
  define_method(_render_with_renderer_method_name(key), &block)
  RENDERERS << key.to_sym
end

remove(key)

此方法与 add 方法相反。

删除 csv 渲染器

ActionController::Renderers.remove(:csv)
# File actionpack/lib/action_controller/metal/renderers.rb, line 83
def self.remove(key)
  RENDERERS.delete(key.to_sym)
  method_name = _render_with_renderer_method_name(key)
  remove_possible_method(method_name)
end

实例公共方法

_render_to_body_with_renderer(options)

# File actionpack/lib/action_controller/metal/renderers.rb, line 143
def _render_to_body_with_renderer(options)
  _renderers.each do |name|
    if options.key?(name)
      _process_options(options)
      method_name = Renderers._render_with_renderer_method_name(name)
      return send(method_name, options.delete(name), options)
    end
  end
  nil
end

render_to_body(options)

AbstractController::Rendering 中的 render 调用,它将返回值设置为 response_body

如果找不到渲染器,super 将控制权返回给 ActionView::Rendering.render_to_body(如果存在)。

# File actionpack/lib/action_controller/metal/renderers.rb, line 139
def render_to_body(options)
  _render_to_body_with_renderer(options) || super
end