Rails 使用 has_many 自引用一个模型

Rails self reference one model with has_many

我们希望实现以下目标:

  1. 能够将 'Projects' 与其他(多个)项目进行比较。
  2. 在数据库中保存比较参考。

过去我们通过在数据库中存储一个数组来做到这一点,如下所示:

t.string "comparisons", default: [], array: true

现在我们正在考虑使用另一个 table - 除非有更好的方法?

理想情况下是这样的:

我们已经有了这个 table:

|  projects |
|-----------|
| id | name |
| 1  | abc  |
| 2  | def  |
| 3  | ggg  |
| 4  | fff  |

我们想创建另一个 table 与此类似:

|       project_comparisons     |
|-------------------------------|
| id | project_id | compared_id |
| 1  |     1      |      2      |
| 2  |     1      |      4      |
| 3  |     2      |      3      |
| 4  |     2      |      4      |

我们到底在哪里可以做这样的事情:

Project.find(1).project_comparisons.each do |x|
  x.name
end

# Output:
'def'
'fff'

但我们在建立关系时迷失了方向。

这是我们目前所拥有的:

rails g model ProjectComparison project:references compared:references

# Migration file (edited)
create_table :project_comparisons do |t|
  t.references :project, foreign_key: true
  t.references :compared
end


class Project
  has_many :project_comparisons
  has_many :projects, through: :project_comparisons
  # ... Here I think we need something in the line above?
end


class ProjectComparison
  belongs_to :project
end

现在输出不正确。 如果我们现在迭代示例:

Project.find(1).project_comparisons.each do |x|
  x.name
end

# Output:
# aaa
# aaa

应该是'def'和'fff'

我能否以某种方式指定我们希望 'compared_id' 获得正确的项目,还是我们走错了路?

怎么样:

create_table :project_comparisons do |t|
  t.references :project, foreign_key: true
  t.references :compared, foreign_key: { to_table: 'projects'}
end


class Project
  has_many :project_comparisons
  has_many :compared, through: :project_comparisons
end


class ProjectComparison
  belongs_to :project
  belongs_to :compared, class_name: "Project", foreign_key: "compared_id"
end

Project.find(1).compared.each do |x|
  x.name
end