2012-04-13 2 views
21

Я использую JBuilder, чтобы вернуть некоторые JSON. У меня есть index.json.jbuilder, который генерирует данные, и мне нужно отобразить его в строке. Однако я не уверен, как это сделать, поскольку: @my_object.to_json и @my_object.as_json, похоже, не проходят через JBuilder.Как передать строку JSON-представление представления JBuilder?

Как можно визуализировать представление JBuilder как строку?

+0

Вы пытаетесь вернуть JSON с контроллера как ответ JSON или буквально построить строку JSON в изоляции? – Winfield

ответ

39

Я рендеринга коллекцию пользователей в виде строки 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 
+0

Привет, Аарон, я пробовал реализовать вышеупомянутую технику, но когда я перехожу на страницу, я получаю недостающую ошибку шаблона: «Отсутствует шаблон /work.json с {: locale => [: en],: formats => [: html],: handlers => [: erb,: builder,: arb,: jbuilder,: coffee]}. " Я немного новичок в рельсах и не совсем уверен, что происходит. Любая помощь будет очень высоко ценится. Заранее спасибо! – jordancooperman

+0

Я предполагаю, что вам может потребоваться добавить «reply_to: json» в ваш контроллер. –

+0

Я все еще получаю ту же ошибку с «reply_to: json» в моем контроллере – jordancooperman

2

Глядя на исходный код, он выглядит, как вы можете сделать:

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

Я пробовал около 20 минут в оболочке, чтобы сделать это, без большой удачи. Если это не слишком много, чтобы спросить, не могли бы вы опубликовать рабочий пример этого? – Geo

+0

Я вытащил этот фрагмент кода из примеров Jbuilder в документах: https://github.com/rails/jbuilder Похоже, что встроенные шаблоны могут быть разбиты под Ruby 1.8 и работать только с Ruby 1.9 и выше. – Winfield

+0

Это не работает для меня. – maletor

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> 
+0

Я бы предпочел этот подход, также вы можете сделать его агностическим, отбросив часть формата из расширений, т. Е. '_partial.jbuilder' может использоваться изнутри json и html-представлений. – wik

+0

Этот подход хорош, за исключением того, что он не работает в атрибутах данных 'content_tag'. Что дает? – maletor

8

Если вид users.json.jbuilder находится на пути по умолчанию по отношению к контроллеру с, и он не может найти шаблон, это может быть связано с format несоответствие, так как она может пытаться искать файл формата html. Есть два способа исправить это:

  1. Пусть клиент GET /users/index.json

    или

  2. Укажите опцию formats при вызове render_to_string (также относится и к render):


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

Это подтверждено в Rails 4.1.

+0

Я думаю, что это должно рассматриваться как решение, поскольку оно работает для обычного случая и намного проще, чем выбранное решение. –

+2

Любой, кто стоит на рельсах 4.1, должен использовать ЭТОТ ответ. – Stone

2

Если вы делаете это в контроллере, гораздо проще вариант, чтобы попытаться двигаться код в поле зрения, оказываемые контроллером ,

Я описал это здесь: https://github.com/shakacode/react-webpack-rails-tutorial#jbuilder-notes

В принципе вы можете позвонить 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 
0

контроллера вы можете сделать, как это

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

Обратите внимание, что вам нужно «_index.json.. JBuilder», потому что он вызывает частичный визуализатор

0

После кончика justingordon в

Если вы используете Реагировать компонент, вы можете сделать следующее

В контроллере:.

@users = User.all 

В вашем вид:

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

Это тестирование было проверено на Rails 5.1.

Смежные вопросы