Our users want to associate tasks and goals. Specifically, our users want to designate that there are many tasks that serve one goal.
This wave focuses on creating a one-to-many relationship between goals and tasks, where a goal has-many tasks, and a task belongs to one goal.
When we have many tasks and many goals, users will want to conveniently gather all of the tasks associated with one goal. Our API should serve this information with a new route, /goals/<goal_id>/tasks
.
First, we should update our models so that the relationship is saved in our database.
Secondly, we should create our new route, /goals/<goal_id>/tasks
, so that our API gives back the right information.
- Use lesson materials and independent research to review how to set up a one-to-many relationship in Flask.
- Remember to run
flask db migrate
andflask db upgrade
whenever there is a change to the model. - Pay attention to the exact shape of the expected JSON. Double-check nested data structures and the names of the keys for any mispellings.
- Use the tests in
tests/test_wave_06.py
to guide your implementation. - Some tests use a fixture named
one_task_belongs_to_one_goal
that is defined intests/conftest.py
. This fixture saves a task and a goal to the test database, and uses SQLAlchemy to associate the goal and task together.
The Goal model should have a relationship with the model Task.
After reviewing the strategy for creating a one-to-many relationship, it is up to you if you would like to add convenience attributes for accessing the Goal
model from it's related Task
s and vice versa, accessing the list of associated Task
s from a Goal
model.
The Task model should belong to one Goal
.
After reviewing the strategy for creating a one-to-many relationship, in the Task model, we recommend:
- Setting the foreign key to
goal
's primary key column - Using
Optional
syntax to make the attribute nullable
Remember to run flask db migrate
and flask db upgrade
whenever there is a change to the model.
Given:
- a goal that has the ID
1
- three tasks with the IDs
1
,2
, and3
When I send a POST
request to /goals/1/tasks
with this request body:
{
"task_ids": [1, 2, 3]
}
Then the three Task
s belong to the Goal
and it gets updated in the database, and we get back a 200 OK
with the following response body:
{
"id": 1,
"task_ids": [1, 2, 3]
}
Given a goal that has:
- An id
333
- A
title
attribute with the value"Build a habit of going outside daily"
and a task that has:
- An id
999
- A
title
attribute with the value"Go on my daily walk 🏞"
- A
description
attribute with the value"Notice something new every day"
- A
completed_at
attribute with anull
value - It belongs to the Goal with ID 333
when I send a GET
request to /goals/333/tasks
,
then I get this response:
200 OK
{
"id": 333,
"title": "Build a habit of going outside daily",
"tasks": [
{
"id": 999,
"goal_id": 333,
"title": "Go on my daily walk 🏞",
"description": "Notice something new every day",
"is_complete": false
}
]
}
Given a goal that has:
- An id
333
- A
title
attribute with the value"Build a habit of going outside daily"
and no tasks that belong to this goal,
when I send a GET
request to /goals/333/tasks
,
then I get this response:
200 OK
{
"id": 333,
"title": "Build a habit of going outside daily",
"tasks": []
}
Given that no goals exist,
when I send a GET
request to /goals/1/tasks
,
then I get this response:
404 Not Found
You may choose the response body.
Make sure to complete the tests for non-existing tasks to check that the correct response body is returned.