Music Review Rails Project

Ernesto Ramirez
8 min readMay 8, 2021

For my third project at Flatiron School I needed to develop a Rails application almost from scratch. I decided to take my love of music and implement it within the project to develop a music review app.

Overview

This app provides user sign up, login, logout, password encryption and provides the option for users to login or signup with Google and GitHub. Users are able to add artists as well as their associated albums with the songs within their albums. Users will then be able to review these different types of media individually on a scale of 1–5 along with content to complete their review. If a user really likes any of the 3 types of media available then they will have the option to add it to their favorites. Once a user goes to their profile they’ll be able to update their profile information(username, email, password) and they’ll be able to link their social accounts with their profile(Google, GitHub). Each time a user reviews a piece of media it’ll be added to their reviews and any other user could view their reviews via a link on their profile. This concept is the same when a user favorites a piece of media as well.

Models & Associations

Models List w/ Concerns

The models folder includes models of an album, artist, favorite, identity, medium, review, song, user and application record. Within the models folder includes concerns for that are included in each media model(artist, album, song) that defines if a type of media is favorable, reviewable and usable.

Artist Model

The artist model includes all the modules in the concerns folder. It also has the associations of has_many :albums and has_many: songs, through: :albums. This model also builds its parents(medium), this method is made available through the usable module, before it validates in order to have a medium id since it is a type of media. It then validates it’s medium and title(name). There’s a scope method that allows the artists names to be viewed in alphabetical order on the artists index page. Finally, there is a children method that defines an artists children(albums). The other media models(album, song) are essentially the same with minor tweaks to satisfy the models needs. They can be viewed below.

Album Model
Song Model

Database

Schema

Each model that I’ve made has been included here in my database(the medium model was associated with the media table upon generation). Each model, except the identities and medium, has a medium id since the medium keeps track of each type of media along with their reviews and favorites. Foreign keys have been added in various tables in order to create associations within the database.

Schema

Controllers

Controllers List

The controllers handle most the logic within the app. It deals with creating, showing, deleting, and updating instances of media, reviews, favorites, users, and sessions. It also handles redirects to new routes and associates with the database whenever something needs to be found or created.

Artists Controller

The artists controller sets the artist before doing anything else in order to show the artist being viewed. The index method includes the artist alphabetical scope method, seen in the artist model, to order the artists names in alphabetical order. There is also reviews that are shown in the index page, but the scope method .latest_reviews only shows the last 3 reviews that have been created. The create method creates an artist with the artist strong params as an argument. It redirects to the artist path that has been created, but if there are any errors it returns to the create artist page with the errors being shown. The album and song controllers are similar with minor tweaks to satisfy their needs. They can be viewed below.

Albums Controller
Songs Controller

Views

Views List

My views handle all the rendering and layouts within my app. My media folder within my views includes a majority of the partials that I’ve made that are rendered throughout the rest of my views folders. This prevents me from having to repeat code which leaves my folders less cluttered and improves my work flow and efficiency. There is some logic that is included in my views, but it is only used to iterate through objects and determines what is being shown based on certain requirements.

_children.html.erb

The children partial determines if a type of media has any children. For example, if an artist has any albums then it’ll render the albums that an artist has with a link to each album. If the artist has no albums then it’ll render a message saying that the artist has no albums.

_index.html.erb

The index partial shows the artists index page that iterates through each artist to show their names with a link that redirects to that artists review page. If a user is logged in a message will be rendered that’ll allow a user to add an artist to the index page. This message is written in another partial that we’ll look at soon. If a user is not logged in then a message will show that tells the user to log in or sign up to add an artist.

_parent.html.erb

The parent partial checks to see if a piece of media has a parent. For example if an album has an artist a message will display that the album belongs to the artist. A link will be on the artists name that’ll redirect back to that artists review page and show their other albums.

_prompt_new.html.erb

The new prompt partial checks if a user is logged in. If a user is logged in then a message will be displayed to add a media type. For example, if a user was logged in and wanted to add a new song, they would click on the link which will redirect them to the new path for the media. If the user is not logged in then a message will be displayed to log in or signup to add a certain media.

_show.html.erb

The show partial shows a medias reviews, a review form, a favorite button and an option to add new children to the media. If the media has no reviews then a message will render saying that the media has no reviews. If the media does have reviews then all the reviews will render with their content, rating, and the user who rated the media with a link to their user profile. If a user is logged in they’ll have access to a review form that include a text box for content and a drop down box for a rating from 1–5 with a submit button. It’ll also render the favorite button for a user to add the media to their favorites. If the user is not logged in then a message will be displayed to log in or sign up to add a review. If the medias class name is not song then it’ll render the children for the other media with the new prompt partial. Finally, the parent partial will render at the end to show the medias parents.

Omniauth

Omniauth

In order for users to log in or sign up using Google or GitHub I used Omniauth for the two providers in order to make that task possible. I received the client id’s and client secrets from both providers and used them as ENV variables in order to be able to use Omniauth.

Routes

These routes are used to build redirects through out my website. They let the user flow through the application and access certain pages through nested resources.

Root

The root of the app is ‘static#home’ which is just a welcome page that the users first see.

User Routes

The user routes include the signup route which is a get request that is aliased as ‘users#new’. This uses the users resources but only includes the show, update and create pages for the user. Within the user resources includes resources for reviews and favorites that only includes their index pages. Below the users nested resource include the remaining resources for reviews and favorites. The reviews include create, edit, update and destroy pages. The favorites include create and destroy

Media Routes

The media resource only includes the media show page. The nested artist resource includes the index, new, create and show page. Within these pages includes the albums nested resource which includes the new page. Within the new album page includes the new song page. Outside of the nested artist resource includes the albums and songs resources that have their associated create and show pages.

Session Routes

The session routes have a get route for logging a user in which is aliased as ‘sessions#new’ and a post route that is aliased as ‘sessions#destroy’. There is also a resource for sessions that has the create route.

Omniauth Routes

The omniauth route just has a get request that goes to the providers page in order for a user to use either Google or Github to log a user in or sign up them up with either social account. It is aliased as ‘sessions#omniauth’.

Fallback Routes

The fallback route has a get request to the root of the app.

Conclusion

Throughout the creation of this app there were lots of highs and lows, but overall it was a great learning experience. I had fun turning my vision into a reality and along the way learned new things that helped improve my app.

Here is a link to my apps GitHub repository.

--

--