我如何使用多个外键制作 rails 模型 belongs_to

How can i make rails models belongs_to using multiple foreign key

最近我有一个迁移,将 user_id 列添加到 watch_events 表。因此我想更改 watch_event 模型来处理 belongs_to 但采用多种方法

  create_table 'users', force: :cascade do |t|
    t.integer 'id'
    t.integer 'customer_id'
  end

  create_table 'watch_events', force: :cascade do |t|
    t.integer 'customer_id'
    t.integer 'user_id'
  end

之前

class WatchEvent < ApplicationRecord
  belongs_to :user, foreign_key: :customer_id, primary_key: :customer_id
end

我想要的:

如何在 watch_event 模型上实现这一点?

如果我没有正确理解你的问题,那么你正在寻找的是 Polymorphic association

如果您看到下面的代码,它基本上所做的就是在 watch_events、table、watcher_typewatcher_id 中创建两列。 belongs_to :watcher 然后使用 watcher_type 列来确定它应该关联到哪个模型,

create_table 'watch_events', force: :cascade do |t|
  t.references 'watcher', polymorphic: true, null: false
end

class WatchEvent < ApplicationRecord
  belongs_to :watcher, polymorphic: true
end

我认为 Rails 不支持 'fallback foreign keys' 关联。但是,您可以为您的问题编写一个简单的包装器。首先,使用你的两个键和两个 'internal' 关联名称(:user_1:user_2)将你的 WatchEvent class 与用户模型关联两次。然后,添加一个 'virtual association reader' (user) 和一个 'virtual association setter' (user=(new_user)):

class WatchEvent < ApplicationRecord
  
  belongs_to :user_1,
             class_name: 'User',
             foreign_key: :customer_id

  belongs_to :user_2,
             class_name: 'User',
             foreign_key: :user_id
  
  def user
    user_1 || user_2
  end

  def user=(new_user)
    self.user_1 = new_user
  end

end

使用此解决方案,要求“使用 customer_id 查找用户”和“如果 customer_idnil 或不为 nil,则使用 user_id 作为后备外键产生结果”是满意的。它发生在关联 reader 方法 user 中。当有 reader 方法时,您将需要一个 setter 方法,即 user=()。随意根据需要设计 setter 的内部结构,我的只是一个建议。

顺便说一句:您可能需要重新添加国外的声明primary_key。为了清楚起见,我省略了它。