views:

74

answers:

1

Hi everyone,

I have a system where I need to login three user types: customers, companies, and vendors from one login form on the home page.

I have created one User table that works according to AuthLogic's example app at http://github.com/binarylogic/authlogic_example. I have added a field called "User Type" that currently contains either 'Customer', 'Company', or 'Vendor'.

Note: each user type contains many disparate fields so I'm not sure if Single Table Inheritance is the best way to go (would welcome corrections if this conclusion is invalid).

Is this a polymorphic association where each of the three types is 'tagged' with a User record? How should my models look so I have the right relationships between my User table and my user types Customer, Company, Vendor?

Thanks very much!

------UPDATE------

Current setup:

#User model
class User < ActiveRecord::Base
  acts_as_authentic
  belongs_to :authenticable, :polymorphic => true
end

#Customer model (Company and Vendor models are similar)
class Customer < ActiveRecord::Base
  has_many :users, :as => :authenticable
  acts_as_authentic
end

Is this a valid way to set them up?

A: 

This is what it sounds like you are trying to do:

You have users that can be in one of three groups. If that isn't quite right a little clarification would help.

Since AuthLogic only cares about it's special fields, making and using other fields in your user model is no biggy.

Each user might be made up something like this:

#The Authlogic Fields
t.string :username,          :null => false
t.string :crypted_password,  :null => false
t.string :password_salt,     :null => false
t.string :persistence_token, :null => false

#Your field to identify user type
t.integer :user_type

#If your user is a customer, you would populate these fields
t.integer :customer_name
...

#If your user is a company, you would populate these fields
t.integer :company_name
...

#If your user is a vendor, you would populate these fields
t.integer :vendor_name
...

I'm not sure what you mean by "single table inheritance" but if you want to keep information about a vendor in a table separate from the users table (really no reason to unless you are REALLY concerned about performance) you can just link up your models like this:

class User < ActiveRecord::Base
  has_many :customers, :companies, :vendors
end

class Customer < ActiveRecord::Base
  belongs_to :user
end

class Company < ActiveRecord::Base
  belongs_to :user
end

class Vendor < ActiveRecord::Base
  belongs_to :user
end

In this case, since a user would have no associations to 2 of the 3 user types, you are pushed into using the has_many association which works nicely with the 0 association case. You would just have to do some checks in your code to make sure you don't double up.

James
Hi James, I'm going to try this out - thanks very much for the code. The reason I want to avoid your first option is that the Customer, Company, and Vendor tables all have >20 fields in them, and I don't want the User table to end up with ~60 fields, ~40 of which are always empty. I'm going to try the one-many and see if that works better. Thank you!
sscirrus