0

I'm upgrading a project to Rails 4.0.13 (from 3.2). The project has existing models Entity and Contact. I have simplified the models and database structure to eliminate any unrelated information.

Gemfile:

source 'http://rubygems.org'
gem 'rails', '4.0.13'
gem 'mysql2', '~> 0.3.x'
gem 'composite_primary_keys'

Migrations:

class CreateEntities < ActiveRecord::Migration
  def change
    create_table :entities do |t|
      t.string :name
      t.integer :lock_version
      t.timestamps
    end
  end
end

class CreateContacts < ActiveRecord::Migration
  def change
    create_table :contacts do |t|
      t.integer :entity_id
      t.integer :contact_type_id
      t.string  :name
      t.integer :lock_version
      t.timestamps
    end
  end
end

Models:

class Entity < ActiveRecord::Base
  has_one :contact, -> { where contact_type_id: 1 }
  accepts_nested_attributes_for :contact
end

class Contact < ActiveRecord::Base
  belongs_to :entity
  belongs_to :entity_contact_type
end

entities_test.rb:

require 'test_helper'
class EntityTest < ActiveSupport::TestCase
  def test_auto_create_new_contact
    entity = entities(:one)
    entity.contact_attributes = { :name => 'new name' }
    assert_difference 'Contact.count' do
      entity.save
      assert_equal 'new name', entity.contact.name
      assert !entity.contact.new_record?
    end
  end
end

When I run entities_test, I get the following error:

1) Error: EntityTest#test_auto_create_new_contact:

ActiveRecord::StaleObjectError: Attempted to update a stale object: Entity

test/unit/entity_test.rb:9:in `block in test_auto_create_new_contact' test/unit/entity_test.rb:8:in `test_auto_create_new_contact'

I created a new simplified project to isolate the issue for demonstration purposes, and I've narrowed it down to the 'composite_primary_keys' gem. If I remove that line from the Gemfile, I don't get the error. However, in practice removing that Gem is not an option; there are other parts of the project that depend on it.

Fred Willmore
  • 4,386
  • 1
  • 27
  • 36

1 Answers1

1

I have found an answer: in my migration I failed to specify that lock_version should have a default value of 0, and not allow null values:

t.integer :lock_version, null: false, default: 0
Fred Willmore
  • 4,386
  • 1
  • 27
  • 36