Factory Girl Patch for Continued DataMapper Compatibility
Friday
Sep 25, 2009
5:56 pm
The Factory Girl gem from thoughtbot is the way to go if you have to test ORM classes. It has been featured in Ryan Bates Railscast, and by good fortune, it also works with DataMapper, my ORM of choice. When I upgraded to the latest release of DataMapper however, all my user tests broke. in particular the crypted_password and salt fields were not being set when the record was saved. I'm using the salted password mixin from Merb and I assumed that it was to blame having not gotten up to speed with some of the new API changes in DataMapper. It turned out instead to be an incompatibility between Factory Girl and Datamapper that had existed for a long time but was now showing up. I've modified factory girl to maintain compatibility and my changes are at http://github.com/startrader/factory_girl.
More About the Solution
The problem arises because DataMapper does not follow ActiveRecord's convention of using a bang (!) at the end of a method to have it raise an error if it could not complete. In DataMapper the bang instead completes the action without calling before and after hooks. It is a way to skip any validation that isn't data store enforced.
When Factory Girl used #save! expecting it to raise a validation exception if things went wrong, it instead skipped the before filter in the salted user mixin that encrypts the password. My factory created users were being saved with nil password fields and all my tests where now complaining that they could not log in.
My fix was to force Factory Girl to use the #save method that is common to both ORMs and raise its own error if saving the record fails.
Further Thoughts
Factory Girl's test suite makes it fairly clear that it only targets ActiveRecord. I'm optimistic that when Rails 3 comes out it will instead target ActiveORM which will have a DataMapper compatibility layer.
I've been using DataMapper for all my projects for the last year or so, and I'm really starting to see why it has not reached the magic 1.0 mark. On the other hand it is, in my humble opinion, so much easier to be creative with. It is worth dealing with a smaller community and a few yet-to-be-implemented features, at least for me. With the 0.10.0 release, the code has been made much more readable. It is now very possible to dig into the code and ge things working. (More on this in a future post when I actually have something working) I believe that DataMapper will benefit hugely from Rails 3 being ORM agnostic. I'm hopeful that this will also help build up the DataMapper community.
As an aside, I will be giving a talk on DataMapper at the Sacramento Ruby Meetup on October 15th if your reading this and in the area it would be fun to have a large audience.