diff --git a/docs/UPGRADING.md b/docs/UPGRADING.md index 0678921b15..6adbf27c61 100644 --- a/docs/UPGRADING.md +++ b/docs/UPGRADING.md @@ -398,6 +398,27 @@ end Note the block: a bare `inverse_of nil` reads the option rather than setting it. +## The show action answers HTML by default + +`show` used to declare its JSON format before its HTML one, so a request carrying no +`Accept` header — `curl`, a bare `fetch()`, most HTTP client libraries — arrived as +`*/*`, matched every registered type, and got JSON back. Every other action answered +HTML for the same request. + +It now declares HTML first. A client that explicitly sends `Accept: application/json`, +or requests the `.json` extension, is unaffected. + +If you have a script relying on the unheadered JSON response, send the header or use +`.json`: + +```bash +curl -H 'Accept: application/json' https://example.com/admin/player/1 +curl https://example.com/admin/player/1.json +``` + +Note that the JSON branch renders the whole record, including columns the model config +hides from the show view. + ## Dropped support These are intentionally gone — migrate off them before upgrading: diff --git a/lib/rails_admin_next/config/actions/show.rb b/lib/rails_admin_next/config/actions/show.rb index b0e0d036d4..ab1f840149 100644 --- a/lib/rails_admin_next/config/actions/show.rb +++ b/lib/rails_admin_next/config/actions/show.rb @@ -20,9 +20,11 @@ class Show < RailsAdminNext::Config::Actions::Base register_instance_option :controller do proc do + # HTML first: an Accept-less request arrives as */*, which matches every + # registered type, so Rails falls back to whichever is declared first. respond_to do |format| - format.json { render json: @object } format.html { render @action.template_name } + format.json { render json: @object } end end end diff --git a/spec/integration/actions/show_spec.rb b/spec/integration/actions/show_spec.rb index 3b0bf811db..6471c37530 100644 --- a/spec/integration/actions/show_spec.rb +++ b/spec/integration/actions/show_spec.rb @@ -47,6 +47,15 @@ end end + context "with no explicit format" do + it "responds with HTML" do + page.driver.options[:headers] = {"HTTP_ACCEPT" => "*/*"} + visit show_path(model_name: "team", id: team.id) + + expect(Mime::Type.parse(response_headers["Content-Type"]).first).to be_html + end + end + context "when compact_show_view is enabled" do it "hides nil fields in show view by default" do visit show_path(model_name: "team", id: team.id)