多个has_one关系的反向

时间:2014-09-11 09:35:15

标签: ruby-on-rails activerecord

如何建模以下场景?我需要在验证时从车轮内进入自行车,所以我不能省略has_one

class Bicycle < ActiveRecord::Base
  belongs_to :front_wheel, :class_name => 'Wheel'
  belongs_to :back_wheel, :class_name => 'Wheel'
end

class Wheel < ActiveRecord::Base
  has_one :bicycle
end

b = Bicycle.new
b.front_wheel = Wheel.new
b.back_wheel = Wheel.new

b.save

# Fails with
ActiveModel::MissingAttributeError: can't write unknown attribute `wheel_id'

数据库架构:

create_table "bicycles", force: true do |t|
  t.integer  "front_wheel_id"
  t.integer  "back_wheel_id"
  t.datetime "created_at"
  t.datetime "updated_at"
end

create_table "wheels", force: true do |t|
  t.datetime "created_at"
  t.datetime "updated_at"
end

如果有人为这个问题找到了更好的标题,请更新它或给我留言。

1 个答案:

答案 0 :(得分:1)

问题是您的has_one会在桌面上寻找wheel_id。但是你将拥有front_wheel_idback_wheel_id并且车轮不知道它是前轮还是后轮。我不知道你是否可以为外键设置两个可能的选项。我不会假设。这意味着您的结构需要重新考虑。

您可以使用单表继承,因为我假设前轮和后轮将是相同的。所以你有一个车轮模型,车轮数据库将有一个类型列,其前后轮模型继承它。

class Wheel < ActiveRecord::Base    
end

class FrontWheel < Wheel
  has_one :bicycle
end

class BackWheel < Wheel
  has_one :bicycle
end

然后你有

b = Bicycle.new
b.front_wheel = FrontWheel.new
b.back_wheel = BackWheel.new

b.save

然后由于模型名称,前轮应成功查找front_wheel_id,后轮将查找back_wheel_id