概要
Ajaxを用いた非同期通信でコメントを表示する機能の開発時、JSONレスポンスとHTML表示の両立に苦労したので記録として。
「json 画面 黒 配列 htlm 表示されない」などのワードで検索してもバシッと同じ状況の解決策が出てこず、何日もハマったのでどなたかの参考になれば。
結論
リクエストに対するレスポンスでJSOMとHTMLの両方をformatで明示する。
def index
@default_avatar_url = view_context.asset_path('default-avatar.png')
@comment = @article.comments.new
@comments = @article.comments.order(created_at: :desc)
respond_to do |format|
format.html # HTMLページとしてコメント一覧を表示
format.json do # JSONレスポンスとしてコメントデータを返す
comments_json = @comments.as_json(include: {
user: {
only: [:username, :display_name, :id], # 必要なユーザー情報を指定
methods: :profile_image_url # プロフィール画像のURLを返すメソッド
}
})
comments_json.each do |comment|
comment["is_current_user"] = (comment["user"]["id"] == current_user.id)
end
render json: comments_json
end
end
end
上記のコードはHTMLフォーマットのリクエストがあった場合、通常のHTMLページとしてコメント一覧を表示する。
JSONフォーマットのリクエストがあった場合、コメントデータをJSON形式で返す。
このような形式にすればHTMLの表示とJSONレスポンスによる動的なHTMLの生成を両立できる。
経緯
JSONレスポンスを取得して動的にHTMLを生成するページを作成しようとしたところ、真っ黒な画面に配列だけが表示されてしまう減少に直面。
特にエラーが発生しているわけでなく、失敗の原因が掴めないまま何日も解決できなかった
原因は「Railsはアクション名に対応するビューファイルに自動でレンダリングする=どんなときでもHTML表示される」と思っていたこと。
当初はJSONレスポンスの記述さえ行っていればHTMLページが生成され、遷移すると思い込んでいた。
しかし、調べたところJSONレスポンスがある場合はHTMLの生成より優先されてしまい、JSONレスポンス内の配列データだけが渡ってしまうということだった。画面に配列だけが表示された原因はこれ。
そこで、上記のformatを記述してHTMLの生成とJSONレスポンスを両立するコードを明示。
HTML表示と動的なHTML生成を両立できた。