Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixtures cannot be loaded #68

Closed
gjtorikian opened this issue Jan 3, 2024 · 11 comments · May be fixed by #70
Closed

Fixtures cannot be loaded #68

gjtorikian opened this issue Jan 3, 2024 · 11 comments · May be fixed by #70

Comments

@gjtorikian
Copy link

This is a fork of this earlier comment I made.

I finally found some time to set up a reproducible test case: https://github.com/gjtorikian/ulid-fixtures-bug

Run bin/rails db:create && bin/rails db:migrate && bin/rails test to see the issue:

E

Error:
ProductTest#test_it_can_find_a_product:
ActiveRecord::RecordNotFound: Couldn't find Product with [WHERE "products"."id" = $1]
    test/models/products_test.rb:9:in `block in <class:ProductTest>'

It seems that, for fixtures which are backed by ULID, the Rails test runner cannot find them.

In ulid-rails < 2.0, I was able to work around this with:

module ULID
  module Generator
    extend T::Sig
    # encode is a private method, so we monkey patch in
    # a new method that calls the private method
    def encode_wo_random(input)
      encode(input, ULID::Generator::ENCODED_LENGTH)
    end
  end
end

module FixtureSetExtensions
  extend T::Sig

  def identify(label, column_type = :integer)
    # Need to override default ID generation for fixtures,
    # because it wholly assumes that the fixture IDs are integers
    if column_type == :binary && !ULID::Rails::Validator.is_valid?(label)
      input = super # use default ID generation
      value = ULID.encode_wo_random(input)
      ULID::Rails::Type.new.serialize(value)
    else
      super
    end
  end
end

module FixtureExtensions
  def find
    primary_key_type = model_class.columns.find { |c| c.name == model_class.primary_key }.type
    super unless primary_key_type == :binary

    deserialized_primary_key = ULID::Rails::Type.new.deserialize(fixture[model_class.primary_key])
    # all of the lines below are from the original `find` method
    object = model_class.unscoped do
      model_class.find(deserialized_primary_key)
    end
    object.instance_variable_set(:@strict_loading, false)
    object
  end
end

module ActiveRecord
  class FixtureSet
    class << self
      prepend FixtureSetExtensions
    end
  end

  class Fixture
    prepend FixtureExtensions
  end
end

To begin with, I think this is a Rails problem, but I am not entirely sure. Rails converts a fixture's YAML key name (product_one) into an integer (here). That integer does not exist in the DB, because we're using ULIDs. And, from what I remember, the ULID ID autogeneration inserts some randomness; so I rewrote the methods to allow for Rails to look up fixtures by their keyname turned into a ULID.

If this is a Rails problem, their identify code should probably support bytea, just as they already support uuid. But I am not sure they will accept that solution, and so I think this lib should have a solution by default. What I cannot figure out is why no one else seems to have encountered this issue, and what I've done to trigger it.

@gjtorikian
Copy link
Author

👋 @bquorning just seeing if there's any more info I can provide here.

bquorning added a commit that referenced this issue Mar 8, 2024
bquorning added a commit that referenced this issue Mar 9, 2024
bquorning added a commit that referenced this issue Mar 9, 2024
@bquorning
Copy link
Collaborator

Thank you for the bug report and the repository with reproduction code @gjtorikian. That made the bug very easy to replicate for me 🙏🏼

Rails’ fixtures seem to depend on the column type and ignores the sql_type.

(ruby) ActiveRecord::FixtureSet::ModelMetadata.new(Product).primary_key_type
:binary
(ruby) Product.connection.schema_cache.columns(:products)[0].type
:binary
(ruby) Product.connection.schema_cache.columns(:products)[0].sql_type
"bytea"

The code you linked to is switching on this type and adding a special case if its value is :uuid. Since the value in our case is :binary, an integer is created.

The only solution I could find was to change the type returned by ULID::Rails::Type, from :binary to :ulid (I am not 100% sure that this won’t have bad consequences), and then patch the ActiveRecord::FixtureSet.identify method to add special handling for the :ulid type.

Could you please check if #70 fixes the issue?

bquorning added a commit that referenced this issue Mar 9, 2024
bquorning added a commit that referenced this issue Mar 9, 2024
@gjtorikian
Copy link
Author

Sadly, it. did not. 😦 Here's the stack trace from that branch:

NoMethodError: undefined method `encoding' for nil
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activemodel-7.1.3.2/lib/active_model/type/binary.rb:43:in `initialize'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activemodel-7.1.3.2/lib/active_model/type/binary.rb:32:in `new'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activemodel-7.1.3.2/lib/active_model/type/binary.rb:32:in `serialize'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:555:in `block (2 levels) in build_fixture_sql'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:552:in `each'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:552:in `map'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:552:in `block in build_fixture_sql'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:544:in `map'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:544:in `build_fixture_sql'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:586:in `block in build_fixture_statements'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:584:in `each'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:584:in `filter_map'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:584:in `build_fixture_statements'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:455:in `insert_fixtures_set'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/fixtures.rb:681:in `block in insert'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/fixtures.rb:672:in `each'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/fixtures.rb:672:in `insert'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/fixtures.rb:658:in `read_and_insert'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/fixtures.rb:603:in `create_fixtures'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/test_fixtures.rb:255:in `load_fixtures'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/test_fixtures.rb:142:in `setup_fixtures'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/isolator-1.0.1/lib/isolator/railtie.rb:7:in `setup_fixtures'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/test_fixtures.rb:10:in `before_setup'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activesupport-7.1.3.2/lib/active_support/testing/setup_and_teardown.rb:40:in `before_setup'

Error:
ConversationPolicyTest#test_for_a_reader_without_corresponding_message_permisions:
NoMethodError: undefined method `pop' for nil
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/mocha-2.1.0/lib/mocha/mockery.rb:54:in `ensure in teardown'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/mocha-2.1.0/lib/mocha/mockery.rb:54:in `teardown'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/mocha-2.1.0/lib/mocha/hooks.rb:39:in `mocha_teardown'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/mocha-2.1.0/lib/mocha/integration/mini_test/adapter.rb:47:in `after_teardown'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activesupport-7.1.3.2/lib/active_support/testing/time_helpers.rb:71:in `after_teardown'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/actioncable-7.1.3.2/lib/action_cable/test_helper.rb:17:in `after_teardown'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/test_fixtures.rb:15:in `after_teardown'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activesupport-7.1.3.2/lib/active_support/testing/setup_and_teardown.rb:51:in `after_teardown'

bin/rails test test/policies/conversation_policy_test.rb:90

Let me know how else I can help! I tried the branch out in the test case repo I created earlier, and it didn't work there either.

@bquorning
Copy link
Collaborator

Thanks for giving it a try.

Let me know how else I can help! I tried the branch out in the test case repo I created earlier, and it didn't work there either.

That is strange. When I use gem "ulid-rails", git: "https://github.com/k2nr/ulid-rails.git", branch: "patch-fixtures" with your test case repo, the test is passing.

Could you try again, and perhaps push up your changes to ulid-fixtures-bug if it’s still failing?

@gjtorikian
Copy link
Author

Sure! I pushed my commit up; I'm also running the test using bin/rails test (curious if you ran some other command that worked?).

@bquorning
Copy link
Collaborator

I run bin/rails db:create && bin/rails db:migrate && bin/rails test – and the test passes on my machine. 😕

Can you share which error you get, plus stacktrace?

@gjtorikian
Copy link
Author

Sure, here it is:

bin/rails db:create && bin/rails db:migrate && bin/rails test
Database 'test_development' already exists
Database 'test_test' already exists
/rails dbRunning 1 tests in a single process (parallelization threshold is 50)
Run options: --seed 29343

# Running:

E

Error:
ProductTest#test_it_can_find_a_product:
ActiveRecord::NotNullViolation: PG::NotNullViolation: ERROR:  null value in column "id" of relation "products" violates not-null constraint
DETAIL:  Failing row contains (null, Name, Description, 1984-01-01 00:00:00, 1994-01-01 00:00:00).

    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/postgresql/database_statements.rb:55:in `exec'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/postgresql/database_statements.rb:55:in `block (2 levels) in raw_execute'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract_adapter.rb:1028:in `block in with_raw_connection'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activesupport-7.1.3.2/lib/active_support/concurrency/null_lock.rb:9:in `synchronize'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract_adapter.rb:1000:in `with_raw_connection'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/postgresql/database_statements.rb:54:in `block in raw_execute'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activesupport-7.1.3.2/lib/active_support/notifications/instrumenter.rb:58:in `instrument'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract_adapter.rb:1143:in `log'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/postgresql/database_statements.rb:53:in `raw_execute'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:521:in `internal_execute'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:131:in `execute'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/query_cache.rb:25:in `execute'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/postgresql/database_statements.rb:47:in `execute'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/postgresql/database_statements.rb:151:in `execute_batch'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:462:in `block (3 levels) in insert_fixtures_set'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/transaction.rb:535:in `block in within_new_transaction'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activesupport-7.1.3.2/lib/active_support/concurrency/null_lock.rb:9:in `synchronize'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/transaction.rb:532:in `within_new_transaction'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:344:in `transaction'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:461:in `block (2 levels) in insert_fixtures_set'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/postgresql/referential_integrity.rb:19:in `disable_referential_integrity'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:460:in `block in insert_fixtures_set'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:601:in `with_multi_statements'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:459:in `insert_fixtures_set'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/fixtures.rb:681:in `block in insert'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/fixtures.rb:672:in `each'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/fixtures.rb:672:in `insert'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/fixtures.rb:658:in `read_and_insert'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/fixtures.rb:603:in `create_fixtures'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/test_fixtures.rb:255:in `load_fixtures'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/test_fixtures.rb:142:in `setup_fixtures'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/test_fixtures.rb:10:in `before_setup'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activesupport-7.1.3.2/lib/active_support/testing/setup_and_teardown.rb:40:in `before_setup'


bin/rails test test/models/products_test.rb:8



Finished in 0.027135s, 36.8528 runs/s, 0.0000 assertions/s.
1 runs, 0 assertions, 0 failures, 1 errors, 0 skips

~/Developer/ulid-fixtures-bug main ⇡
❯ bin/rails db:reset
Dropped database 'test_development'
Dropped database 'test_test'
Created database 'test_development'
Created database 'test_test'

~/Developer/ulid-fixtures-bug main ⇡
❯ bin/rails db:migrate && bin/rails test
Running 1 tests in a single process (parallelization threshold is 50)
Run options: --seed 12539

# Running:

E

Error:
ProductTest#test_it_can_find_a_product:
ActiveRecord::NotNullViolation: PG::NotNullViolation: ERROR:  null value in column "id" of relation "products" violates not-null constraint
DETAIL:  Failing row contains (null, Name, Description, 1984-01-01 00:00:00, 1994-01-01 00:00:00).

    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/postgresql/database_statements.rb:55:in `exec'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/postgresql/database_statements.rb:55:in `block (2 levels) in raw_execute'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract_adapter.rb:1028:in `block in with_raw_connection'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activesupport-7.1.3.2/lib/active_support/concurrency/null_lock.rb:9:in `synchronize'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract_adapter.rb:1000:in `with_raw_connection'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/postgresql/database_statements.rb:54:in `block in raw_execute'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activesupport-7.1.3.2/lib/active_support/notifications/instrumenter.rb:58:in `instrument'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract_adapter.rb:1143:in `log'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/postgresql/database_statements.rb:53:in `raw_execute'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:521:in `internal_execute'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:131:in `execute'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/query_cache.rb:25:in `execute'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/postgresql/database_statements.rb:47:in `execute'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/postgresql/database_statements.rb:151:in `execute_batch'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:462:in `block (3 levels) in insert_fixtures_set'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/transaction.rb:535:in `block in within_new_transaction'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activesupport-7.1.3.2/lib/active_support/concurrency/null_lock.rb:9:in `synchronize'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/transaction.rb:532:in `within_new_transaction'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:344:in `transaction'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:461:in `block (2 levels) in insert_fixtures_set'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/postgresql/referential_integrity.rb:19:in `disable_referential_integrity'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:460:in `block in insert_fixtures_set'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:601:in `with_multi_statements'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:459:in `insert_fixtures_set'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/fixtures.rb:681:in `block in insert'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/fixtures.rb:672:in `each'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/fixtures.rb:672:in `insert'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/fixtures.rb:658:in `read_and_insert'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/fixtures.rb:603:in `create_fixtures'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/test_fixtures.rb:255:in `load_fixtures'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/test_fixtures.rb:142:in `setup_fixtures'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-7.1.3.2/lib/active_record/test_fixtures.rb:10:in `before_setup'
    /Users/gjtorikian/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activesupport-7.1.3.2/lib/active_support/testing/setup_and_teardown.rb:40:in `before_setup'


bin/rails test test/models/products_test.rb:8

FWIW I will also try this branch in my actual (real) app and see if I can pinpoint what isn't working. Thank you for your help with all of this!

@gjtorikian
Copy link
Author

I set up GitHub Actions on that test repo, and the tests failed in the same way I posted above: https://github.com/gjtorikian/ulid-fixtures-bug/actions/runs/8225587319/job/22490802305

I'm not sure why this would work on your machine, but at least I confirmed it's not mine! 😅

@bquorning
Copy link
Collaborator

Ok, this is weird. I got the error once locally, but then I never saw it again. I will try to dig deeper into this over the coming days.

@bquorning
Copy link
Collaborator

I think I found it! I am not sure how, but it seems the directive id: :binary did not make its way from db/migrate/20240103172229_create_products.rb into db/schema.rb. If I change that first line, the test is passing.

diff --git a/db/schema.rb b/db/schema.rb
index ba62d9b..f090cca 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -14,7 +14,7 @@ ActiveRecord::Schema[7.1].define(version: 2024_01_03_172229) do
   # These are extensions that must be enabled in order to support this database
   enable_extension "plpgsql"
 
-  create_table "products", force: :cascade do |t|
+  create_table "products", id: :binary, force: :cascade do |t|
     t.string "name"
     t.text "description"
     t.datetime "created_at", null: false

@gjtorikian
Copy link
Author

Good news, your suggested change fixed my sample bug! But, I still can't seem to get that branch to work for my project. There must be something I am setting up incorrectly. I am reluctant to do so, but I'll close this issue out since I think the problem is on my end. Will report back if I find out what is going on.

bquorning added a commit that referenced this issue Aug 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants