简体   繁体   中英

How do I design this rails database relationship?

Ok so I have users and companies. I have 95% of the users will have one and only one company so I wanted to do a one to many.

Users Table

create_table "users"
  string   "email",
  string   "first_name"
  string   "last_name"
  string   "phone_number"
  integer  "company_id"

But the problem is there are admins that need to be associated to more then one company and a few users in the system that have 2 companies.

So then I assumed a join table because of the many to many relationship

Join Table

"company_users"
  t.integer  "company_id"
  t.integer  "user_id"

But I have to assess the users company so frequently that I want to be able to access the company easily and hate to have a join table for 5% of the users. Any ideas?

There is no way out of using the linking table, unless you leave out the data about the admins with multiple companies. I suggest you track both the many-to-many and track a primary company.

 class User
   belongs_to :primary_company, :class_name => Company
   has_many :company_users
   has_many :companies, :through => :company_users
 end

Unfortunately, even if there were only one single user in the system that had more than one company, it then becomes many-to-many.

  1. You could require that the user have two records, one for each company, but that seems not ideal.
  2. You could put 2 foreign keys to Company on User and declare belongs_to :company, foreign_key: 'company1_id' twice using different foreign keys. Not ideal at all, but it could work.
  3. You could use a database that supports arrays and have an array of company_ids. This won't easily work with ActiveRecord though. However, if using MongoDB is an option, Mongoid has good support for this.
  4. Most likely, you're just going to have to have a joins table. I'd consider putting another field on there for the role (admin, employee, etc) and call the model Position. Then a user has_many :positions and has_many :companies, through: :positions . If this is going to cause an awful lot of joins, you'll want to find a way to cache it. Caching is actually really easy in Rails.

Rails Caching
Low-level caching in Rails

You can denormalize.

Add a boolean flag ' only_1_company '.

Maintain it with triggers.

I re-read the answer and now feel that your problem is in

"I want to be able to access the company easily and hate to have a join table for 5% of the users."

What do you 'hate' this fact? How is the 'only 5%' actually affecting either the application architecture or performance or usability?

Focus on the issue that is showing up for your users. If they find the ui confusing or too slow, then work on the basis of that issue.

Trying to eliminate 'possible' future performance problems is generally considered to be a poor use of time. The application may well change considerably by that time. Also, addressing performance may mean approaches like denormalization and you definitely don't want to use such approaches until the exact problem is identified.

Also databases are made to be very efficient in looking up records through join tables so again I would not worry about inefficiencies unless they are causing actual problems right now.

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