rails new task-team
Published: 2022-06-06 22:32:38

**NOTE**: I wrote this blog post some time ago for Phase 3 of my Flatiron School SE program.


My goal for this project was to refine my process for building apps, in order to do so more efficiently. I came up with the following list of steps + questions to guide the development process:

**Brainstorm app idea**
* What problem do you want to solve?
* What experience do you want to provide?
* Is there something your app can make more convenient or less confusing/time-intensive?
* Why should a user choose your app over another?

**Write up User Stories**
* Who is going to use your app? What is your target audience?
* What exactly will members of that audience want to do with your app? 

**Draft a list of features**
* What features _make_ the app? What are the MVP (minimum viable product) features?
* What stretch features will you add if the MVP is completed ahead of schedule? 
* What features can you omit from the first version? What features will be added with subsequent releases of your app?

**Backend, pt. 1 - Schema, Models, and Associations**
* What models does your app need? What attributes do those models have?
* How are those models related? What associations are necessary to make these relationships work? 
* Create a detailed schema diagram.

**Backend, pt. 2 - `bin/rails console`**
* Write out seed data based on your user stories.
* Test associations in the Rails console. Be thorough and use the seed data to exercise your models & associations in a similar manner to how they'll be used in-app. 
* Make any changes to models or schema, if necessary.

**NOTE**: go **feature by feature** (i.e., build vertically).

**Frontend, pt. 1 - views**
* Make mock-ups (e.g., wireframes) of every page (or the most important ones, at least) your app will need. 
* Note how a user will get from one page to another, and consider a nav menu for getting to frequently-used pages quickly.
* Generate dummy views (e.g., a login form that isn't connected to the backend). 

**Frontend, pt. 2 - controllers**
* Generate controllers and routes needed for the feature you're working on. 
* Make the "dummy" views "smart" by grabbing and/or manipulating the data you need and displaying them to the user.

**DRY things up**
* Consider ways you can slim down your controllers by extrapolating logic into class/instance methods on models.
* Write helper methods for actions you perform repeatedly, such as grabbing the current user from the `session` user id.

**Finishing touches**
* Style your app, maybe using a framework or some simple HTML & CSS.

**NOTE**: I have yet to start writing tests. However, I plan on incorporating this into my development process in the future. As of now, I'm relying on manually testing stuff like models, views, &c. 

The aspect of the development process with which I had the most difficulty was creating the backend--namely, creating and associating models in a way that made sense for my app.

The (relatively) final version of my app ended up with 4 models: `User`, `Team`, `List`, and `Task`. 

Initially, though, I didn't have the `Task` model. I was trying to associate the remaining as follows: 
* User has_many lists and has_many teams through lists 
* Team has_many lists and has_many users through lists
* List belongs_to user and belongs_to team

That wasn't working because it didn't make sense for List to be the join-table, as it were, between User and Team. And building the association the other didn't make sense because a List can't **have_many teams**. No matter how I tried to make it work, it wouldn't--because that's not the relationship between these models "in real life." 

Outside the context of a Rails database, a User can work independently of a Team, as well as collaborate with other people. A person belongs to a Team, and the people on that team may be grouped into sub-teams (which I simplified into Lists) to work on different tasks. 

* A User (optionally) belongs to a team, has many tasks, and has many lists through tasks. The tasks are directly associated to the user because many different users can have assigned tasks on the same list.
* A Team has many users and lists, and has many tasks through lists. Tasks are associated through lists because a user may leave a team, yet the list is "stuck" to the Team and will still have the task (that was formerly assigned to the user).
* A List has many tasks, has many users through tasks, and belongs to a team.
* A Task belongs to a list and (optionally) to a user (allowing for tasks to be 'unassigned'). 

Structuring the relationships this way made much more sense and allowed me to proceed with considerably less confusion and headache. 

I knew designing the database was (arguably) the most important part of building the MVP, but I underestimated how much time I should spend brainstorming/planning/testing my models and associations. On my next project, I'll dedicate more time to this step of the process so that subsequent steps can progress smoothly.