Scratching An Itch: The Rails Model Generator With Factory Girl Support
Mark Cornick, Former Viget
Many development projects start as scratches for a developer’s itch. We do something enough times to decide that not only must there be a better way, but that we’re going to find it.
At Viget, we’ve mostly sworn off fixtures for our test suites. Instead, several of our recent projects have used Thoughtbot’s Factory Girl as a fixture replacement, for which it works very well. However, the Rails generators are not aware of its presence—they still generate fixtures, which we don’t use, and end up deleting. As Clinton has said, you should be automating anything you do repeatedly, and the Rails generators help meet that goal. So, it would be nice if the Rails model generator would stop creating these unused fixtures, and maybe create factories instead.
A new version of Factory Girl dropped at the end of November. Near the top of its change log is this encouraging snippet:
Factory definitions are now detected in subdirectories, such as factories/person_factory.rb (thanks to Josh Nichols)
It might not seem like much, but when I read this, a thought entered my mind. Instead of creating one fixture file per model in the generator, what about creating one factory file? After discussing it with other Viget developers on Campfire, the itch was ready to be scratched—we were going to have a model generator that creates factories instead of fixtures.
Less than a day later, the first version was done. It’s literally the same model generator that ships with Rails 2.2.2, but with all the fixture references changed to factories. Not a monumental display of skill, perhaps, and the point about how open source makes all this possible is obvious and oft-repeated. But, still, an itch scratched, and one less thing that’s not fully automated.
Do you have some itch that bugs you in development? Think about taking an hour or two and scratching it with some code. If it saves you effort and makes your development process easier, it’ll be time well spent.