考虑以下模型设置:
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 #=> [...]
答案 0 :(得分:1)
您不能has_many
与has_one
配对,has_*
需要与belongs_to
配对(当然除了has_many :through
)。< / p>
因此,您需要更改为motorcycle
belongs_to
:front_tire
或创建第三个联接模型。
答案 1 :(得分: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
,这将返回FrontTire
或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
Npw Motorcycle.first.tires
将返回两个对象的数组,一个FrontTire
的实例和一个BackTire
的实例。您可能希望添加验证器以防止将多个前/后轮胎分配到同一辆摩托车。
答案 2 :(得分:0)
这根本没有经过测试,但是这样的事情怎么样:
has_many :motorcycles,
:class_name => 'Motorcycle',
:finder_sql => proc { "select * from motorcycles
where front_tire_id = #{id} OR
back_tire_id = #{id}" }
答案 3 :(得分:0)
我认为这样的事情应该有效
class Tire < ActiveRecord::Base
belongs_to :motorcycle
end
将has_many :motercycles
更改为belongs_to :motorcycle
Motorcycle
有很多轮胎(通过has_one
)
Tires
属于motorcycle
或者你可以使用像
这样的东西class Motorcycle < ActiveRecord::Base
has_many :tires
end
class Tire < ActiveRecord::Base
belongs_to :motorcycle
end
含有Tire
的{{1}}的可以包含前面或后面的值
你可以在模型中创建一些常量来维护像
这样的常量column position
这只是另一种选择:)
答案 4 :(得分:-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