webentwicklung-frage-antwort-db.com.de

Wie kann ich eine JSON-Darstellung einer JBuilder-Ansicht in einem String rendern?

Ich verwende JBuilder as, um JSON zurückzugeben. Ich habe einen index.json.jbuilder, der die Daten generiert, und ich muss sie in eine Zeichenfolge rendern. Ich bin mir jedoch nicht sicher, wie ich das machen soll, da: @my_object.to_json und @my_object.as_json nicht über JBuilder zu laufen scheinen.

Wie kann ich die JBuilder-Ansicht als String rendern?

22
Geo

Ich rendere eine Sammlung von Benutzern wie folgt als JSON-Zeichenfolge im Controller:

#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
42
Aaron Renoir

Wenn sich die Ansicht users.json.jbuilder im Standardpfad relativ zum Controller befindet und die Vorlage nicht gefunden werden kann, liegt möglicherweise eine format Diskrepanz vor, da möglicherweise versucht wird, nach der html-Formatdatei zu suchen. Es gibt zwei Möglichkeiten, dies zu beheben:

  1. Lassen Sie den Client /users/index.json abrufen.

    oder

  2. Geben Sie die Option formats an, wenn Sie render_to_string aufrufen (gilt auch für render):


#controllers/users_controller.rb
def index
  @users = User.all
  @users_json = render_to_string( formats: 'json' ) # Yes formats is plural
end

Dies wurde in Rails 4.1 verifiziert.

9
Matt

Sie können es auch so machen, wodurch Ihr Controller etwas sauberer wird.

# 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
asgeo1

Wenn Sie dies im Controller tun, ist es viel einfacher, den Code in die vom Controller gerenderte Ansicht zu verschieben.

Ich habe dies hier beschrieben: https://github.com/shakacode/react-webpack-Rails-tutorial/blob/master/docs/jbuilder.md

grundsätzlich können Sie render in der Ansicht aufrufen, und Sie sind fertig. So was:

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

Hier sind die Hinweise, was passiert, wenn Sie die Daten von der Steuerung an die Ansicht übergeben möchten:

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
3
justingordon

Im Quellcode sieht es so aus, als ob Sie Folgendes tun können:

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

Von der Konsole:

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

via https://github.com/Rails/jbuilder/issues/84#issuecomment-38109709

1
James EJ

in controller kannst du das so machen

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

beachten Sie, dass Sie "_index.json.jbuilder" benötigen, da es einen partiellen Renderer aufruft

0
kuboon

Justingordons Tipp folgen.

Wenn Sie eine React-Komponente verwenden, können Sie Folgendes tun.

In Ihrem Controller:

@users = User.all

Ihrer Ansicht nach:

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

Dies wurde auf Rails 5.1 getestet.

0
kairon