My Sinatra Project — Pushing for Stretch Goals While Combining Frameworks (March 2020)

Harry Wilson
5 min readJul 13, 2020

--

This week I completed my first ever full-stack web application, Workout Swap. With my app, users can sign-up, login (if they input their credentials correctly) and then create, edit, delete, copy and even rate/report workouts. The app links to a database powered by Active Record so if the user logs out and then returns, their data is still available to them. Having already studied Object Oriented Ruby programming in depth for our first CLI project, the challenges here came in learning the Sinatra framework (my first ever framework), integrating dynamic routes and keeping track of a full-stack app (there are a lot more files this time!).

Photo by Ilya Pavlov on Unsplash

The app itself did not take too long to code. I setup my database by writing my migrations (which allows Active Record to write our SQL for us), setup my Models and their relationships (has_many or belongs_to or has_many_through) and then with the help of some Helper methods which I defined in yet another class (these were used to check the current user and to see if someone was logged in), I coded my controllers and view classes so that the app linked up nicely.

Once my app had met the basic requirements, I decided to look at the stretch goals. One goal was to setup Flash Messages in our app. Let’s say for example the user tries to log in and has not actually setup an account, the idea would be that a message flashes at the top of the screen and tells the user they need to sign up first and then you can click to dismiss the message. Having now spent a few months working with JavaScript at my internship, I knew exactly how I could implement this feature. However, I wanted to try and improve my knowledge of the Sinatra framework and see if there was a way to do this without JavaScript.

After a quick google search I saw there were a few gems which could help me and I ultimately decided on using Sinatra Flash. I installed the gem, added it to my gem file and entered ‘bundle install’ into my command line so I had access to all its features. One of the great things about the Sinatra setup is that our app has a main view file called layout.erb (the .erb stands for embedded ruby which allows you to type Ruby into an otherwise HTML heavy file using erb tags) which contains a yield block in ERB tags:

<%= yield %>

This feature means that every view file that you have coded will be placed in this yield block. This allows you to code, for example, a navbar in your layout file so that it appears above every view file’s content. A handy feature which also allows you to adhere to the DRY coding principle.

The Sinatra Flash gem gives you access to a hash which contains … FLASH MESSAGES (yeah it’s not super suprising haha). By placing the below code in your layout.erb file, you can have access to them on any page in your site! Note the fact that these ERB tags do not have an equals sign (=) in them. This is because we do not want the user to be able to see this code in the browser.

<% flash.keys.each do |type| %>
<div id=”flashMessage” data-alert class=”flash <%= type %> alert-box radius alert alert-<%=type%> alert-dismissible fade show” role=”alert”>
<%= flash[type] %>

<button type=”button” class=”close” data-dismiss=”alert” aria-label=”Close”>
<span aria-hidden=”true”>&times;</span>
</button>
</div>
<% end %>

Here we are iterating over each key within the flash hash (try saying that three times fast) and for each hash we are producing a div with various attributes as well as a button which will close the alert message. I want to come back to the ‘type’ which you see in ERB tags as this was some dynamic coding which I added later. How exactly do we access these messages you might be thinking? Well, that’s pretty simple, we access them just like we would any other hash! In our controller class, let’s say in this case we want a message to pop up when the user tries to log in without having signed up, we place the following code:

post ‘/login’ do 
user = User.find_by(username: params[:username])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
redirect to ‘/home’
else
flash[:danger] = “You need to have an account to Log In”
redirect to ‘/’
end
end

This is the POST request for our login form, so the data a user enters is sent here when they click the submit button. Our database will search for a user using the params hash (all data entered in the form is stored in a params hash and the keys match up with name attributes in our form) and store it here in a variable user. It checks they exist and checks their password matches the salted hash password in our system (generated by another gem ‘bcrypt’ and authenticated here thanks to some clever code in our User model) and if everything goes well, it sets that user as the current user for the session and sends you to the ‘/home’ route. We are interested in what happens when this is not the case. In our else block, we can see that we are accessing the flash hash and following the ‘=’ we enter the message as a string which we would like to appear! It really is that simple. So … why exactly did you choose to write danger as your key?

Remember I said I had coded the word ‘type’ into ERB tags for the classes which would be assigned to each Flash div on our layout.erb page. Well, another Framework I am using for this project is Bootstrap. Bootstrap allows you to assign class names to your HTML which give that element styling. In this case, I took advantage of the fact that there are certain class names which assign color to an element. In this case, ‘danger’ can be used to make an element red. Knowing that I want to see the above Flash message in red means that I can use the key [:danger] and when my Flash hash iterates through, it will take that and assign that as the type it’s iterating through, which makes it appear (thanks to those ERB tags) as a class name for that particular div element. So whenever I call a Flash message in my controller, I can choose to say ‘flash[:danger]’ or ‘flash[:success}’ or any other Bootstrap color class and my message will appear that way without me ever having to manually style each element! Another clever way to keep your code DRY.

This project has really taught me a lot. I’ve been exposed to full-stack application development for the first time, coded dymanic routes, my own helper methods, advanced my knowledge of SQL, Ruby, and even learned a new framework. The thing I am most proud of is that I have looked to always try and combine everything I know. When you use different frameworks and languages together, you can create something extremely powerful with very little code, keeping your application very DRY while also implementing advanced features!

--

--