Ruby-on-rails 在 Rails 3 中,如何在 JSON 响应中呈现 HTML?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2459787/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 22:24:19  来源:igfitidea点击:

In Rails 3, how does one render HTML within a JSON response?

ruby-on-railsjsonmerb

提问by ylg

I'm porting an application from Merb 1.1 / 1.8.7 to Rails 3 (beta) / 1.9.1 that uses JSON responses containing HTML fragments, e.g., a JSON container specifying an update, on a user record, and the updated user row looks like . In Merb, since whatever a controller method returns is given to the client, one can put together a Hash, assign a rendered partial to one of the keys and return hash.to_json (though that certainly may not be the best way.) In Rails, it seems that to get data back to the client one must use render and render can only be called once, so rendering the hash to json won't work because of the partial render.

我正在将一个应用程序从 Merb 1.1 / 1.8.7 移植到 Rails 3 (beta) / 1.9.1,该应用程序使用包含 HTML 片段的 JSON 响应,例如,一个 JSON 容器指定更新、用户记录和更新的用户行好像 。在 Merb 中,由于控制器方法返回的任何内容都被提供给客户端,因此可以组合一个哈希,将呈现的部分分配给其中一个键并返回 hash.to_json(尽管这当然可能不是最好的方法。)在 Rails 中,似乎要将数据返回给客户端必须使用渲染并且渲染只能调用一次,因此由于部分渲染,将哈希渲染为 json 将不起作用。

From reading around, it seems one could put that data into a JSON .erb view file, with <%= render partial %> in and render that. Is there a Rails-way of solving this problem (return JSON containing one or more HTML fragments) other than that?

通过阅读,似乎可以将该数据放入 JSON .erb 视图文件中,并在 <%= render partial %> 中进行渲染。除此之外,是否有解决此问题的 Rails 方法(返回包含一个或多个 HTML 片段的 JSON)?

In Merb:
controller:

在 Merb 中:
控制器:

only_provides :json
...
self.status = 204 # or appropriate if not async
return {
    'action' => 'update',
      'type' => 'user',
        'id' => @user.id,
      'html' => partial('user_row', format: :html, user: @user)
}.to_json

In Rails:
controller:

在 Rails 中:
控制器:

respond_to do |format|
  format.json do
    render template: '/json/message-1', 
      locals: { 
        action: 'update',
        type: 'user',
        id: @user.id,
        partial: 'user_row.html.erb', 
        locals: { user: @user }
      }
  end
end

view: json/message-1.json.erb

视图:json/message-1.json.erb

{
  "action": <%= raw action.to_json %>,
  "type": <%= raw type.to_json %>,
  "id": <%= raw id.to_json %>,
  "html": <%= raw render(partial: partial, locals: locals).to_json %>
}

回答by ylg

The closest to the original from Merb approach I could find in Rails is to use #render_to_string

我在 Rails 中可以找到的最接近 Merb 原始方法的方法是使用#render_to_string

render json: {
  'action' => 'update',
    'type' => 'user',
      'id' => @user.id,
    'html' => render_to_string(partial: 'user_row.html.erb', locals: { user: @user })
}

This gets around a fair bit of complexity that comes in from adding a layer of json.erb templates into the mix, whether it's Rails Purist approach I couldn't say; possibly something with RJS would typically be used.

这解决了相当多的复杂性,因为在混合中添加了一层 json.erb 模板,我不能说是不是 Rails Purist 方法;可能通常会使用 RJS 的东西。

回答by ajh

There's another question that has more solutions for json.erb files. See json erb template cannot find other html partial

还有另一个问题对 json.erb 文件有更多的解决方案。见json erb模板找不到其他html部分

回答by Joshua Partogi

class UsersController < ApplicationController  
  respond_to :json

  def show  
    @user = User.find(params[:id])
    respond_with(@user) do |format|
      if @user.save
        format.json { render :json => @user }
      else
        format.json { render :json => @user.errors, :status => :unprocessable_entity }
      end
    end
  end
end