Skip to content

create_or_find_by creates record when parent is not persisted #54920

@jenshenny

Description

@jenshenny

Steps to reproduce

require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"
  gem "rails", github: "rails/rails", branch: "main"
  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 do |t|
    t.string :name
    t.timestamps
  end

  create_table :books do |t|
    t.string :name
    t.references :author
    t.timestamps
  end
end

class Author < ActiveRecord::Base
  has_many :books
end

class Book < ActiveRecord::Base
  belongs_to :author
end

class BugTest < Minitest::Test
  def test_find_or_create_by_with_destroyed_owner
    author = Author.create!(name: "Test Author")
    author.destroy!

    assert_raises(ActiveRecord::RecordNotSaved) do
      author.books.create_or_find_by!(name: "Test Book")
    end
  end
end

Expected behavior

A ActiveRecord::RecordNotSaved is raised with You cannot call create unless the parent is saved. I'd expect create_or_find_by to act like create and raise this error.

Actual behavior

The new record is created.

System configuration

Rails version:
Rails main since #54845

cc: @Edouard-chin

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions