Ruby on Rails polymorphic association
Asked Answered
S

3

5

Here's what I'm trying to achieve: I have a Users table and each user can be any of a dozen of types: actor, dancer, director,...which is determined after signing up. Each type of user can have any number of profiles. Eg. actors can have any number of actor_profiles, dancers cand have any number of dancer_profiles,...

The problem is how do I link the profile with the user. An obvious solution would be to create an aditional table for each profile type, so that I could use a polymorphic belongs_to in User and then a simple belongs_to in each profile, but that seems less than optimum. An arguably better way would be to tell rails that user it's of type actor, so that user.profiles would work naturally, without any clutter. Does rails support such behaviour, or is there anything better than the former method? Thanks.

Spurry answered 6/3, 2009 at 2:34 Comment(0)
B
3

pjb's answer uses Single Table Inheritance. For this to work you need to add a column called type to your Users and to your Profiles* tables, so that Rails can save what type of User this is (since Actor, Dancer etc. are just subclasses of User).

This means they will all be saved in the users/profiles tables, but when you instantiate them ActiveRecord will instantiate them as the correct type. With this you'll be able to call

User.find

but also do things like

Actor.find, Actor.all, etc

and have it scoped to only Actors

Google rails single table inheritance for more details and examples.

  • Of course you'd need to declare your Profile subclasses the same way you declared your User subclasses

class Profile < ActiveRecord::Base belongs_to :user end

class ActorProfile < Profile end

class DancerProfile < Profile end

etc

Bagley answered 9/3, 2009 at 22:2 Comment(0)
S
1

Define the relationships in the subclasses:

class User < ActiveRecord::Base
end

class Actor < User
  has_many :profiles, :class_name => "ActorProfile"
end

class Dancer < User
  has_many :profiles, :class_name => "DancerProfile"
end
Susannahsusanne answered 6/3, 2009 at 2:42 Comment(0)
B
0

You'll need to make sure that your User table has a column called "type". Rails will save the TYPE of the Class (User, Actor, etc.) in that database field.

Barthelemy answered 22/5, 2009 at 13:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.