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

Associations with Rails Engine lead to ActiveRecord::RecordInvalid #1584

Open
Th-Os opened this issue Jun 27, 2023 · 0 comments
Open

Associations with Rails Engine lead to ActiveRecord::RecordInvalid #1584

Th-Os opened this issue Jun 27, 2023 · 0 comments
Labels

Comments

@Th-Os
Copy link

Th-Os commented Jun 27, 2023

Description

I use simple 1:n associations with models residing in a Rails Engine. The main app includes this engine directly under /engines.
However, the validation fails for belongs_to associations when I use implicit or explicit associations. I even tried out before(:create) and after(:build) hooks. Only initialize_with works, which is kind of limiting.
My test just executes FactoryBot.build(:thing) (see factories_test.rb). FactoryBot.lint results in the same error.

Error:
ActiveRecord::RecordInvalid: Validation failed: [MODEL] must exist

My overall setup is a bit more complex. However, this should not influence this bug, as these models / factories use the same database and are integrated into the same Engine. All other parts of this application work - including model tests with manually constructing the models. But FactoryBot seems to ignore my association and just uses nil for it.

Any suggestions? Is there some restriction, when using models from Rails Engines?

Reproduction Steps

I could not reproduce this bug with your reproduction script - as it seems to be connected to the Engine.

engines/some-engine/test/factories/thing_factory.rb in Rails Engine

FactoryBot.define do
  factory :thing, class: "Thing" do
    # simple association does not work.
    association :container, factory: :container

    # before(:create) and after(:build) don't work.
    after(:build) do | model |
      container = create(:container)
    end

    # this does not work, too.
    container { FactoryBot.create(:container) } 

    # only initialize_with works.
    initialize_with do
      container = create(:container)
      new(attributes.merge(container: container))
    end
  end
end

engines/some-engine/test/factories/container_factory.rb in Rails Engine

FactoryBot.define do
  factory :container, class: "Container" do
   ...
  end
end

engines/some-engine/app/models/thing.rb in Rails Engine

# table with container_id

class Thing < ApplicationRecord
  belongs_to :container
end

engines/some-engine/app/models/container.rb in Rails Engine

class Container < ApplicationRecord
  has_many :things
end

test/factories_test.rb in main app

FactoryBot.factories.each do |factory|
  method_name = "test_#{factory.name}"
  define_method(method_name) do
    instance = FactoryBot.build(factory.name)
    assert instance.valid?, "invalid factory: #{factory.name}, error messages: #{instance.errors.messages.inspect}"
  end
end

Resulting Error:
ActiveRecord::RecordInvalid: Validation failed: Container must exist

Expected behavior

FactoryBot.build(:thing) should work with associations.

Actual behavior

Error when executing FactoryBot.lint:
ActiveRecord::RecordInvalid: Validation failed: Container must exist

System configuration

factory_bot version: 6.2.0 (factory_bot_rails)
rails version: 7.0.4.2
ruby version: 3.2.2
Test Framework: Minitest

@Th-Os Th-Os added the bug label Jun 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant