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开发者_StackOverflow 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.
精彩评论