0

I've built a Rails 4.2.5 / Devise 3.5.2 app with a single user model called Employer. I currently have multiple social integrations using the Devise omniauthable module. I now want to extend these social integrations to a second user model called Contact, however I'm unable to do this using the standard procedure because Devise's omniauthable module doesn't play nice with more than one user model.

Here are my two user models:

class Employer < ActiveRecord::Base
    devise :database_authenticatable, :registerable,
    :recoverable, :rememberable, :trackable, :validatable,
    :omniauthable, :confirmable
end

class Contact < ActiveRecord::Base
    devise :database_authenticatable, :registerable,
    :recoverable, :rememberable, :trackable, :validatable,
    :omniauthable, :confirmable
end

I read the wiki article on how to configure Omniauth for multiple models. I followed the instructions precisely, but I still could not get it to work because the information on routing is extremely vague. Specifically, I couldn't what the right routes are when building them manually. Note that in my user models above I removed the omnuauthable module when attempting the workaround in the wiki article.

I was able to build the following routes based off what I read int he wiki article:

match "/user/:key/auth/:provider", to: "omniauth_callbacks#passthru", constraints: { action: /twitter|facebook|linkedin/ }, via: [:get, :post]
match "/user/:key/auth/:action/callback", to: "omniauth_callbacks#twitter", constraints: { action: /twitter|facebook|linkedin/ }, via: [:get, :post]
match "/user/:key/auth/:action/callback", to: "omniauth_callbacks#facebook", constraints: { action: /twitter|facebook|linkedin/ }, via: [:get, :post]
match "/user/:key/auth/:action/callback", to: "omniauth_callbacks#linkedin", constraints: { action: /twitter|facebook|linkedin/ }, via: [:get, :post]

The problem is that I don't know how to build my omniauth authorize paths. When a user is on my page and clicks the authenticate button, what controller action do I send them to and how do I manually build that functionality that Devise offers out of the box?

So my question is as follows:

  1. Is there an easier out-of-the-box solution to using Devise's omniauthable module with more than one user model. Specifically I'm looking for a solution that does not rely on STI, which is not practical for me to implement at this point.
  2. If there is no out of the box solution, how can I implement the approach from the wiki article? The article is clearly lacking some essential information that I would need to get its solution to work.

Lastly let me point out that this is not a duplicate question. I have seen similar questions on here that ask about how to implement this with and without STI, however the answers to those questions generally propose using an STI architecture or simply point the wiki article that I'm seeking help with, but do not seem to offer real reproducible solutions or advice on how to implement Omniauth with multiple models. My question is much more specific and a result of a deficiency in the wiki article's explanation on how to manually build the routing for the omniauthable module.

Daniel Bonnell
  • 4,817
  • 9
  • 48
  • 88
  • Using more than one user model is usually a bad idea in the first place. You have to use very complex logic in your authentication system to know what table to load the current user from. Usually this is much better handled by using a role based access system. – max Mar 09 '16 at 15:27
  • If you have to have different methods / logic for the different types of user you would use Multiple Table Inheritance instead. – max Mar 09 '16 at 15:30
  • I'm not interested in redesigning the architecture of the user models at this point as it introduces too much refactoring work. I also don't want `Contact` to inherit from `Employer`. I prefer to keep these models as seperate as possible. The app is quite complex, but needless to say there is little complex logic involved for authentication. Each user model interacts with a different part of the app. There is no crossover. `Employer` is analogous to an admin that only accesses part of the app. `Contact` is analogous to a user or employee who only has access to consumer facing side of the app. – Daniel Bonnell Mar 09 '16 at 15:39

0 Answers0