rails icon indicating copy to clipboard operation
rails copied to clipboard

Active record association not attached (or detached) with config.load_defaults 7.0

Open aglushkov opened this issue 2 years ago • 2 comments

Steps to reproduce

This works with load_defaults 6.0 and raises error with load_defaults 7.0

  • Build some User
  • Build some Order with buyer User
  • Build some OrderItem with Order and owner User
  • Save OrderItem
# frozen_string_literal: true

require "bundler/inline"

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

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

  gem "rails", "~> 7.0.0"
  gem "sqlite3"
end

require "active_record/railtie"

class Application < Rails::Application
  config.load_defaults 7.0 #------------ WORKS with 6.0 ------------
end

ENV["DATABASE_URL"] = "sqlite3::memory:"
Rails.application.initialize!

ActiveRecord::Schema.define do
  create_table :users, force: true do |t|
  end

  create_table :orders, force: true do |t|
    t.belongs_to :buyer, null: false
  end

  create_table :order_items, force: true do |t|
    t.belongs_to :user, null: false
    t.belongs_to :order, null: false
  end
end

class User < ActiveRecord::Base
  has_many :owned_order_items, class_name: 'OrderItem'
  has_many :buyer_orders, class_name: 'Order', foreign_key: :buyer_id, inverse_of: :buyer
end

class Order < ActiveRecord::Base
  has_many :order_items
  belongs_to :buyer, class_name: 'User', inverse_of: :buyer_orders
end

class OrderItem < ActiveRecord::Base
  belongs_to :order

  belongs_to :owner,
    class_name: 'User',
    foreign_key: :user_id,
    inverse_of: :owned_order_items
end

buyer = User.new
order = Order.new(buyer: buyer)
order_item = OrderItem.new(owner: buyer, order: order)

order_item.save!

Expected behavior

No errors, order_item successfully saved

Actual behavior

Error order_item.order_id in nil

SQLite3::ConstraintException: NOT NULL constraint failed: order_items.order_id (ActiveRecord::NotNullViolation)

System configuration

Rails 7.0.2.3

ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-linux]

aglushkov avatar Mar 29 '22 06:03 aglushkov

Was introduced by https://github.com/rails/rails/pull/34533 PR, like in https://github.com/rails/rails/issues/44780 issue.

fatkodima avatar Mar 29 '22 08:03 fatkodima

I had the same issue. Pretty much the same code, except in my case the parent record is trying to create an associated record with accepts_nested_attributes_for. But looks to be the same root issue.

Also with similar code, an object can no longer be set to an invalid value. For example, record.another_table_id = nil doesn't set record.another_table_id to nil anymore. It instead raises error ActiveRecord::NotNullViolation. This happens when has_inversing is turned on. Rails version 6.1.6.1, ruby 2.7.2. This is also the same issue caused by the same bug. Associations also have the inverse_of flag.

alexadia avatar Jul 29 '22 19:07 alexadia