我怎样才能将字符串呈现为JBuilder视图的JSON表示?

时间:2012-04-13 08:03:51

标签: ruby-on-rails json jbuilder

我正在使用JBuilder来返回一些JSON。我有index.json.jbuilder生成数据,我需要将其渲染为字符串。但是,我不确定如何执行此操作,因为:@my_object.to_json@my_object.as_json似乎没有通过JBuilder。

如何将JBuilder视图呈现为字符串?

8 个答案:

答案 0 :(得分:43)

我在控制器中将一组用户呈现为json字符串,如下所示:

#controllers/users_controller.rb
def index
  @users = User.all
  @users_json = render_to_string( template: 'users.json.jbuilder', locals: { users: @users})
end

#views/users/users.json.jbuilder
json.array!(users) do |json, user|
  json.(user, :id, :name)
end

答案 1 :(得分:9)

如果视图users.json.jbuilder位于相对于控制器的默认路径并且找不到模板,则可能是由于format差异造成的,因为它可能正在尝试查找{ {1}}格式文件。有两种方法可以解决这个问题:

  1. 让客户获得html

  2. 在致电/users/index.json时指定formats选项(也适用于render_to_string):


  3. render

    这已在Rails 4.1中得到验证。

答案 2 :(得分:3)

你也可以这样做,这会让你的控制器更清洁。

# controller
def new
  @data = Data.all
end


# view
<% content_for :head do %>
  <script type="text/javascript">
    var mydata = <%= raw render :partial => 'path/to/partial', :locals => {data: @data} %>;
  </script>
<% end %>


# path/to/_partial.html.jbuilder
json.array!(@data) do |d|
  json.extract! field1, :field2, :field3, :field4
  json.url data_url(d, format: :json)
end


# layouts/application.html
<!DOCTYPE html>
<html>
<head>
  <%= yield :head %>
</head>
<body>
...
</body>
</html>

答案 3 :(得分:3)

如果您在控制器中执行此操作,则更简单的选择是尝试将代码移动到控制器呈现的视图中。

我在这里描述了这个: https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/docs/jbuilder.md

基本上你可以在视图中调用render,然后就完成了。像这样:

<%= react_component('App', render(template: "/comments/index.json.jbuilder"),
    generator_function: true, prerender: true) %>

如果您想将数据从控制器传递到视图,请注意以下内容:

class PagesController < ApplicationController
  def index
    @comments = Comment.all

    # NOTE: The below notes apply if you want to set the value of the props in the controller, as
    # compared to he view. However, it's more convenient to use Jbuilder from the view. See
    # app/views/pages/index.html.erb:20
    #
    #  <%= react_component('App', render(template: "/comments/index.json.jbuilder"),
    #     generator_function: true, prerender: true) %>
    #
    #
    # NOTE: this could be an alternate syntax if you wanted to pass comments as a variable to a partial
    # @comments_json_sting = render_to_string(partial: "/comments/comments.json.jbuilder",
    #                                         locals: { comments: Comment.all }, format: :json)
    # NOTE: @comments is used by the render_to_string call
    # @comments_json_string = render_to_string("/comments/index.json.jbuilder")
    # NOTE: It's CRITICAL to call respond_to after calling render_to_string, or else Rails will
    # not render the HTML version of the index page properly. (not a problem if you do this in the view)
    # respond_to do |format|
    #   format.html
    # end
  end
end

答案 4 :(得分:2)

查看源代码,看起来你可以这样做:

json_string = Jbuilder.encode do |json|
  json.partial! 'path/to/index', @my_object
end

答案 5 :(得分:1)

来自控制台:

view = ApplicationController.view_context_class.new("#{Rails.root}/app/views")
JbuilderTemplate.encode(view){|json| json.partial!('path/to/index', @my_object) }

通过https://github.com/rails/jbuilder/issues/84#issuecomment-38109709

答案 6 :(得分:0)

在控制器中你可以这样做

def index
  json = JbuilderTemplate.new(view_context) do |json|
    json.partial! 'index'
  end.attributes!
  do_something(json)
  render json: json
end

请注意,您需要&#34; _index.json.jbuilder&#34;因为它调用了部分渲染器

答案 7 :(得分:0)

按照justingordon的提示。

如果您使用的是React组件,则可以执行以下操作。

在您的控制器中:

@users = User.all

在您看来:

<%= react_component("YourComponentName",
                    props: render('your_template.json.jbuilder')) %>

这是在Rails 5.1上测试的。