Building The Conversation

Upgrading DataMapper from 1.0 to 1.1

I just upgraded DataMapper from 1.0 to 1.1 in our app.

DataMapper 1.1 brings several minor API changes, warranting the minor version bump, and closes 52 tickets in Lighthouse. There have been many performance improvements, some closing bottlenecks that result in as much as a 20x speedup from the 1.0.2 behaviour.

It took me about three hours, and most of that was waiting for bundle update and builds to run. We were running our own forks of a few of the 1.0 gems as well to get some much needed bug fixes, so that added a bit of time also. Here are the major changes I needed to make.

Get real internet

My wireless kept dropping out doing a big bundle update. Got fed up and found an ethernet cable and then it all worked. Far quicker. There is a larger lesson in here somewhere.

DataMapper no longer uses ActiveSupport::Inflector

DataMapper uses it’s own Inflector class, thankfully it appears to be mostly API compatible with ActiveSupport. Our config/initializers/inflections.rb file now looks like this:

    [
      ActiveSupport::Inflector,
      DataMapper::Inflector
    ].each do |klass|
      klass.inflections do |inflect|
        inflect.uncountable %w( research content published )
      end
    end


DataMapper no longer monkey-patches core classes

Previously DataMapper monkey-patched many core classes to add convenience methods such as String#compress_lines and Hash#only. This caused no end of conflicts with ActiveSupport and others, so with 1.1 these extensions were moved into explicit classes.

    "Hello\nthere".compress_lines                          # old
    DataMapper::Ext::String.compress_lines("Hello\nthere") # new


We had a few only calls in our app, which can be replaced with slice (provided by ActiveSupport). I also had to patch dm-paperclip and database_cleaner, since they were depending on the old extensions.

Always use ZonedTime

We had a few (incorrect) uses of Property::DateTime in our models. This is provided by DataMapper out of the box, but does not work with Rails timezones. Instead, you should use ZonedTime, provided by dm-zone-types. Don’t forget to write a data migration to get your dates into UTC time in the database!

Use a newer version of dm-do-adapter

The 1.1.0 gem release of dm-do-adapter contains a deprecated call to DataObjects::URI.new. This isn’t broken, it’s just noisy. It will be fixed in the soon to be released 1.1.1, but to silence it now, pick up a newer version from git. Add this to your Gemfile:

    # We can technically use the 1.1 gem, but it throws up deprecation warnings.
    # This ref is the commit the warnings were silenced, but is before the DM
    # dependencies were bumped to 1.1.1 (which hasn't been released yet)
    gem 'dm-do-adapter',
      git: 'git://github.com/datamapper/dm-do-adapter',
      ref: '7f0b53d1ada8735910e0'


Update forks

Not all of the patches and bug fixes we rely on made it into 1.1, so I rebased our forks against the 1.1 tag.

    $ cd dm-core-tc
    $ git add remote dm git://github.com/datamapper/dm-core.git
    $ git fetch
    $ git checkout -b tc-1.1
    $ git rebase v1.1.0
    $ git push origin tc-1.1


There were a few duplicates and faux-conflicts, so I made liberal use of the --skip option to rebase. In our Gemfile, we reference the fork like so:

    gem 'dm-core', 
      git:    'git://github.com/conversation/dm-core',
      branch: 'tc-1.1'


That’s basically it. It wasn’t a huge deal. You should do it too.

Facts matter. Your tax-deductible donation helps deliver fact-based journalism.