MassiveRecord and Devise

thhermansen edited this page May 28, 2011 · 2 revisions

We have successfully integrated Devise 1.2.1 with a MassiveRecord user model. There are a few things which we need to do to make MassiveRecord play nicely with Devise. We wrap this up in a gem at some point, but for now - this is what you have to do..

The hardest part is to be able to look user records up by email or other Devise tokens when you by default only can find a record by it's id. But before we solve that, lets begin with:

Gemfile

We obviously need to require Devise in our Gemfile, but we also need to require orm_adapter gem from a github source, since the gem it self does not have MassiveRecord support. So in your Gemfile do:

gem 'orm_adapter', :git => 'git://github.com/CompanyBook/orm_adapter.git'
gem 'devise'

How to tell Devise how it can define attributes in a MassiveRecord class

Devise needs a way of defining it's attributes inside of the MassiveRecord model. Attributes like email, password, tokens etc. To make this possible put this file in your lib/devise/orm/ folder or something. Make sure to require it in Devise's config file config/initializers/devise.rb under the ORM configuration.

Devise.setup do |config|
  # ==> ORM configuration
  # Load and configure the ORM. Supports :active_record (default) and
  # :mongoid (bson_ext recommended) by default. Other ORMs may be
  # available as additional gems.
  require 'devise/orm/massive_record'
end

Index Devise attributes

Indexing user authentication table

Devise finds records via attributes like email, remember- and reset password token. We need to be able to find records based on these attributes, but out of the box we can only find records based on it's id. One thing you can do is to use the email as an id (or maybe a hashed version of the email as the ID), but users tends to change emails, so that might not be a good idea after all. So, in order to look up users by email (and other attributes) we need to do it differently. You can for instance index your record via solr (Sunspot with MassiveRecord support), but back then when we first added Devise support we had not added the solr support yet, so lets do it without it.

Our tactic for indexing user records was to create an index table where keys where for instance user's email or user's remember token. Take a look at this gist for an example and store it in your app/models directory.

Make User model search via user authentication table

Now that we have an user authentication index table lets make the User model use it. Take a look at this gist to give you an example on how to do that.

Uniqueness validation of emails

One last thing before we are done. If you include Devise's validatable module (which I think you should) you will get yourself into trouble because MassiveRecord does not provide you with one. As you might saw from the gist above; I have overridden user's validates_uniqueness_of method to fix this. The uniqueness validator which validates user's email through the UserAuthenticationIndex can be found here. Put it in your /lib or something.

Conclusion

Phew! That was quite a bit. I hope I have remembered everything I did when I made Devise work with MassiveRecord. I think in the future Devise support will be a lot easier, but for now you will have to do this work yourself. Send me a message if you have any questions.