Search code examples
ruby-on-railspostgresqlactiverecordrails-admin

Active Record, how to make N-N relationship properly?


I have a N-N relationship between the tables Notebook and Part. A Notebook has many Parts and a Part can be present in many Notebooks. Here's a example of the schema:

enter image description here

In other approach, as suggested by AJFaraday in comments, I would have a single join table notebook-parts with a role to identify if its a gpu, a processor, etc:

enter image description here

How can I use the approach 2 to invoke notebook.processor, notebook.gpu etc inside Rails? And also I'll need to have some empty parts since some notebooks doesn't have dedicated gpu's, or maybe have only ssd's without hd's etc ?

How the model's relationship's should be?


Solution

  • Just create a model for the join table and reference it in both models.

    # models/notebook_part.rb
    class NotebookPart
      belongs_to :notebook
      belongs_to :part
    end
    
    # models/part.rb
    class Part
      has_many :notebook_parts
      has_many :notebooks, though: :notebook_parts
    end
    
    # models/notebook.rb
    class Notebook
      has_many :notebook_parts
      has_many :parts, though: :notebook_parts
    end
    

    Then in your notebook model you can create methods based on part roles something like:

    # models/notebook.rb
    def processors
      parts.where(part_role: :processor)
    end
    

    Then make that for any other roles you deem necessary, or think of some metaprogramming loop to make those lists for you.