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

【Rails】"Status code :unprocessable_entity is deprecated"みたいな警告の修正方法

Last updated at Posted at 2025-09-24

はじめに: バリデーションエラー時に警告が出る!?

Railsで以下のようなコントローラがあったとします。

class BlogsController < ApplicationController
  # ...
  
  def create
    @blog = Blog.new(blog_params)

    respond_to do |format|
      if @blog.save
        format.html { redirect_to @blog, notice: "Blog was successfully created." }
        format.json { render :show, status: :created, location: @blog }
      else
        format.html { render :new, status: :unprocessable_entity }
        format.json { render json: @blog.errors, status: :unprocessable_entity }
      end
    end
  end
  
  # ...

バリデーションエラーが起きたときは以下のコードが実行されます。

format.html { render :new, status: :unprocessable_entity }
format.json { render json: @blog.errors, status: :unprocessable_entity }

が、rack 3.1.0 rack 3.2.0以降を使っている場合、このコードが実行されたタイミングで以下のような警告が出力されます1

warning: Status code :unprocessable_entity is deprecated and will be removed in a future version of Rack. Please use :unprocessable_content instead.

(ChatGPT翻訳)
警告: ステータスコード :unprocessable_entity は非推奨であり、Rack の将来のバージョンで削除されます。代わりに :unprocessable_content を使用してください。

この記事ではこの問題の対応方法を説明します。

対応方法その1: unprocessable_contentに書き替える

ひとつは警告の内容に従って、コード内の:unprocessable_entityをすべて:unprocessable_contentに書き替えることです。

-format.html { render :new, status: :unprocessable_entity }
+format.html { render :new, status: :unprocessable_content }

こうすると、警告が表示されなくなります。

ただし、gemの内部で:unprocessable_entityが使われていたりすると、コードの置換ができないので警告が出続けます。

対応方法その2: Rails 8.0.3以上にアップデートする(おすすめ🌟)

もう一つの方法は、Rails 8.0.3以上にアップデートすることです。

Gemfile
-gem "rails", "8.0.2.1"
+gem "rails", "8.0.3"
bundle update rails

2025年9月22日にリリースされたRails 8.0.3では、以下のプルリクエストがマージされています。

このプルリクエストでは、rack 3.1.0以上を利用している場合に、自動的に:unprocessable_entity:unprocessable_contentに切り替えてくれます。

そのため、既存のコードを書き替えずとも、rackの警告は表示されなくなります。

また、gemの内部で:unprocessable_entityが使われていたりした場合でも、Railsがうまく処理してくれるはずです。

参考情報1: Rails 7.2でもそのうち対応されるはず

この修正はRails 7.2のブランチにも適用されています。
ただし本記事の執筆時点(2025年9月24日)では、まだ公式リリースされていません。
おそらくこの修正は次のバージョン(7.2.3?)でリリースされると思います。

ただし、Rails 7.2ではこの警告に遭遇するケースはまれだと思われます。
その理由についてはコメント欄を参照してください。

参考情報2: scaffoldで生成されるコードはどうなる?

上で紹介した修正PRでは、scaffoldで使われるテンプレートも:unprocessable_entity:unprocessable_contentを適切に使い分けるように修正されています。

試しにscaffoldを実行してみましょう。

rails g scaffold Post content:text

生成されたコードを見てみると・・・

class PostsController < ApplicationController
  # ...
  
  def create
    @post = Post.new(post_params)

    respond_to do |format|
      if @post.save
        format.html { redirect_to @post, notice: "Post was successfully created." }
        format.json { render :show, status: :created, location: @post }
      else
        format.html { render :new, status: :unprocessable_entity }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end
  
  # ...

あれ、:unprocessable_entityのままですね💦

これ、実はRails本体のジェネレータではなく、jbuilder gemのジェネレータが使われているせいです。

そこで、jbuilderを消してから、もう一度scaffoldを実行してみます。

Gemfile
-gem "jbuilder"
bundle install
rails g scaffold Post content:text

生成されたコードはこちらです。

class PostsController < ApplicationController
  # ...
  
  def create
    @post = Post.new(post_params)

    if @post.save
      redirect_to @post, notice: "Post was successfully created."
    else
      render :new, status: :unprocessable_content
    end
  end
  
  # ...

はい、今度は:unprocessable_contentが使われるようになりました!

Rails 8.0.3以上を使っていれば :unprocessable_entityでも:unprocessable_contentでも、どっちでも警告は出なくなるとはいえ、jbuilderの有無によってscaffoldの挙動が異なることは頭の片隅に置いといてもいいかもしれません。

(参考)
こちらに修正PRが出ているので、もしかするとjbuilderもそのうち対応されるかも?

ところで、unprocessable entityとunprocessable contentって何なん?

unprocessable entityとunprocessable contentはどちらもHTTPステータスコード422に対応する名称です。

HTTPステータスコード422の意味は以下の通りです。

HTTP の 422 Unprocessable Content はクライアントエラーレスポンスステータスコードで、サーバーがリクエストコンテンツのコンテンツ型を理解し、リクエストコンテンツの構文が正しいことを示していますが、コンテンツに格納された指示を処理することができなかったことを表します。
https://developer.mozilla.org/ja/docs/Web/HTTP/Reference/Status/422

422はもともとはunprocessable entityと呼ばれていたが(参考)、RFC 9110 (HTTP/1.1 Semantics, 2022)でunprocessable contentという名前に変わったみたいですね。

つまり、

  • unprocessable entity(old)
  • unprocessable content(NEW!)

というわけです。

Rack 3.1から仕様が変わったのは、この名称変更に従った結果です。

ですので、Railsでもこれから新しいコードを書くときは、:unprocessable_entityではなく、:unprocessable_contentを使った方がいいと思います。

まとめ

というわけで、この記事ではRailsでたまに見かける"Status code :unprocessable_entity is deprecated"みたいな警告の対処方法を説明してみました。

ざっくりまとめると、

  • 最新のRailsにアップデートしよう!
  • これから新規に書くコードは:unprocessable_entityではなく、:unprocessable_contentを使おう!

という感じですね。

みなさん、この方針で対処していってください!

  1. rack 3.1.0で一度警告が出力されるようになりましたが、rack 3.1.3で警告が出ないように修正されました(参照

3
0
3

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