When I run rails g model Car in a Rails Engine (which is configured to be namespaced inside a module), the Rails model correctly namespaces, but the FactoryBot factory does not.
Reproduction Steps
Run the following from the Engine root:
bundle exec rails g model Car name:string
Expected behavior
Ideally, inside the Engine I would expect not to have to manually edit the generated files to get them to work, or to use a workaround with the confusing --skip-namespace alongside an explicit namespace string. Not running the --skip-namespace flag has the added benefit of keeping the nested module namespace rather than the implicit ::Namespace syntax in the model as generated by the base Rails generators.
Actual behavior
The resulting files are not namespaced correctly, and they won't work without manual intervention in the generated files:
# app/models/discord_bot/car.rb
module DiscordBot
class Car < ApplicationRecord
end
end
# spec/factories/discord_bot/cars_factory.rb
FactoryBot.define do
factory :car do
name { "MyString" }
end
end
# spec/models/discord_bot/car_spec.rb
require 'rails_helper'
module DiscordBot
RSpec.describe Car, type: :model do
it "works" do
car = build(:car)
expect(car).to be_present
end
end
end
and when I run rspec, I get the following error:
Failures:
1) DiscordBot::Car works
Failure/Error: car = build(:car)
NameError:
uninitialized constant Car
# ./spec/models/discord_bot/car_spec.rb:6:in `block (2 levels) in <module:DiscordBot>'
I can fix this by manually editing the factory like so:
FactoryBot.define do
factory :car, class: "DiscordBot::Car" do
name { "MyString" }
end
end
In order to get this to work in an Engine, I had to pass --skip-namespace with the generator, but namespace the model itself, as below:
bundle exec rails g model DiscordBot::Car name:string --skip-namespace
which results in the following:
# app/models/discord_bot/car.rb
class DiscordBot::Car < ApplicationRecord
end
# spec/factories/discord_bot/cars.rb
FactoryBot.define do
factory :discord_bot_car, class: 'DiscordBot::Car' do
name { "MyString" }
end
end
# spec/models/discord_bot/car_spec.rb
require 'rails_helper'
RSpec.describe DiscordBot::Car, type: :model do
# basic spec to test
it "works" do
car = build(:discord_bot_car)
expect(car).to be_present
end
end
And then it works without any manual changes (other than writing the tests).
Description
When I run
rails g model Car
in a Rails Engine (which is configured to be namespaced inside a module), the Rails model correctly namespaces, but the FactoryBot factory does not.Reproduction Steps
Run the following from the Engine root:
Expected behavior
Ideally, inside the Engine I would expect not to have to manually edit the generated files to get them to work, or to use a workaround with the confusing
--skip-namespace
alongside an explicit namespace string. Not running the--skip-namespace
flag has the added benefit of keeping the nested module namespace rather than the implicit::Namespace
syntax in the model as generated by the base Rails generators.Actual behavior
The resulting files are not namespaced correctly, and they won't work without manual intervention in the generated files:
and when I run rspec, I get the following error:
I can fix this by manually editing the factory like so:
In order to get this to work in an Engine, I had to pass
--skip-namespace
with the generator, but namespace the model itself, as below:which results in the following:
And then it works without any manual changes (other than writing the tests).
System configuration
factory_bot_rails version: 6.4.3 factory_bot version: 6.4.6 rails version: 7.1.3.3 ruby version: 3.2.3