In my application I have models: Car:
class Car < ActiveRecord::Base
has_one :brand, through: :car_configuration
has_one :model, through: :car_configuration
has_one :body_style, through: :car_configuration
has_one :car_class, through: :car_configuration
belongs_to :car_configuration
end
CarConfiguration:
class CarConfiguration < ActiveRecord::Base
belongs_to :model, class_name: 'CarModel'
belongs_to :body_style, class_name: 'CarBodyStyle'
belongs_to :car_class
has_one :brand, through: :model
has_many :cars, dependent: :destroy
has_many :colors, dependent: :destroy
def brand_id
brand.try(:id)
end
end
and CarBrand:
class CarBrand < ActiveRecord::Base
default_scope { order(name: :asc) }
validates :name, presence: true
has_many :models, class_name: 'CarModel', foreign_key: 'brand_id'
end
Now I want to get all Cars which CarConfiguration brand id is for example 1. I tried something like this but this not work:
joins(:car_configuration).where(car_configurations: {brand_id: 1})
Thanks in advance for any help.
Associations
I don't think you can have a belongs_to :through
association ( belongs_to through associations ), and besides, your models look really bloated to me
I'd look at using a has_many :through
association :
#app/models/brand.rb
Class Brand < ActiveRecord::Base
has_many :cars
end
#app/models/car.rb
Class Car < ActiveRecord::Base
#fields id | brand_id | name | other | car | attributes | created_at | updated_at
belongs_to :brand
has_many :configurations
has_many :models, through: :configurations
has_many :colors, through: :configurations
has_many :body_styles, through: :configurations
end
#app/models/configuration.rb
Class Configuration < ActiveRecord::Base
#id | car_id | body_style_id | model_id | detailed | configurations | created_at | updated_at
belongs_to :car
belongs_to :body_style
belongs_to :model
end
#app/models/body_style.rb
Class BodyStyle < ActiveRecord::Base
#fields id | body | style | options | created_at | updated_at
has_many :configurations
has_many :cars, through: :configurations
end
etc
This will allow you to perform the following:
@car = Car.find 1
@car.colours.each do |colour|
= colour
end
OOP
Something else to consider is the object-orientated
nature of Ruby (& Rails).
Object orientated programming is not just a fancy buzzword - it's a core infrastructure element to your applications, and as such, you need to consider constructing your Models etc around objects:
This means that when you're creating your models to call the likes of Car
objects, etc, you need to appreciate the associations
you create should directly compliment that particular object
Your associations currently don't do this - they are very haphazard & mis-constructed. I would recommend examining what objects you wish to populate / create, and then create your application around them
In your achitecture, brand_id from CarConfiguration is not an attribute of the model hence, you can't query as you tried...
The solution is more to select the good car configuration first and get all the corresponding cars :
CarConfiguraton.joins(:brand).where(brand: {id: 1}).cars
def self.with_proper_brand(car_brands_ids)
ids = Array(car_brands_ids).reject(&:blank?)
car_ids = Car.joins(:car_configuration).all.
map{|x| x.id if ids.include?(x.brand.id.to_s)}.reject(&:blank?).uniq
return where(nil) if ids.empty?
where(id: car_ids)
end
That was the answer.
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.