Skip to content

Rails 7.1: incorrect path when submitting form for a singular resource #49604

@jp524

Description

@jp524

Steps to reproduce

When submitting a form with an error, Rails 7.1 redirects to incorrect path when the resource is singular.
This may be an issue with Turbo (see expected and actual behaviors below).

# frozen_string_literal: true

require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"

  git_source(:github) { |repo| "https://github.com/#{repo}.git" }

  # Activate the gem you are reporting the issue against.
  gem "rails", "~> 7.1.0"
  gem "sqlite3"
end

require "active_record"
require "minitest/autorun"
require "logger"

# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)

ActiveRecord::Schema.define do
  create_table :authors, force: true do |t|
    t.string :name
  end
end

class Author < ActiveRecord::Base
  validates :name,
            format: { with: /\A[a-zA-Z0-9-]{0,39}\z/, message: 'can only contain alphanumeric characters and dashes' },
            length: { maximum: 39 }
end

require "rack/test"
require "action_controller/railtie"

class TestApp < Rails::Application
  config.root = __dir__
  config.hosts << "example.org"
  config.session_store :cookie_store, key: "cookie_store_key"
  config.secret_key_base = "secret_key_base"

  config.logger = Logger.new($stdout)
  Rails.logger  = config.logger

  routes.draw do
    resource :author, only: %i[edit update]
  end
end

class AuthorsController < ActionController::Base
  include Rails.application.routes.url_helpers

  before_action :set_author, only: %i[edit update]

  def edit; end

  def update
    if @author.update(author_params)
      redirect_to edit_author_path
    else
      render :edit, status: :unprocessable_entity
    end
  end

  private

  def set_author
    @author = Author.find(1) # Actual application would use session to find author logged in
  end

  def author_params
    params.require(:author).permit(:name)
  end
end

class BugTest < Minitest::Test
  include Rack::Test::Methods

  Author.create!(name: 'name')

  def test_author_updated_success
    patch '/author', { author: { name: 'validName' } }
    assert_equal 'http://example.org/author/edit', last_response.headers['location']
  end

  def test_author_updated_failure
    patch '/author', { author: { name: 'invalid!!!name?' } }
    assert_equal 'http://example.org/author/edit', last_response.headers['location']
  end

  private

  def app
    Rails.application
  end
end

Expected behavior

The request path should be author/edit.
The console in Rails 7.0.8 showed

Started PATCH "/author" for 127.0.0.1 at 2023-10-12 09:22:13 -0400
Processing by AuthorsController#update as TURBO_STREAM

Actual behavior

The request path is author/#{author.id}”.
The console in Rails 7.1.0 shows

Started PATCH "/author.1" for 127.0.0.1 at 2023-10-12 09:21:10 -0400
Processing by AuthorsController#update as */*

System configuration

Rails version: 7.1.0

Ruby version: 3.2.2

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions