We want to achieve the following:
- Be able to compare 'Projects' with other (multiple) Projects.
- Save the comparison reference in the database.
In the past we did this by storing an array in the database like below:
t.string "comparisons", default: [], array: true
Now we are thinking about using another table - unless there is a better way?
Ideally something like this:
We already have this table:
| projects |
|-----------|
| id | name |
| 1 | abc |
| 2 | def |
| 3 | ggg |
| 4 | fff |
We want to create another table similar to this:
| project_comparisons |
|-------------------------------|
| id | project_id | compared_id |
| 1 | 1 | 2 |
| 2 | 1 | 4 |
| 3 | 2 | 3 |
| 4 | 2 | 4 |
Where in the end we could do something like this:
Project.find(1).project_comparisons.each do |x|
x.name
end
# Output:
'def'
'fff'
But we are getting lost in the relationship setup.
This is what we have so far:
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
This now has the the incorrect output. If we now iterate the example:
Project.find(1).project_comparisons.each do |x|
x.name
end
# Output:
# aaa
# aaa
It should have been 'def' and 'fff'
Can I somehow specify that we want the 'compared_id' to get the correct Project, or are we on the wrong path here?
CodePudding user response:
What about something like:
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