0

考虑以下模型设置:

Model A
  has one B1, type: B
  has one B2, type: B

Model B
  has many A

我希望能够从事这项工作:

class Motorcycle < ActiveRecord::Base
  has_one :front_tire, class_name: "Tire"
  has_one :back_tire, class_name: "Tire"
end

class Tire < ActiveRecord::Base
  has_many :motorcycles
end

最终结果是我能够做到这一点:

m = Motorcycle.new
ft = Tire.new
bt = Tire.new
m.front_tire = ft
m.back_tire = bt
m.save
Tire.first.motorcycles #=> [...]
4

5 回答 5

1

您不能has_many与 配对has_onehas_*需要与belongs_to(当然除了has_many :through)配对。

因此,您需要更改为motorcycle belongs_to:front_tire或创建第三个连接模型。

于 2012-08-26T16:25:21.820 回答
1

我认为您正在寻找基本的 Single-table Inheritance,因为前轮胎和后轮胎确实不是一回事,而是特定类型的轮胎。为此,您需要在表中添加一个type字符串列tires,并声明该类的两个子Tire类:

class Motorcycle < ActiveRecord::Base
  belongs_to :front_tire
  belongs_to :back_tire
end

class Tire < ActiveRecord::Base
end

class FrontTire < Tire
  has_many :motorcycles
end

class BackTire < Tire
  has_many :motorcycles
end

这将允许您使用Tire.first,它会返回一个FrontTireor的实例BackTire,它会有很多motorcycles. 这满足您的Tire.first.motorcycles要求。

m = Motorcycle.new
ft = FrontTire.new # id 1
bt = BackTire.new  # id 2
m.front_tire = ft
m.back_tire = bt
m.save
Tire.first.motorcycles # returns FrontTire #1

# Or, find specifically by tire type
FrontTire.first.motorcycles # all motorcycles with this front-tire
BackTire.first.motorcycles  # all motorcycles with this back-tire

或者,您可以简单地使用通用tires关系,因为前轮胎和后轮胎是不同的类:

class Motorcycle
  has_many :tires
end

class Tire < ActiveRecord::Base
end

class FrontTire < Tire
  has_many :motorcycles, foreign_key: :tire_id
end

class BackTire < Tire
  has_many :motorcycles, foreign_key: :tire_id
end

NpwMotorcycle.first.tires将返回一个包含两个对象的数组,一个是 a 的FrontTire实例,一个是 a 的实例BackTire。您可能希望添加一个验证器以防止将多个前/后轮胎分配给同一辆摩托车。

于 2012-08-26T16:38:32.490 回答
0

这根本没有经过测试,但是这样的事情怎么样:

has_many :motorcycles,
         :class_name => 'Motorcycle',
         :finder_sql => proc { "select * from motorcycles
                         where front_tire_id = #{id} OR
                         back_tire_id = #{id}" }
于 2012-08-26T15:47:22.117 回答
0

我认为这样的事情应该有效

class Tire < ActiveRecord::Base
  belongs_to :motorcycle
end

更改has_many :motercyclesbelongs_to :motorcycle

Motorcycle有很多轮胎(通过has_oneTires属于motorcycle

或者你可以使用类似的东西

class Motorcycle < ActiveRecord::Base
  has_many :tires
end

class Tire < ActiveRecord::Base
  belongs_to :motorcycle
end

包含Tire一个column positionwich 可以保存正面或背面的值

你可以在模型中创建一些常量来维护那些像

class Tire < ActiveRecord::Base
 FROUT 1
 BACK 2
 #....
end

这只是另一种选择:)

于 2012-08-26T16:18:46.657 回答
-1

我设法用这组代码解决了它:

class Motorcycle < ActiveRecord::Base
  has_many :tire_brands
  has_one :front_tire, class_name: "Tire"
  has_one :back_tire, class_name: "Tire"
end

class Tire < ActiveRecord::Base
  belongs_to :motorcycle
  belongs_to :tire_brand
end

class TireBrand < ActiveRecord::Base
  has_many :tires
  has_many :motorcycles, through: :tires
end
于 2012-08-26T17:55:52.843 回答