1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

JSONとHTML表示の両立

Last updated at Posted at 2024-02-29

概要

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生成を両立できた。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?