Devise: multiple models vs. polymorphic associations

In the app, both the Contact model and the Company model need to be able to log in. The things they can see and do are completely separate (but who knows how the app will evolve later on). So far I’ve only implemented the logging in functionality for the Contact model, not the Company model.

Just yesterday, I learned what a polymorphic association is. Now, I wonder if I should scrap my original plan to have two models that can log in separately, and instead have just one User model, with a polymorphic association to the Contact and Company models.

On the one hand, the Devise GitHub page only talks about multiple model logins. On the other hand, most posters on StackExchange seem to be using polymorphic associations instead of multiple models.

I am leaning towards using polymorphic associations, because I already have role-based authorization implemented with CanCan for contacts. I could just add another role for “company-type” users. I can imagine this approach is more scalable. Right now having two separate Models that can log in doesn’t seem so bad, but if later on more and more Models start needing to log in, I would much rather just one row to a “roles” table, rather than having to implement login functionality separately for each of those Models.

2 Comments

  1. How did this work out for you? I’m contemplating the same decision, and leaning the same way as you did, but I’ve heard other suggest it tends to get messy later on and needs to be refactored away. Hoping you’ve had success though because this seems like a clean and intuitive solution.

  2. In the end the login logic for the two models turned out to be so different that I used Devise for one and hand-rolled auth for the other, in two separate models. So the question turned out not to really apply to me.

    Since I wrote this, I learned that there are two additional ways that might work and be cleaner:

    1. Put login functionality in a concern to be mixed into whatever models need it (each model needs its own database columns). I have never tried this, but it seems in principle it should work. http://signalvnoise.com/posts/3372-put-chubby-models-on-a-diet-with-concerns

    2. Do it polymorphically, but in a way that allows you to maintain database foreign key constraints, i.e., data-integrity. All models would share the same database table for auth. Again, have not actually tried this myself. http://enterpriserails.chak.org/full-text/chapter-10-multiple-table-inheritance

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s