Including Associated Data In A Sinatra API Response
Tags: ruby, beginners, webdev, sinatra
Published: 2022-07-18 18:15:33

I just wrapped up development on a [Scrum](https://www.zoho.com/sprints/what-is-a-scrum-board.html)/[Kanban](https://www.atlassian.com/agile/kanban/boards)-like application based on Ruby and React. In this post, I'll be discussing one of the roadblocks I was up against when creating the Ruby application controller.

---

A scrum/kanban (we'll call it scrumban from here on out) board is used by development teams to provide a way to break down a project into smaller chunks of work that are able to be implemented in 2-to-4-week sprints. The scrumban board _typically_ contains columns for work that is in the backlog, in-progress, in-review and closed.

My scrumban application allows a team to add new tasks to a project, edit a tasks properties (e.g. description, due date, story points, etc.) and delete tasks. All of the data for this application including users, project names, and tasks reside in their own tables in an SQLite database.

The scrumban React front end makes HTTP requests to the server through Sinatras application controller. Upon initial page load, the front end makes a request to the server for JSON object containing all of the tasks and their associated project and assigned user. **THIS** is where I hit a wall during development.

_How do I set up the application controller routing in a way that includes an entities associated data from **multiple** tables?_


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yxcbzryrtfw6fgfc2zhx.gif)

## Problem
My Ruby models are set up as shown in the Entity-Relationship Diagram (ERD) shown below. We have a Projects table, a Users table and a Tasks table (our "Join" table). Each task has a single associated project and a single associated user assigned to the task. A project and user can have many tasks.
![Scrum Board ERD](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/np9tlfh9yu74uytzklbe.png)

When it came time to configure my application controller (the "C" in [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller)), I wanted to return a JSON object of all of the tasks in the database. I also wanted to include project and user information for each of these tasks. I knew how to access associated data from **one** table (shown below), but how do I include data from **multiple** tables?

```ruby
1 get '/' do
2   task = Task.all
3   task.to_json(
4     include: :project
5   )
6 end
```
I searched forums and read the Sinatra documentation, but I just couldn't find the solution. I'm sure the answer **is** documented out there somewhere. But I was struggled to find it.

## Solution
One day I decided I was going to solve the mystery once and for all. I refused to build work-arounds into the client-side React application (e.g. multiple fetch requests, filtering arrays to find matching foreign and local keys, etc).

I threw everything I had at the problem. I tried multiple `include:` statements. I tried putting putting the associated tables into an object like this `include: {:project, :user}`.

Finally, I tried an array. It worked! Putting `[:project, :user]` after the `include:` statement is we include associated data from multiple tables!

```ruby
1 get '/' do
2   task = Task.all
3   task.to_json(
4     include: [:project, :user]
5   )
6 end
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ye9poqfor684ov00zk78.gif)

This will now give us the associated project **and** the assigned user for each task! It seems so simple now, but I was truly at a loss.

I hope this post helps someone else. If it does, let me know in the comments!

Photo by <a href="https://unsplash.com/@joshuafuller?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Joshua Fuller</a> on <a href="https://unsplash.com/s/photos/ruby?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>