【问题标题】:Rails self reference one model with has_manyRails 使用 has_many 自我引用一个模型
【发布时间】:2021-02-19 06:28:40
【问题描述】:

我们要实现以下目标:

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

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

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

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

最好是这样的:

我们已经有了这张桌子:

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

我们要创建另一个类似的表:

|       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”获取正确的项目,还是我们在这里走错了路?

【问题讨论】:

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


    【解决方案1】:

    类似的东西呢:

    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
    

    【讨论】:

    • 太棒了!我还发现它只通过将 foreign_key 添加到:belongs_to :project, foreign_key: 'compared_id' 来工作,但是我不会有很好的.compared 方法。我也会阅读foreign_key: { to_table: 'projects'}
    猜你喜欢
    • 2011-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-10
    • 1970-01-01
    • 2015-10-27
    相关资源
    最近更新 更多