migrating-from-factory-bot
Migrating from factory_bot
ORM::Factory is a Raku port of Ruby's
factory_bot. Most concepts
carry over one-for-one; this page lists the cases where the spelling
changed.
Module and DSL entry point
| factory_bot | ORM::Factory |
|---|---|
FactoryBot.define { ... } | define { ... } |
FactoryBot.modify { ... } | ORM::Factory.modify: { ... } |
FactoryBot.lint | ORM::Factory.lint |
factory :user do ... end | .factory: 'user', { ... } |
Names are Raku strings, not Ruby symbols: build(:user) becomes
build('user').
Method-name conventions
Ruby snake_case becomes Raku kebab-case:
| factory_bot | ORM::Factory |
|---|---|
build_stubbed | build-stubbed |
attributes_for | attributes-for |
to_create | to-create |
initialize_with | initialize-with |
skip_create | skip-create |
rewind_sequences | rewind-sequences |
register_strategy | register-strategy |
Ruby ! becomes -or-die; Ruby ? becomes is-:
| factory_bot | ORM::Factory |
|---|---|
save! | save-bang |
persisted? | is-persisted |
new_record? | is-new-record |
valid? | is-valid |
Traits / variants
factory_bot's trait is renamed variant throughout, partly to free up
the word "trait" (which means something specific in Raku) and partly because
"variant" reads more clearly:
| factory_bot | ORM::Factory |
|---|---|
trait :admin do ... end | .variant: 'admin', { ... } |
traits_for_enum :status | .variants-for-enum: 'status', @values |
automatically_define_enum_traits | automatically-define-enum-variants (on by default; derives variants from an ORM::ActiveRecord enum) |
Blocks
Ruby blocks with block-locals become Raku pointy blocks:
sequence(:email) { |n| "user#{n}@example.com" }.sequence: 'email', -> $n { "user{$n}\@example.com" };Class lookup
factory_bot infers the model class from the factory name and an class:
option lets you override it. ORM::Factory does the same, but the toggle is
explicit:
.factory: 'admin', :class(User), { ... };
ORM::Factory.set-allow-class-lookup(False); # turn off auto-resolutionPersistence
factory_bot is tightly coupled to ActiveRecord. ORM::Factory defers to
the persistence adapter protocol; ActiveRecord is one
implementation (auto-detected when loaded). With no ORM installed, the
generic adapter handles plain Raku classes.
X::RecordInvalid (raised from create) is the AR exception, the
same as factory_bot's ActiveRecord::RecordInvalid.
What is intentionally missing
Data generation ā
factory_botdoes not ship a Faker either. Use a Raku faker / data-generator next to it (see the cookbook).Linting strategies beyond
buildandcreateāfactory_botlintscreateby default;ORM::Factorydoes the same and accepts:strategy<build>for the same reason.reloadof definitions on file change āORM::Factory.reloadclears the registry, but there is no file-watcher; you re-runfind-definitionsyourself.
A side-by-side example
# factory_bot
FactoryBot.define do
sequence(:email) { |n| "user#{n}@example.com" }
factory :user do
fname { "Greg" }
email { generate(:email) }
trait :admin do
role { "admin" }
end
end
factory :post do
title { "Hello" }
author factory: :user, role: "admin"
end
end
FactoryBot.create(:user, :admin)
FactoryBot.build_stubbed(:post)# ORM::Factory
define {
.sequence: 'email', -> $n { "user{$n}\@example.com" };
.factory: 'user', {
.fname: 'Greg';
.email: { ORM::Factory.generate('email') };
.variant: 'admin', {
.role: 'admin';
};
};
.factory: 'post', {
.title: 'Hello';
.association: 'author', :factory<user>, 'admin';
};
};
ORM::Factory.create('user', 'admin');
ORM::Factory.build-stubbed('post');