在Rails中重定向外键

时间:2015-10-26 16:11:46

标签: ruby-on-rails-4 rails-activerecord

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_itemsorder_id = 1 AND(order_items.order_reference ='ref1ref2' )

我认为尝试的每个SQL查询都存在相同的基本问题 - 在某个地方,Rails决定我们仍然隐含地试图通过order_id进行键入,而我无法找到说服它的方法。

其他选项

目前我的选择似乎是使用Composite Primary Keys gem或者只是忽略Rails的内置关联并使用数据库查询攻击我们自己的关联,但似乎都不理想 - 而且似乎Rails肯定会有切换外键的选项。但如果是这样,它在哪里?

谢谢,

萨莎

0 个答案:

没有答案