Skip to content

rigor-factorybot

Validates every FactoryBot.create(:name, key: …) / .build(…) / .build_stubbed(…) / .attributes_for(…) / *_list call against an index of your factory definitions: an unknown factory name or an attribute key the factory doesn’t declare is flagged (each with a did-you-mean). When rigor-activerecord is also active, attribute keys are additionally cross-checked against the model’s columns. No FactoryBot runtime dependency.

It ships bundled in rigortype. Activate it under plugins::

plugins:
- rigor-factorybot
# - rigor-activerecord # optional: enables the AR column cross-check
spec/factories/users.rb
FactoryBot.define do
factory :user do
name { "Alice" }
email { "alice@example.com" }
end
end
FactoryBot.create(:user, name: "X") # ✓ info trace
FactoryBot.build(:post, headline: "Hi") # ✗ unknown-attribute (suggest :title)
FactoryBot.create(:usre) # ✗ unknown-factory (suggest :user)
RuleSeverityFires when
plugin.factorybot.factory-callinfothe call resolved to a known factory; lists its declared attributes
plugin.factorybot.unknown-factoryerrorthe literal :name isn’t in the factory index (with a did-you-mean)
plugin.factorybot.unknown-attributeerrora keyword key isn’t a declared attribute (with a did-you-mean); also checked against the model’s columns when :model_index is available

The legacy FactoryGirl constant is recognised the same way. Recognised entry methods: create / build / build_stubbed / attributes_for and the *_list variants. Inside a factory it recognises name { … } (modern), name "…" (legacy positional), and add_attribute(:name) { … }.

plugins:
- gem: rigor-factorybot
config:
factory_search_paths: ["spec/factories", "spec/factories.rb"] # default
# Minitest projects: ["test/factories"]
  • Literal arguments onlyFactoryBot.create(name) with a variable name passes through.
  • Traits / sequences / associations not collected yet — an attribute defined only inside trait :admin do … end can surface a false unknown-attribute until the trait slice ships.
  • Explicit receiver only — bare create(:user) (from include FactoryBot::Syntax::Methods) is not recognised in this slice; it needs receiver-type inference, which would otherwise false-positive on every unrelated create call.

The factory discoverer / index, the cached producer, the :model_index consumption, the demo, and the contract surfaces this plugin exercises are in the plugin’s README. To write a plugin, see examples/ and the rigor-plugin-author skill.

© 2026 TypedDuck. Licensed under CC BY-SA 4.0.