Authlogic provides an API for working with subdomain-based authentication.
class User < ActiveRecord::Base has_many :brands has_many :companies, :through => :brands acts_as_authentic end class Brand < ActiveRecord::Base belongs_to :user belongs_to :company end class Company < ActiveRecord::Base has_many :brands has_many :users, :through => :brands authenticates_many :user_sessions, :scope_cookies => true end
Session Controller:
class UserSessionsController < ApplicationController def create @company = Company.find(params[:user_session][:company]) @user_session = @company.user_sessions.new(params[:user_session]) if @user_session.save else end end end
On the other hand
Here is a way to solve the problem using your current approach (I would use the first approach):
Set user data - to the email hash key used to create the UserSession object. AuthLogic will pass this value to the find_by_login method. In the find_by_login method, select the desired values.
Assumption: The subdomain identifier is set in the field named company in the form.
class UserSessionsController < ApplicationController def create attrs = params[:user_session].dup #make a copy attrs[:email] = params[:user_session] # set custom data to :email key @user_session = UserSession.new(attrs) if @user_session.save else end end end
Model code
Your code to search for a user with a given email address and subdomain can be simplified and optimized as follows:
class User < ActiveRecord::Base def find_by_email params={} # If invoked in the normal fashion then .. return User.first(:conditions => {:email => params}) unless params.is_a?(Hash) User.first(:joins => [:brands => :company}], :conditions => ["users.email = ? AND companies.id = ?", params[:email], params[:company]]) end end
Change 1
After user authentication, the system should provide access to authorized data.
If you store data for all domains in the same table, you must have data for the subdomain and the authenticated user. Suppose you have a Post model with company_id and user_id . When a user logs in, you want to display user messages for the subdomain. This is one way to capture user data for a subdomain:
Posts.find_by_company_id_and_user_id(current_company, current_user) Posts.for_company_and_user(current_company, current_user) # named scope
If you do not cover the data, you will have potential holes in your system.