Rails一个模型两个关联

时间:2017-10-12 21:59:32

标签: ruby-on-rails associations

我有一个用户模型和一个任务模型。所有用户都是相同的,每个用户都可以创建一个新任务并将该任务分配给另一个用户。在任务模型中,我有一个assigned_by列和一个assigned_to列,以便任何人都可以创建新任务并将其分配给其他任何人。后来我希望每个用户能够查看分配给他们的所有任务以及他们分配给其他人的所有任务。为此,我想设置一个关联。做这样的事情可以吗?

class Task < ApplicationRecord
  belongs_to :user, :foreign_key => 'assigned_by'
  belongs_to :user, :foreign_key => 'assigned_to'
end

我在同一个模型中有两个外键。然后在用户模型中我有:

class User < ApplicationRecord
  has_many :tasks
end

这是做这样事的正确方法吗?

3 个答案:

答案 0 :(得分:2)

您可能想要的是设置三个表:

class User < ApplicationRecord
  has_many :assignments, foreign_key: 'assignee_id'
  has_many :assignments_as_assigner, foreign_key: 'assignee_id'
  has_many :tasks, through: :assignments
  has_many :assigned_tasks, through: :assignments_as_assigner
  has_many :created_tasks, class_name: 'Task'
                           foreign_key: 'creator'
end

class Task < ApplicationRecord
  belongs_to :creator, class_name: 'User'
  has_many :assignments
end

class Assignment < ApplicationRecord
  belongs_to :assignee, class_name: 'User'
  belongs_to :assigner, class_name: 'User'
  belongs_to :task
end

这将创建一对多关联,以便可以将任务分配给许多用户。

模型中的每个关联都必须具有唯一的名称 - 否则您将覆盖之前的关联。

答案 1 :(得分:1)

尝试这样做防止覆盖

class User < ApplicationRecord
  has_many :owned_tasks,    class_name: "Task", foreign_key: "owner_id"
  has_many :assigned_tasks, class_name: "Task", foreign_key: "assignee_id"
end

class Task < ApplicationRecord
  belongs_to :owner,    class_name: "User", foreign_key: "owner_id"
  belongs_to :assignee, class_name: "User", foreign_key: "assignee_id"
end

答案 2 :(得分:1)

您建议的方法不起作用,因为您无法定义具有相同名称的2个方法(在这种情况下,两个方法都将被称为user)。

更好的方法是通过它实际上调用关系。 例如

class Task < ApplicationRecord
  belongs_to :assigned_by, class_name: 'User'
  belongs_to :assigned_to, class_name: 'User'
end

您可能还需要添加foreign_key选项或在数据库assigned_by_idassigned_to_id

中调用外键

此外,您需要更改User模型,因为tasks方法不明确。

class User < ApplicationRecord
  has_many :tasks_delegated, foreign_key: 'assigned_by_id', class_name: 'Task'
  has_many :tasks_assigned, foreign_key: 'assigned_to_id', class_name: 'Task'
end