简体   繁体   中英

Multiple foreign keys referenced in a single Rails model

I have a typical User model (username, password, name, etc). I want to allow users to attach three chosen categories to their account. Each of the three categories exist in the Category model.

How can I link three foreign keys from Category to a single User without using an intermediate table for tracking? Each Category can belong to any number of Users, but each user can have only three Categories.

I played with has_many :through but I really don't think a relationship table is necessary and it would generate a lot of coding on my end to work with it.

Any ideas?

From a code maintainability standpoint, even though you may want to restrict the number of categories a user can pick to 3 right now, you may not want to code it with this limitation. You'll be kicking yourself later when you want to increase it to 5 or reduce it to 1. My suggestion would be to just use has_and_belongs_to_many with a join table (you don't need :through because, from what I can tell, you don't need a join model , just a join table). Using HABTM will automatically use a join table so you don't have to worry about writing the code to handle that. Just make sure you name the join table and its columns properly.

As for actually restricting the user to only 3 categories, just implement that restriction in the view/controller (ie restrict the UI so they can't choose more than 3).

I'm sure you've already read this, but in case you haven't, here's the docs for HABTM.

HABTM is your best bet. To restrict users to three categories, add a model level validation:

class User < ActiveRecord::Base
  has_and_belongs_to_many :categories
  validate :no_more_than_three_categories
protected
  def no_more_than_three_categories
    self.errors.add(:categories, "may not have more than three") if categories.size > 3
  end
end

At your discretion, pull out the magic number 3 to a class level constant or a configuration setting.

And don't fear the code. Do it right and the code will fear you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM