Makers group project — learning many-to-many relationships on rails

Angus Pettifer
makers-group-project
4 min readJul 20, 2018

We are now past half way through the task of making Facebook for pets. During the planning session at the start of this 2 day sprint we each wrote down our learning objectives. This allowed us to split the development tasks according to what people wanted to learn.

I was keen to learn more about how databases work, and specifically wanted to build a feature that had a many-to-many relationship. So my pair and I set about building groups. Each pet can be a member of many groups, each group can have many pets as members, hence the term many-to-many.

The way that a many-to-many relationships are structures is as follows. There are two ‘sibling’ tables, in this case pets and groups. There is a joiner table that knows which pet is a member of which group.

In this case:

  • Cat belongs to the Wannabe Capybaras group, and the Chocolate lovers group
  • Dog belongs to the Wannabe Capybaras group
  • Capybara belongs to the Chocolate lovers group

Seems simple right? What could possibly go wrong?

I had heard rails was opinionated, I hadn’t quite realised just how opinionated.

“A yellow sign high in the mountains reads “Caution, avalanche danger”” by Nicolas Cool on Unsplash

Big mistake 1… typo

Rails does not like you making mistakes.

In our first iteration of this task we had labelled the pet column as ‘type’ (I.e. type of pet). We used rails generate to generate a new table in the database, but frustratingly I had made a typo, I typed ‘amount’ instead of ’type’ as that was what was in the tutorial I was following (foolish mistake!).

On our first round of googling did not find the ‘rails db:rollback’ command that would have saved a lot of hassle. Instead we manually deleted the migration file from the folder and relevant lines of code from the schema. We then deleted the entire database from my local computer and started again using ….

Big mistake 2… use of type

Rails does not like it when you use certain words as column headings.

Having started again, we now had the correct migrate file and schema. All seemed well. However, when we ran ‘rails console’ and checked the pets table, it did not show me the ‘type’ column heading. Full disclaimer, I didn’t fully understand what all the commands where doing (my face was green), so we tried deleting the lot, including the database and starting again. No change.

We then checked using PSQL and did find the column ‘type’. So it had appeared, but for some reason rails didn’t want to show it to me.

Confused, but persistent, we decided to proceed with animals being able to add their ‘type’, but instantly ran into errors. It turns out that, since rails is very opinionated, it doesn’t like you using the word ‘type’ as a column heading. ‘Type’ is a reserved word for active record.

Big mistake 3… pluralising a column heading

Rails magic includes pluralisation, it even knows that ‘people’ is the plural of ‘person’.

Undeterred, my pair and I start again, again. This time we decide to call the column ‘names’. Once again we start running into errors. We had fallen for another of rails’ opinionated tricks.

Click here to understand how you should label your column names. Ignore this at your peril.

At the end of the sprint we had the database structure successfully set up. We were also effectively using the has_and_belongs_to_many association in the respective controllers. This uses some ‘rails magic’ in order to allow us to create relationships between pets and groups.

As the feature freeze went in we had created a page where a pet could join a group, but unfortunately they could only join all the groups, and the way they joined them was refreshing the page. So sadly our work did not make it to production.

What we learnt:

  • The database structure for a many-to-many relationship and how to set this up in rails
  • Rails magic embedded in has_and_belongs_to_many association
  • Don’t mess with rails, its opinion is more important than yours

Thank you for reading! If you enjoyed this post, please clap 👏 to help others find it. I’d also love your feedback if you care to share.

--

--