Optional or Conditional model associations in Rails
Asked Answered
R

2

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?

Ridgeling answered 11/10, 2011 at 22:33 Comment(0)
C
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.

Carmel answered 11/10, 2011 at 22:55 Comment(2)
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.Ridgeling
@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.Carmel
W
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.

Watson answered 11/10, 2011 at 22:55 Comment(3)
+1 because a lazy programmer is a good programmer :) and for the note about conditions used for associationsCarmel
@WizardofOgz That's what I keep telling my boss! I think it was... Hamlet? who said "Out of laziness comes innovation."Watson
You're absolutely right! I just gave Wizard the cred since he included code. :)Ridgeling

© 2022 - 2024 — McMap. All rights reserved.