JSONを返すために JBuilder を使用しています。私はindex.json.jbuilder
データを生成し、それを文字列にレンダリングする必要があります。ただし、次の理由から、これを行う方法がわかりません。@my_object.to_json
および@my_object.as_json
JBuilderを経由していないようです。
JBuilderビューを文字列としてレンダリングするにはどうすればよいですか?
私は次のようにコントローラーでユーザーのコレクションを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
ビューusers.json.jbuilder
がコントローラーを基準にしたデフォルトのパスにあり、テンプレートが見つからない場合は、format
の不一致が原因である可能性があります。これは、html
フォーマットファイル。これを修正する方法は2つあります。
クライアントにGET/users/index.json
を依頼する
または
render_to_string
を呼び出すときにformats
オプションを指定します(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で確認されています。
このようにすることもできます。これにより、コントローラーが少しきれいになります。
# 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>
コントローラでこれを行う場合、はるかに簡単なオプションは、コントローラによってレンダリングされているビューにコードを移動しようとすることです。
私はこれをここで説明しました: 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
コンソールから:
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
ソースコードを見ると、次のことができるように見えます。
json_string = Jbuilder.encode do |json|
json.partial! 'path/to/index', @my_object
end
コントローラでは、このように行うことができます
def index
json = JbuilderTemplate.new(view_context) do |json|
json.partial! 'index'
end.attributes!
do_something(json)
render json: json
end
部分レンダラーを呼び出すため、「_ index.json.jbuilder」が必要であることに注意してください
Justingordonのヒントに従います。
Reactコンポーネントを使用している場合は、次のことができます。
コントローラ内:
@users = User.all
あなたの見解では:
<%= react_component("YourComponentName",
props: render('your_template.json.jbuilder')) %>
これはRails 5.1でテストされました。