tldr;
在Rails中,如何将外键的目标列设置为父父ID以外的列?
到目前为止的努力
这感觉应该是一个简单的操作,但我收效甚微。我有一个父模型Order,它有许多OrderItems,但我希望OrderItems的外键引用Order的reference1和reference2字段的组合。
我看了几条路:
首先尝试
class Order < ActiveRecord::Base
has_many :order_items, foreign_key: :order_reference,
primary_key: :unique_reference
inverse_of: :order
validates :reference1, uniqueness: { scope: :reference2 }
end
class OrderItem < ActiveRecord::Base
belongs_to :order, foreign_key: unique_reference,
primary_key: order_reference
inverse_of: :order_item
end
(我创建了一个冗余感的unique_reference列,我们在创建之前使用reference1 + reference2填充,并为OrderItem提供了相应的order_reference列)
我尝试了上面的一些变体,但无法说服OrderItem接受unique_reference作为键。它设法链接记录,但是当我调用OrderItem#order_reference时,而不是匹配相应的Order#unique_reference字段的内容,它将返回其父ID的字符串化版本。
第二次尝试
我从Order类中删除了unique_reference列,将其替换为同名方法和has_many块:
class Order
has_many :order_items, -> (order) { where("order_items.order_reference = :unique_reference", unique_reference: order.unique_reference) }
def unique_reference
"#{reference1}#{reference2}"
end
end
class OrderItem < ActiveRecord::Base
belongs_to :order, ->(item){ where("CONCAT(surfdome_archived_order.source, surfdome_archived_order.order_number) = surfdome_archived_order_items.archived_order_reference") }
end
这一次,调用Order#order_items会引发SQL错误:
'where子句'中的未知列'order_items.order_id':SELECT order_items
。* FROM order_items
WHERE order_items
。order_id
= 1 AND(order_items.order_reference ='ref1ref2' )
我认为尝试的每个SQL查询都存在相同的基本问题 - 在某个地方,Rails决定我们仍然隐含地试图通过order_id进行键入,而我无法找到说服它的方法。
其他选项
目前我的选择似乎是使用Composite Primary Keys gem或者只是忽略Rails的内置关联并使用数据库查询攻击我们自己的关联,但似乎都不理想 - 而且似乎Rails肯定会有切换外键的选项。但如果是这样,它在哪里?
谢谢,
萨莎