简体   繁体   中英

Complex Query in Rails using Model.where(…).includes(…)

I am trying to query through four layers (yikes!) of associations. Associations are as follows:

(edit: added associations details, I had them in the source but didn't include them here)

Provider
   has_many :specialties, :through => :provider_specialties
   has_many :provider_specialties, :through => :provider_licenses
   has_many :provider_licenses

ProviderLicense
  belongs_to :provider
  has_many :specialties, :through => :provider_specialties
  has_many :provider_specialties

#linking model between ProviderLicense and Specialty
ProviderSpecialty
  belongs_to :provider_license
  belongs_to :specialty

Specialty
  has_many :provider_specialties

My starting point is Ryan Bates's RailsCast . I have had success in searching for associated objects one layer deep, but this one is killing me.

providers = Provider.includes([:provider_languages, { :provider_licenses => :provider_specialties }]).where(conditions)

def specialties_and_conditions
  ["providers_specialties.specialty_id = ?", specialty_id] unless specialty_id.blank?
end

(edit: working query and joins below)

Provider.joins([:specialties => { :provider_licenses => :provider_specialties }]).where(conditions)

def specialties_and_conditions
  ["specialty_id = ?", specialty_id] unless specialty_id.blank?
end

I don't really understand how the "includes" method works. I am trying to search for the specialty_id in the ProviderSpecialty (linking) relationship with the code above, but have had little success making it work. Any help would be greatly appreciated! Thanks!

It looks like you are confusing includes with joins. Includes is used to preload data to save on queries. Joins is used like a normal Join in SQL statements to let you filter by associated criteria.

First I would add this to your ProviderLicense model (this lets you use the many-to-many relationship easier):

has_many :specialties, :through => :provider_specialties

I don't really know what query you are trying to achieve, but maybe this will help?

Provider.joins({:provider_licenses => [:specialties]}).where('specialties.id = ?', specialty_id)

You should have a look in your development logs at the SQL query that is generated and then tweak from there.

I haven't tested my code, so it may be slightly off with syntax.

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