The End of the Line

Kellen May
5 min readMay 7, 2021

--

Well Rails, old friend. It was lovely seeing the world together, but our time is up. A great saying is “It’s not “good-bye”, but “see you later”. “

I have learned so much I these past few months and it really came full-circle with this project. I used tools from one of the first you labs in my project and I really thought those methods or practices would have been forgotten! I am grateful for all the struggles and the bugs that have been found, and the one’s I’m sure I will keep finding the more I fiddle with my application in the few days to come before I submit this final Rails project for good.

I think this is starting to turn into one of those articles where I teach you how to make a potpie, but first I need to tell you why I love potpies because when I was 7 I scraped my knee and I didn’t stop crying until I had a piece of grandmas “block famous” pot pie….

My project from a general perspective, is a song and playlist creation application. I provided the ability to add songs to a list that can be added upon instantiation of a playlist, but there is also a nifty way to add a song to a playlist that is already made after you make a new song!

As always lets start from the beginning of the application. Sign-in, or OAuth… Once we learned about this process I was like “Wow this is it. I am a programmer I can have people sign-in with their g-mail!!” So lets look at how this works.

def omniauthuser = User.find_or_create_by(uid: request.env['omniauth.auth'][:uid], provider: request.env['omniauth.auth'][:provider]) do |u|u.email = request.env['omniauth.auth'][:info][:email]u.password = SecureRandom.hex(15)endif user.valid?session[:user_id] = user.idredirect_to songs_pathelseredirect_to login_pathendend

The code above is my OmniAuth method in my SessionsController file. A few new words in here are uid, provider, and request.env. A UID is a unique ID based off the ‘provider’. The provider here would be ‘google’ since we are using g-mail, and the request.env is a ruby array that contains information about a visiting user’s and server environments located in the .env file. Speaking on that .env file it is very important to not push that up to your github repo. You can do that by adding ‘.env’ into your .gitignore file in your project. The .env file contains your CLIENT_ID and CLIENT_SECRET. We would be exposing our entire userbase to potential security breeches if we allowed that up to the repository.

Since I explained a regular login request for my previous project I think we can skip over that part, and move on to how users can actually be able to make playlists and songs, and how they are able to communicate! This all happened with the magic of Rails and in our Models of the M of our MVC. Our models are responsible for interacting with our database. While I’m at it I will also explain that a controller is responsible for handling the request from a HTTP, then determine which controller and method to direct to. It starts with a ‘get’ request, and if the controller needs to use a view, which is responsible for sending data to our controller. In your view you have your forms, which is a very important part of creating a key: :value pair to instantiate data for an object.

Looking back to the models for my project. We can see how the model interacts with the database through ActiveRecord methods.

class PlaylistSong < ApplicationRecordbelongs_to :songbelongs_to :playlistendclass Playlist < ApplicationRecordbelongs_to :userhas_many :playlist_songshas_many :playlist_usershas_many :playlists, through: :playlist_usershas_many :songs, through: :playlist_songs
accepts_nested_attributes_for :playlist_songs
end

I am showing two of my models to show what we can actually get from the ActiveRecord associations… The first code shown above is what is known as a “join table” meaning it is used to join to allow relationships between two classes that wouldn’t be able to other wise. With a belongs_to relationship we can use a :key for each class playlist and playlist_song and then reach through the table by use of one :key seeing another and recognizing its existence. About half way down the code below we can see that I can call PlaylistSong.create and give it the properties of playlist_id and song_id.

def create@playlist = Playlist.new(playlist_params)@playlist.user_id = current_user.idif @playlist.saveplaylist_params[:song_ids].each do |song|if song != ""PlaylistSong.create(playlist_id: @playlist.id, song_id: song)endendredirect_to playlist_path(@playlist)elserender :newendend

With these associations we can also post things to our view pages. By joining the two tables we can use each database when inside each others views.

One of the harder requirements for me was, this project was having to make nested routes. While the actual syntax to make the paths for a nested route is easy…

resources :playlists doresources :playlist_songs, only: [:index, :new, :create]      resources :playlist_users, only: [:new, :create, :edit, :update, :destory]end

It’s what came after that proved to be difficult, and knowing what I know now I would have named things differently because when you call paths like

url: playlist_playlist_users_path(@playlist)

it can get confusing very fast. Another thing to note with this project is the use of ‘s’. Index pages are users_path , but a show page needs an argument and to also not be plural so user_path(@user) I think it could have been a lot neater had I planned a liiiittle further ahead.

So here comes the nested routes full-form. It is most beneficial for a nest route to be a join_table in my experience. Had hours and hours of headaches these past two weeks trying to get has_many relationship to do things it is just not meant to do. So I have my nested route as playlist/:playlist_id/playlist_list/new yea I know… messy I told you. I’ll quickly show you the form and then explain what its doing for us.

<%= form_with model: @playlist_song, url: playlist_playlist_songs_path(@playlist) do |f| %><%= f.hidden_field :playlist_id, value: @playlist.id%><%= f.collection_select(:song_id, Song.all, :id, :title, prompt: true) %><%= f.submit %><%end%>

So here we are in our playlist_songs/new file, which we see is a nested route, we will have @playlist defined already and only need to call the id to be able to set it to theplaylist_id param. Song is a little different, but since playlist_songs belongs_to song as well we can just iterate over @song.all and select the song based off it’s id and set it to the song_id param.

Rails is said to have a lot of magic behind it, and as someone that is new to programming only starting here at FlatIron School, I will have to say I believe in magic. As with every journey we know it must come to an end. With the submission of this blog for my last project using Ruby on Rails, I think this is the end of the line.

--

--

Kellen May
Kellen May

Written by Kellen May

0 Followers

current software engineering student with flatiron here to document my progress

No responses yet