Rails: How do I model preferences? Should I use ha

2019-04-02 10:53发布

I have two models: User and HairColor. A user has only one hair color, but can have many hair color preferences. What's the best way to model this?

Here's what I started to do:

#models/user.rb
class User < ActiveRecord::Base
  belongs_to :hair_color
  has_many :preferences, 
  has_many :hair_colors, :through => :preferences
end

#models/hair_color.rb
class HairColor < ActiveRecord::Base 
  has_many :users
end

#models/preference.rb
class Preference < ActiveRecord::Base 
  belongs_to :user
  belongs_to :hair_color
end

Is using has_many :through the right approach? Also what if I want to extend this to other attributes such as "eye color"? (A user has one eye color, but can prefer many eye colors"

1条回答
萌系小妹纸
2楼-- · 2019-04-02 11:21

There will be a limited amount of hair colors, so the preference table needs to have a hair_color_id and be set up like so:

#models/user.rb
class User < ActiveRecord::Base
  has_one :hair_color
  has_many :preferences
end

#models/hair_color.rb
class HairColor < ActiveRecord::Base 
  belongs_to :user
  belongs_to :preference
end

#models/preference.rb
class Preference < ActiveRecord::Base 
  belongs_to :user
  has_many :hair_color
end

I believe that's correct. Let me know if you run into any snags.


When you add eye color or any other characteristic, you'll probably have to do something different with preference. I'd have 4 columns at that point: id, user_id, foreign_id, foreign_type

foreign_id would be the id from the eye_color/hair_color table, and foreign_type would be "eye" or "hair" or something. Then in your model, you'd have something like this:

#models/hair_color.rb
class HairColor < ActiveRecord::Base 
  belongs_to :user
  has_many :preferences, :foreign_key => :foreign_id, :conditions => { "preferences.foreign_type" => "hair" }
end

That gets a little crazy, but it's the most DRY way of doing it. You'd put the same thing in your eye_color.rb and just replace "hair" with "eye" for the foreign_type.

查看更多
登录 后发表回答