Rails has_one和belongs_to加入

时间:2014-08-08 09:20:06

标签: sql ruby-on-rails ruby join

在我的应用程序中,我有模特: 汽车:

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

和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

现在我想获得所有CarConfiguration品牌id的汽车例如1。 我试过这样的事情,但这不起作用:

  joins(:car_configuration).where(car_configurations: {brand_id: 1})

提前感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

<强>协会

我认为你不能拥有belongs_to :through关联(belongs_to through associations),此外,你的模特看起来真的很臃肿

我会考虑使用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

这将允许您执行以下操作:

@car = Car.find 1
@car.colours.each do |colour|
   = colour
end

<强> OOP

需要考虑的是Ruby(&amp; Rails)的object-orientated性质。

面向对象的编程不仅仅是一个花哨的流行语 - 它是应用程序的核心基础结构元素,因此,您需要考虑构建模型等围绕对象:

enter image description here

这意味着当您创建模型以调用Car个对象等时,您需要了解您创建的associations应该直接补充该特定对象

你们的协会目前不这样做 - 他们是偶然的&amp;误构造。我建议您检查一下您希望填充/创建的对象,然后围绕它们创建应用程序

答案 1 :(得分:2)

在您的体系结构中,来自CarConfiguration的brand_id不是模型的属性,因此您无法在尝试时进行查询...

解决方案更多的是首先选择好的汽车配置并获得所有相应的汽车:

CarConfiguraton.joins(:brand).where(brand: {id: 1}).cars

答案 2 :(得分:1)

    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

这就是答案。