LightBox
LightBox

Reputation: 3425

Rails association for different user types

I have a user model and want to attach profile information to it specific to the gender.

Should I have a FemaleProfile & MaleProfile model in addition to the User model that holds the gender neutral data as illustrated below?

User model:

has_one :FemaleProfile
has_one :MaleProfile

Fields :Name, :Age

FemaleProfile model:

belongs_to :User

Fields :Name, :Age, :Dress_Color

MaleProfile model:

belongs_to :User

Fields :Name, :Age, :Tie_Color

What I don't understand if this is indeed correct is that a user has either a male or female profile yet the association has both types of profile associated with the User.

Is there an inverse polymorphic relationship? I have taken a look at STI but it does not allow fields exclusive to the inheriting models.

Upvotes: 0

Views: 136

Answers (2)

jvnill
jvnill

Reputation: 29599

You can go with polymorphic associations (why are you asking for an inverse polymorphic implementation?) or a serialized attribute.

Serialized Attribute

you can add a gender_details column with type text and then serialize this attribute. then define female and male attributes.

# user.rb
class User < ActiveRecord::Base
  MALE_DETAILS = %w[sports cars]
  FEMALE_DETAILS = %w[perfume flowers]

  serialize :gender_details, Hash

  (MALE_DETAILS + FEMALE_DETAILS).each do |attr|
    define_method attr do
      self.gender_details ||= {}
      self.gender_details[attr.to_sym]
    end

    define_method "#{attr}=" do |value|
      self.gender_details ||= {}
      self.gender_details[attr.to_sym] = value
    end
  end
end

so you can use

user.sports = 'Basketball'
user.flower = 'Rose'

Upvotes: 0

siekfried
siekfried

Reputation: 2964

I would consider in this cas using Multi Table Inheritance. I personally use the citier gem to implement this : http://inspiredpixel.net/citier/

Concretely, you would have a User table with the 4 common fields, and 2 inherited tables, each one with its own fields, which seems to be what you look for.

Upvotes: 1

Related Questions