Sinatra Project- ActiveRecord Validation/Rack Flash insights!
Tags: flatironschool, sinatra, validation, rackflash
Published: 2020-11-27 21:28:25

I recently completed my Sinatra MVC CRUD project at Flatiron School. I created a Study Session Tracker website. 

This website has login, signup and logout functionality for users. The website allows users to create study lists for a topic (ex. Ruby, Javascript, etc.) that they forsee they'll be studying. The user can then create completed study sessions they've done that go onto a specific study list for a topic. They can also edit and delete these study sessions. 

I also added into my project ActiveRecord validations and display of validation failures in the views to users. 

The flow I took to set up ActiveRecord validations as well as Rack Flash to display failure messages to users was: 

-Put `gem "rack-flash3"` in the gem file and then run `bundle install`. 
-Require "sinatra" and require "rack-flash" in the controllers in which you want to validate user input. 
-Put `enable :sessions` in the configure block of your ApplicationController and `use Rack::Flash` under the class definition of the controllers in which you want to validate user input. 
-Put specific ActiveRecord validations in the models for certain model attributes you'd like to validate user input for. 

The above steps will get you ready to validate user input. 

From here, to further demonstrate how an ActiveRecord validation works, I'll walk you through a challenge I was having in this project in finding and implementing a certain validation. 

One of the challenges I was having was to get an ActiveRecord validation that'd make it so a user could not create multiple study lists with the same exact topic. I didn't want a user to be able to have multiple study lists titled "Ruby" for instance, but instead I wanted all of a user's study lists to have unique names (ex: Ruby, Javascript, React). 

Once the steps prior had been set up, this is the code I wrote in my StudyListsController and my StudyList model to get this validation working: 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/g9cxwco0qv3xycyo2xuk.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/1sgorfcl1j0s4xn1y919.png)

Line 5 in the StudyList Model is the model validation that I used for this. The ActiveRecord `validates_uniqueness_of` validation, along with the scope parameter that follows, validate whether the value of the specified attributes are unique based on a scope parameter. 

According to my model associations, a study list belongs to a user, thus, each study list created has a user_id foreign key associated with it. Since study lists have access to their user_id, I used the user_id as the scope parameter. 

`validates_uniqueness_of :topic, scope: :user_id`

This code is basically making it so that a topic can only be used once for a particular user_id when a new study list is being created. 

The above picture of code for the `post "/studylists"` route, my controller action that creates new study lists for users, works to properly implement the validation like so: 

-I first make a new study list with the user input for topic that I have gotten from the params hash, along with setting user_id equal to the current user's id (the current_user variable comes from a helper method that finds the current user). I use .new so that the study list is not saved to the database yet, because I want this data to have been validated before it would possibly hit the database. 

-Then I have an `if @studylist.save`. If `@studylist` saves, this means that the input I received in the params hash from the user passed the validations on the StudyList model. If any of the validations on the StudyList model fail, `.save` is cancelled and will return false, and thus will not save `@studylist` to the database. 

-The code after the `else` is what will happen if `@studylist` is not saved. A flash message is a way to let your users know what happened after an action they took on your website. I set `flash[:message]` to the message I want the user to see. This way they will know exactly how to correctly create a new study list. 

-In this else statement I also redirect them to the form for creating a new study list. This way, if their new study list submission fails, the page they are on with the fill-in form immediately reloads and then on the page they see the error message that I set `flash[:message]` to.

-The final part I implemented for this validation was to make sure that users would see the error message I set flash[:message] to, in case of the validation on the model failing. The extra bit of code I put in my view file that has the form for a new study list was the following from line 16-18:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/jn15a6ogiyxn9bxyyczs.png) 

This code displays the flash[:message] you defined to the user when applicable. The flash message will then stay there until the user goes to another page. 

ActiveRecord validations are great for keeping bad data out of your database. Rack Flash, when used in conjunction with these ActiveRecord validations, is great for helping you to display informative messages to users based on their actions. 

I hope these insights on my recent experience using ActiveRecord validations and Rack Flash might be able to help someone in some way!