简体   繁体   中英

Rails associations many to many through join table

I have the following models: Organisation , Valuation and Capability .

The Organisation model used to have a country field, but it came to my attention it can have multiple locations.

To solve this I could create a Location model and add a has_many relation between Organisation and Location , equally however a location can belong to more than one organisation. For example, Organisation X might have a location in UK, DE and US and organisation Y might have a location in UK and DE.

The bigger problem lies with Valuation which describes valuations of a organisation at a specific location for a specific capability. So where the valuation at organisation X in location Y might be 10, it could be 8 for organisation X at location Z.

Right now Valuation has belongs_to assocations to both Organisation and Capability :

class Valuation < ApplicationRecord
  belongs_to :organisation
  belongs_to :capability
end

To account for the location, I would need to add another association, but I am looking for some hints as to which one.

The question then is, how to set up my assocations so I can ask questions like:

" what is the average valuation of organisation x with capability y over all locations "

or

" what is the valuation of organsiation x for capability y at location z "

EDIT

Ended up going with the many-to-many approach, ended up with the models:

class Organisation < ApplicationRecord
  has_many :memberships
  has_many :locations, through: :memberships
end

class Location < ApplicationRecord    
  has_many :memberships
  has_many :organisations, through: :memberships
end

class Membership < ApplicationRecord
  belongs_to :organisation
  belongs_to :location
end

Question now is to link this to Valuation

The relationship between Organization and Location is actually many-to-many. What you need is a joined table OrganizationsLocation , whose table is organizations_locations with schema organization_id and location_id .

And, the valuation should actually belong to an OrganizationsLocation record.

class OrganizationsLocation < ActiveRecord::Base
  belongs_to :organization
  belongs_to :location

  has_many :valuations
end

Organization could have many valuations through above model.

class Organization < ActiveRecord::Base
  has_many :organizations_locations
  has_many :valuations, through: :organizations_locations
end

For your first question "what is the average valuation of organization x with capability y over all locations", you could get all the valuations with below code and calculate the average:

x.valuations.where(capability_id: y.id)

For your second question: "what is the valuation of organization x for capability y at location z":

OrganizationsLocation.find_by(organization_id: x.id, location_id: z.id).valuations.find_by(capability_id: y.id)

UPDATE:

Since you already have a joined table memberships , which is the same with my suggested table organizations_locations , it could fit your needs.

You Valuation should belongs_to a Membership instead of Organization .

class Valuation < ActiveRecord::Base
  belongs_to :membership
  belongs_to :capability
end

x.valuations.where(capability_id: y.id)

Membership.find_by(organization_id: x.id, location_id: z.id).valuations.find_by(capability_id: y.id)

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