假设以下内容:
class Customer < ActiveRecord::Base
has_many :orders
end
class Order < ActiveRecord::Base
belongs_to :customer
end
客户可以是红色客户和/或蓝色客户,但他们从不只是客户。红色顾客拥有狗,蓝色顾客戴帽子(顾客必须戴帽子或拥有狗)。对于给定的订单,red_customer 从不等于blue_customer。由于我从不使用customer_id,因此我希望将其从架构中删除,并将其替换为red_customer_id和blue_customer_id。每个订单都有一个red_customer_id和blue_customer_id。
...实例
架构(目前很难看)
create_table "orders"
t.string "name"
t.integer "user_id" # I want to get rid of this
t.integer "red_customer_id"
t.integer "blue_customer_id"
end
但是如果我删除user_id,那么我的关联会中断。我该如何清理它?
答案 0 :(得分:0)
假设订单一次只能属于一个用户,我建议您不要在表中包含2个foreign_keys。使用单表继承:
可以获得相同的结果class Customer < ActiveRecord::Base
has_many :orders
end
class RedCustomer < Customer
end
class BlueCustomer < Customer
end
class Order < ActiveRecord::Base
belongs_to :red_customer, foreign_key: 'customer_id'
belongs_to :blue_customer, foreign_key: 'customer_id'
end
这样,您可以为客户保留一个表,并为订单保留一个foreign_key。
为此,您需要在customer表中使用type
字符串列,也可以在订单迁移中将polymorphic: true
添加到客户foreign_key声明中,这样列customer_type
将会也被创造。
class CreateCustomers < ActiveRecord::Migration
def change
create_table :customers do |t|
t.string :type
t.timestamps null: false
end
end
end
class CreateOrders < ActiveRecord::Migration
def change
create_table :orders do |t|
t.references :customer, polymorphic: true, index: true
t.timestamps null: false
end
end
end
按预期工作:
order = Order.create
order.red_customer = BlueCustomer.create #=> raises <ActiveRecord::AssociationTypeMismatch>
order.red_customer = RedCustomer.create #=> Ok
order.blue_customer #=> nil
order.red_customer #=> #<RedCustomer id: ...>
order.blue_customer = BlueCustomer.create #=> Ok
order.red_customer #=> nil
希望这会对你有所帮助。