PR Journal: MVC Sinatra Project
Phase 2 of my software engineering bootcamp at Flatiron School required us to build an MVC (Model View Controller) Sinatra Application with ActiveRecord. I created an application that allows you to log your PRs (personal records) for the most common gym weight exercises, with full CRUD (create, read, update, and delete) functionalities. This was an exciting assignment as this was the first time we created a website with style-able user interface… and maybe it’ll actually help me with my gym goals!
You can find the Heroku-hosted application here.
- Build an MVC Sinatra application.
- Use ActiveRecord with Sinatra.
- Use multiple models.
- Use at least one
has_manyrelationship on a User model and one
belongs_torelationship on another model.
- Must have user accounts — users must be able to sign up, sign in, and sign out.
- Validate uniqueness of user login attribute (username or email).
- Once logged in, a user must have the ability to create, read, update and destroy the resource that
- Ensure that users can edit and delete only their own resources — not resources created by other users.
- Validate user input so bad data cannot be persisted to the database.
- BONUS: Display validation failures to user with error messages.
My application allows users to signup or login to their account and view their recorded PRs. They can add new PRs, and view, update, or delete old ones. The name, date, and personal record fields must all be filled in to successfully submit a PR. Similarly, the first name, last name, email, and password fields must all be filled in to create an account. The program uses session cookies and stores the cookie in the browser to persist the user account; this allows the user to not have to sign in for every following request.
My full code can be viewed here.
The file structure for the app is as follows:
Controllers: I have an application controller, a workouts controller, and a sessions controller. Both the workouts and sessions controllers inherit from the application controller.
Models: I have a user model and a workout model, where the user
has_many workouts, and each workout
belongs_to a user.
Views: I created a homepage (welcome.erb) for the root domain. I also made sure to have a layout.erb to avoid having to repeat the common HTML for every .erb file. The sessions folder consists of a login and signup page. The static pages folder includes the About Us, Contact Me, and Terms & Conditions pages that are linked in the site’s footer. Lastly, the workouts folder has .erb files for the PR Journal list page, individual workout pages, adding a new PR form page, and an edit page.
Useful Resources and Gems
The following are just some of the gems I used that were incredibly helpful for my project:
This gem sets up the basic Sinatra MVC file structure for you and helps with easily setting up file dependencies. We learned that the creator of this gem is a fellow Flatiron graduate, which is pretty cool.
This provided me with the
has_secure_password macro that I added to the User model. This macro allowed me to add a column for
password_digest in the users table. I set up the input types for passwords as “password” in my forms to hide the password in the form instead of displaying them as texts. I also enabled sessions and set my session secret in the application controller to secure passwords.
Tux is similar to IRB, except with higher functionalities and added plugins to help with your development. Unlike IRB, Tux loads your Sinatra environment, which gives access to all your models, tables, and logic; this lets you directly interact with your project’s code, making testing and debugging so much easier.
This extension assists in displaying flash messages, which helped with incorporating our bonus requirement- error messages. I assigned different error message values to the hash key
flash[:errors depending on the error type, and displayed it in the layout if the value exists.
I feel like the most important learnings were about user workflow and being comfortable with the pathways each request would take. Therefore, the pre-coding planning process was important so that I was clear on what exactly I was trying to achieve with my application.
There are more features that I want to come back to and add to my PR Journal application. For example, it would be cool if I can prevent logging duplicate exercises for a single user and maybe even a forum section where users can interact with one another or share their PRs.