如何将一个用户映射到另一个用户(来自同一个 table)

How to map one user to another (from same table)

我想知道如何使用正确的引用 integrity/uniqueness 约束解决我的 model/migrations 中的这个问题。

我有一个用户 table,他有两种类型的用户:support_worker 和 service_user(例如老师和学生)。一个 support_worker 可以为许多 service_user 提供支持。我曾经为这些各自的用户类型分别设置 table,但为简单起见,将两种用户类型放在一个 'user' table 中更有意义(对于 Devise)。

我将有另一个名为 support_allocation 的 table,它记录 support_worker 和他们支持的 service_user(s) 之间的关系 - 这个 support_allocation 存储了有关它的其他信息(如预算;time/money)。所以这个 table 需要将一个 user_id 映射到另一个 user_id。我想象 table 结构看起来像这样: SupportAllocation (id, support_worker_id, service_user_id)

到目前为止,我的迁移看起来像这样(我使用 Devise gem 创建了用户 table 所以这修改了它):

class ChangeUsers < ActiveRecord::Migration[5.2]
  def change
    change_table :users do |t|
      t.string :user_type # support_worker or service_user

      t.string :given_name
      t.string :family_name

      t.string :customer_reference # only for service_users
      t.date :date_of_birth # only for service_users

      t.string :job_roles # only for support_workers
  end
end

class CreateSupportAllocations < ActiveRecord::Migration[5.2]
  def change
    create_table :support_allocations do |t|
      t.boolean :active, default: true

      # This next bit is guesswork
      t.integer support_worker_id # support_worker's user_id
      t.integer service_user_id # service_user's user_id 

      t.timestamps
    end
  end
end

这是我感到困惑的地方...我需要创建一个连接,但这只会在 user_id 上进行,而关系是由两个 user_id 列定义的(如图所示并在上面命名)。我不确定这是一个复合键还是一个(或两个)外键就足够了。

这是我正在进行的迁移工作:

class AddJoins < ActiveRecord::Migration[5.2]
  def change
    change_table :support_allocations do |t|
      t.belongs_to :user, index: true
    end
  end
end

我想知道如何实现这一点。作为记录,我正在为我的应用程序使用 ActiveAdmin。谢谢你的帮助。

我认为您不需要 AddJoins 迁移。在您的 CreateSupportAllocations 模型中添加 2 个关联,如下所示:

belongs_to :support_worker, :foreign_key => :support_worker_id, :class_name => User
belongs_to :service_user, :foreign_key => :service_user_id, :class_name => User

在您的 activeadmin 表单中,您可以为 select 设置集合,例如

(在app/admin/support_allocations.rb)

form do |f|
  f.inputs do 
    # your inputs
    f.input :support_worker, :as => :select, :collection => User.where(:user_type => 'support_worker')
    f.input :service_user, :as => :select, :collection => User.where(:user_type => 'service_user')

  end
  f.actions 
end

# added after comments
index do
  selectable_column
  column :support_worker
  actions 
end

在您的用户模型中添加一个 to_s 方法,如下所示:

def to_s
  "#{self.full_name}"
end

感谢您的帮助。我将建议的关联添加到我的 SupportAllocation 模型中。作为记录,我还必须将以下关联添加到我的用户模型中,以使连接在两个方向上都能完全工作:

  has_many :occurances_as_support_worker, :class_name => 'SupportAllocation', :foreign_key => 'support_worker_id'
  has_many :occurances_as_service_user, :class_name => 'SupportAllocation', :foreign_key => 'service_user_id'

我使用示例 given here 来解决这个问题。

在索引页面上访问特定于某类用户的属性时(即使用 support_worker_id 或 service_user_id 上的连接)。我使用这样的代码:

 column 'Service user', :full_name, :sortable => 'service_users.family_name' do |support_allocation|
      #ServiceUser.find(support_allocation.service_user_id).full_name
      support_allocation.service_user.full_name
    end

      column 'Support worker', :full_name, :sortable => 'support_workers.family_name' do |support_allocation|
        support_allocation.support_worker.full_name
      end