5

I have a user model. Users can have 1 of 3 roles: role1, role2, role3. This is represented by a 'role' column in the user model. Each role has a unique profile. role1_profile, role2_profile, role3_profile. Each *_profile is a model.

How do I represent this optional association in Rails?

I've tried it two different ways:

class User < ActiveRecord::Base
    #FIRST WAY
    if current_user.role == 'role1' then has_one :role1_profile end 
    #SECOND WAY
    has_one :role1_profile, :conditions => ['user.role = ?', 'role1']
end

But that doesn't work. What is the right way to do this?

hrdwdmrbl
  • 4,814
  • 2
  • 32
  • 41

2 Answers2

4

Associations are not intended to be conditional. It's probably easiest to keep things that way, too.

How about having a polymorphic association between User and the various role profiles?

class User
  belongs_to :role_profile, :polymorphic => true
end

class RoleXProfile
  has_many :users, :as => :role_profile
end

Of course, you would need to add the role_profile_id and role_profile_type fields to your users table.

No matter what you do you will need to check the user's role or role_profile wherever you use it.

Wizard of Ogz
  • 12,543
  • 2
  • 41
  • 43
  • Thank you! I think your solution is perfect. There's always a way in Rails, but when you don't know the way, you tend to implement a solution in a weird way. – hrdwdmrbl Oct 11 '11 at 23:05
  • @jackquack I don't think your approach was weird at all. Quite the opposite, it was very logical. And it may very well point out a place where ActiveRecord can be improved/extended. Anyway, I'm glad you got things working. – Wizard of Ogz Oct 12 '11 at 00:01
4

You might want to consider a polymorphic association instead and just have appropriate role profiles.

My understanding was that the :conditions were conditions the associated model must meet (but I could be wrong on that).

In any case, I think you're making this more difficult than it really is and obfuscating what you really need by making these relationships conditional.

Dave Newton
  • 158,873
  • 26
  • 254
  • 302