1

I'm having trouble conceptualizing a good way to create associations between two different models within my Rails app.

At the moment I have a Person model and a Note model. A person can be the author or the subject of a note. Therefore:

  • A person can belong to many notes (as the subject).
  • A person can have many notes (as the author).
  • A note belongs to one author (person).
  • A note can have one subject (person).

I imagine the app needing to display Person profiles, in which we can see all Notes that the Person has written, as well as all Notes written about the Person.

What's the best way to set up this model-association? Directly, or through an intermediate relationship model?

Thanks in advance!

ArcGhost
  • 137
  • 1
  • 3
  • 12

1 Answers1

1

In my opinion, the cleanest way is to make a note belong to an author and a subject:

class Note < ActiveRecord::base
  belongs_to :author, class_name: 'Person', foreign_key: :author_id
  belongs_to :subject, class_name: 'Person', foreign_key: :subject_id
end

class Person < ActiveRecord::base
  has_many :authored_notes, class_name: 'Note', foreign_key: :author_id
  has_many :notes_about_me, class_name: 'Note', foreign_key: :subject_id
end

You may want to change the names of the relationships above, but you get the picture.

I know we don't normally think of a note about someone as belonging to the subject of the note. However, from a Rails perspective, the belongs_to relationship allows us to place the subject_id foreign key on the notes table which is the simplest solution. If you were to use the has_one relationship, you would have to create a join table which, in my opinion, adds unnecessary complexity.

Make sure your notes table has has two indexed references to the persons table called subject_id and author_id. You can do that with a migration like this:

class AddSubjectAndAuthorToNotes < ActiveRecord::Migration
  def change
    add_reference :notes, :author, index: true
    add_reference :notes, :subject, index: true

    add_foreign_key :notes, :people, column: :author_id
    add_foreign_key :notes, :people, column: :subject_id
  end
end
Tom Aranda
  • 5,919
  • 11
  • 35
  • 51