<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ryan Erricson</title>
    <description>The latest articles on DEV Community by Ryan Erricson (@rickysonz).</description>
    <link>https://dev.to/rickysonz</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F576518%2F3d0a47bb-eb2a-4f43-809a-add334bd0000.jpg</url>
      <title>DEV Community: Ryan Erricson</title>
      <link>https://dev.to/rickysonz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rickysonz"/>
    <language>en</language>
    <item>
      <title>Conditionally Rendering Material UI Alerts in ReactJS/ ReduxJS</title>
      <dc:creator>Ryan Erricson</dc:creator>
      <pubDate>Sat, 03 Jul 2021 16:20:37 +0000</pubDate>
      <link>https://dev.to/rickysonz/conditionally-rendering-material-ui-alerts-in-reactjs-reduxjs-34ce</link>
      <guid>https://dev.to/rickysonz/conditionally-rendering-material-ui-alerts-in-reactjs-reduxjs-34ce</guid>
      <description>&lt;p&gt;Starting a React project and looking for a way to conditionally render error messages with user forms? One approach I recommend taking is utilizing Material UI's alert system, while leveraging a redux state of user error. If this state is ever set, then you can conditionally render an error message in your component. There are a few nuances to this approach so pay attention carefully, also this blog assumes you are comfortable with ReactJS and Redux and have already created a React App. I am using a Ruby On Rails back end but as long as you are getting JSON promises back, this method should work for you. We will be doing the set up for flexible User Login Errors.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Install Material UI's Necessary NPM Packages
&lt;/h2&gt;

&lt;p&gt;Utilize the commands below in your terminal to do so.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install @material-ui/core
npm install @material-ui/lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With those two commands you have access to many Component classes that are in Material UI. &lt;/p&gt;

&lt;h2&gt;
  
  
  2. Set Up Reducer to Update Redux Store
&lt;/h2&gt;

&lt;p&gt;So now your reducer needs to tell your Redux Store, when to update, and what to update the store with. I set mine up in my SignInReducer which in this project is my reducer for users.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;case 'USER_ERROR':
            return {...state, error: action.payload}

        case 'REMOVE_ERROR':
            return {...state, error: {}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Set Up Your Dispatched Actions to Work with Reducer
&lt;/h2&gt;

&lt;p&gt;Wherever you define your actions for the errors you are trying to display depends mostly on what the error messages are displayed for. Since this example is for user login we will put them in the user actions file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const authError = e =&amp;gt; ({
    type: 'USER_ERROR',
    payload: e
})

export const removeError = () =&amp;gt; ({
    type: 'REMOVE_ERROR'
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have the ability to call an action and pass an argument to it to set an error in the Redux store, and we also have a method to call when we want to get rid of the error message. &lt;/p&gt;

&lt;h2&gt;
  
  
  4. Call Dispatch Action During Login Action
&lt;/h2&gt;

&lt;p&gt;The process now is to call this action when a user logs in, and if there is an issue with their login (incorrect username or password) then the back end will pass the error message back. You need to ensure that your back end is also set up to do this, so for example I put custom conditionals to take care of this on my Ruby on Rails back end. This action is fired to my sessions controller to create a new user. The part to look at is the elsif and else conditions as they handle the error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def create

        @user = User.find_by(username: params[:user][:username])

        if @user &amp;amp;&amp;amp; @user.authenticate(params[:user][:password])
            @token = encode_token(user_id: @user.id)
            render json: {
                user: {
                id: @user.id,
                email: @user.email,
                username: @user.username,
                password: @user.password,
                logged_in: true
            },
        token: @token,
    status: 200}
        elsif @user
            render json: {
                status: :unprocessable_entity,
                error: "Wrong Password"
            }
        else
            render json: {
                status: :unprocessable_entity,
                error: "Username Not Found"
            }
        end
    end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now set up your login action to handle this error message that gets passed back. It is easiest to have the conditional set to check for the data status to equal 200. If that status is not 200, the dispatch action we created in step 3 will be called and set the Redux store error to whatever the back end passes back.&lt;/p&gt;

&lt;p&gt;Try logging in with incorrect username and password and look at your Redux tool. It should be telling you that the Redux Store under User(if you combined multiple reducers), there should be a state of error set to what your back end is passing back. If you did not combine reducers it should just be under a state of error.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Set Up Access To State in Component
&lt;/h2&gt;

&lt;p&gt;To access your state in a class component set up your mapStateToProps as such. You probably need to reference other state in the login, but thats all you need for this error message.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let mapStateToProps = (state) =&amp;gt; {
    return ({error: state.signInR.error})
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Functional components should use useSelector method in order to access the state of error as such. signInR is how I reference the correct reducer in my rootReducer, if you do not use combined reducers just use state.error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const error = useSelector(state =&amp;gt; state.signInR.error)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  6. Conditionally Render Alerts Based on Error State
&lt;/h2&gt;

&lt;p&gt;Before anything make sure that you import the Alert Component from Material UI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Alert from '@material-ui/lab/Alert';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then from there set up your return statement to render with an alert if there is a state of error that is longer than 0. Below is an example from my recent project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;render() {
        if(this.props.error &amp;amp;&amp;amp; this.props.error.length &amp;gt; 0){
        return (
            &amp;lt;div className="sign-in-div"&amp;gt;
                &amp;lt;form className = "sign-in-form" onSubmit={this.handleSubmit}&amp;gt;             
  &amp;lt;Alert key={Math.random(100000)} severity="error"&amp;gt;
    {String(this.props.error)}
  &amp;lt;/Alert&amp;gt;
                    &amp;lt;h1&amp;gt;Login&amp;lt;/h1&amp;gt;
                    &amp;lt;input type = "text" placeholder = "Username" name="username" value={this.username} onChange={this.handleChange}/&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/br&amp;gt;
                    &amp;lt;input type = "password" placeholder = "Password" name="password" value={this.password} onChange={this.handleChange}/&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/br&amp;gt;
                    &amp;lt;input type= "submit" value = "Login"&amp;gt;&amp;lt;/input&amp;gt;
                &amp;lt;/form&amp;gt;
                &amp;lt;Link to="/register"&amp;gt;Dont' Have An Account?&amp;lt;br/&amp;gt;Register Here&amp;lt;/Link&amp;gt;

            &amp;lt;/div&amp;gt;
        )} else {
            return(
                &amp;lt;div className="sign-in-div"&amp;gt;
                &amp;lt;form className = "sign-in-form" onSubmit={this.handleSubmit}&amp;gt;
                &amp;lt;h1&amp;gt;Login&amp;lt;/h1&amp;gt;
                    &amp;lt;input type = "text" placeholder = "Username" name="username" value={this.username} onChange={this.handleChange}/&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/br&amp;gt;
                    &amp;lt;input type = "password" placeholder = "Password" name="password" value={this.password} onChange={this.handleChange}/&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/br&amp;gt;
                    &amp;lt;input type= "submit" value = "Login"&amp;gt;&amp;lt;/input&amp;gt;
                &amp;lt;/form&amp;gt;
                &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure to check for the length to be greater than 0 and also to check if the state exists, or you may keep rendering an error message with an empty object.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Removing Error Upon Component Unmounting
&lt;/h2&gt;

&lt;p&gt;So the last part is that you need to ensure that when the component unmounts the error will be deleted. If not then the component may try to rerender an unnecessary error message when the component rerenders or crash your application.&lt;br&gt;
For class components, when your SignInForm unmounts just call the removeError action from step 3. You will need to set up mapDispatchToProps to handle this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;componentWillUnmount = () =&amp;gt; {
        this.props.removeError()
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a functional component, just call it as a cleanup function in a useEffect hook.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useEffect(() =&amp;gt; {
        return () =&amp;gt; {
            dispatch(removeError())
        };
    }, []);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  One More Note on Styling
&lt;/h2&gt;

&lt;p&gt;I found that the easiest way to not make your Alert component take up the entire width of the component it is called in is just by calling styling on the component and setting its width to a percentage. There are a few other ways to override styling like justifyContent can move where the text is and changing margins will change where on the page the error message will display.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Alert key={Math.random(100000)} severity="error" style={{width:'80%'}}&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is all you should need to be able to render error messages from Material UI's Alert component. This is not the most complete or robust implementation for this component, however, for new developers I found this to be the easiest approach that makes sense. Hope this helps you make some awesome applications that can give your user some level of feedback!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Using React-Leaflet with a React/ Redux Application</title>
      <dc:creator>Ryan Erricson</dc:creator>
      <pubDate>Fri, 25 Jun 2021 20:56:39 +0000</pubDate>
      <link>https://dev.to/rickysonz/using-react-leaflet-with-a-react-redux-application-3983</link>
      <guid>https://dev.to/rickysonz/using-react-leaflet-with-a-react-redux-application-3983</guid>
      <description>&lt;p&gt;When I first started my ReactJS project, BrewDog, I heard the horror stories of writing poor code when using Google Maps Javascript API, and wanted a free resource for rendering maps. I wanted to be sure I would not get a random bill for thousands of dollars from Google, so if you're trying to create a React app and want to have a completely free mapping service, look no further than React-Leaflet! It's an easy way to display a map in a React Component and render it with whatever information you want to use from your application's state. This post will give you step by step instruction on implementing React-Leaflet. These instructions assume you are comfortable with Javascript, React, and Redux concepts and also assumes you have set up your application through&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;create-react-app (your project name here)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So first things first let's set up our project to be able to create a map.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1. Install Required NPM Packages
&lt;/h2&gt;

&lt;p&gt;First thing you need to do is run the following command in your terminal to ensure your have the required node packages installed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install react react-dom leaflet react-leaflet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2. Add Script Tag and CSS Link to index.html
&lt;/h2&gt;

&lt;p&gt;Add the stylesheet link in the header of your index.html file FIRST!!!!!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;lt;link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
   integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
   crossorigin=""/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next add this script tag below where the stylesheet link was added (still in the header of your index.html).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;lt;script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"
   integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
   crossorigin=""&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3. Revise Package.json
&lt;/h2&gt;

&lt;p&gt;You will need to do this so that Leaflet is compatible with your browser, when working with Chrome. Go into package.json and make the following changes.&lt;/p&gt;

&lt;h4&gt;
  
  
  Before
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; "browserslist": {
   "production": [
      "&amp;gt;0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
},
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  After
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"browserslist": [
   "&amp;gt;0.2%",
  "not dead",
  "not op_mini all"
],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4. Create Map.js file and Import Necessary Components
&lt;/h2&gt;

&lt;p&gt;Create a new file in your src/components folder called Map.js and put the following lines at the top.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import { connect, useSelector } from 'react-redux';
import { MapContainer, TileLayer, Marker, Popup, useMap } from 'react-leaflet'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5. Create a Map Component to Hold Leaflet Map
&lt;/h2&gt;

&lt;p&gt;Below is an example of how I created a component in one of my applications. YOU NEED TO SPECIFY THE HEIGHT IN PIXELS OR IT WILL NOT RENDER ON THE SCREEN!!! Personally I find it much easier to style this map inline but you can do it in an external stylesheet if you prefer!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
Const Map = () =&amp;gt; {
return (
              &amp;lt;div id="mapid"&amp;gt;
             &amp;lt;MapContainer center={[39.809860, -96.555183]} zoom={4} scrollWheelZoom={false} style={{
                      height:"650px",
                      width: "900px"
                  }}&amp;gt;
                &amp;lt;TileLayer
        attribution='&amp;amp;copy; &amp;lt;a href="http://osm.org/copyright"&amp;gt;OpenStreetMap&amp;lt;/a&amp;gt; contributors'
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
      /&amp;gt;

            &amp;lt;/MapContainer&amp;gt;
            &amp;lt;/div&amp;gt;
                   )};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 6. Handling Centering and Zooming Upon Changes in State
&lt;/h2&gt;

&lt;p&gt;So a really tricky aspect of using Leaflet is making your map rerender properly upon changes in state. If your map is zoomed into one location upon the first render, the map will not adjust if you want it to rerender on a different location. So create this functional component here to pass to your MapContainer. This functional component needs to be declared OUTSIDE of your map component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function ChangeView({ center, zoom }) {
  const map = useMap();
  map.setView(center, zoom = 12);
  return null;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Below your MapContainer opening statement, and above the Tile Layer component call this functional component with the new center or zoom attributes you would like your map to refocus on. &lt;br&gt;
For Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;lt;MapContainer center={[searchedBreweries[0].latitude, searchedBreweries[0].longitude]} zoom={12} scrollWheelZoom={false} style={{
                            height:"700px",
                            width: "900px"
                        }}&amp;gt;
                        &amp;lt;ChangeView center={[searchedBreweries[0].latitude, searchedBreweries[0].longitude]} /&amp;gt;
    &amp;lt;TileLayer
      attribution='&amp;amp;copy; &amp;lt;a href="http://osm.org/copyright"&amp;gt;OpenStreetMap&amp;lt;/a&amp;gt; contributors'
      url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
    /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  You're Done!
&lt;/h2&gt;

&lt;p&gt;After following those steps you should be all set and ready with your map, and having it rerender as needed. You will have to put conditional clauses on how this component returns if it is relying on your state to do things such as place markers on the map. Multiple if else statements above your return clause such as the example below allow you to do this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if(* state exists *){
    return(
      &amp;lt;div id = "mapid"&amp;gt;
    &amp;lt;MapContainer /&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But other then that this guide should have you with a fully functional and FREE Leaflet map.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Accessing Nested Resources Through Fetch Requests</title>
      <dc:creator>Ryan Erricson</dc:creator>
      <pubDate>Thu, 27 May 2021 20:53:45 +0000</pubDate>
      <link>https://dev.to/rickysonz/accessing-nested-resources-through-fetch-requests-with-a-has-many-through-relationship-op9</link>
      <guid>https://dev.to/rickysonz/accessing-nested-resources-through-fetch-requests-with-a-has-many-through-relationship-op9</guid>
      <description>&lt;p&gt;My fourth project for FlatIron was the most challenging so far, but learned so much about JS and working with a back end server. In this blog we will review a way that to access nested resources and manipulate an API's JSON responses to retrieve specific nested data to present with JS in the front end of the program. &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NnzllLQw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tn2fslxv9zti1fqafh2i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NnzllLQw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tn2fslxv9zti1fqafh2i.png" alt="Screen Shot 2021-05-27 at 4.21.37 PM"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PfRhZeyD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eikvq1zyrh3pn7ruph3k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PfRhZeyD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eikvq1zyrh3pn7ruph3k.png" alt="Screen Shot 2021-05-27 at 4.22.25 PM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Schema in Rails
&lt;/h4&gt;

&lt;p&gt;Library has many Songs through Liked Songs&lt;br&gt;
Songs have many Libraries through Liked Songs&lt;br&gt;
Liked Songs belong to Library/ Song&lt;/p&gt;

&lt;p&gt;The schema in Rails says that this Liked Song does not have any attributes of a Song like name, artist, etc. as it is purely a relationship table on the back end. But when looking at the JS class that is Liked Song it does include all of those attributes. This is made possible because of Rail's ability to render JSON that includes nested resources as well as the new ES6 Classes and Constructor in Javascript. &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aZ1Q3e9l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wyf7gno6ml0pyf7motpo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aZ1Q3e9l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wyf7gno6ml0pyf7motpo.png" alt="Screen Shot 2021-05-27 at 4.27.46 PM"&gt;&lt;/a&gt;&lt;br&gt;
By utilizing &lt;strong&gt;(json: -&amp;gt; include())&lt;/strong&gt; rails will pass back not only the Liked Song relationship information but also the song information that is nested. Basically, in Rails the way we constructed the JSON response for Liked Songs will always have Song information nested in it.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8P9Sv29G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4mc4n3dtuxbts4rsuicl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8P9Sv29G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4mc4n3dtuxbts4rsuicl.png" alt="Screen Shot 2021-05-27 at 4.30.55 PM"&gt;&lt;/a&gt;&lt;br&gt;
When a JSON response comes back, this function iterates through the Liked Song INDEX array and pulls the Song value from these Liked Songs. The front end knows to do this because when iterating through the song attribute hash is being called on in &lt;strong&gt;object[i].song&lt;/strong&gt;. object is a variable for the JSON response and object[i] calls that instance in the iteration. Then the Song value is pulled by &lt;strong&gt;calling the .song attribute on the response.&lt;/strong&gt; &lt;br&gt;
The front end then instantiates new instances of a Liked Song from the Song information in this response, as the constructor parameters are satisfactory for a new Liked Song. It is key to remember that with a Rails API you are controlling this information that comes back to your front end through the render at the end of your controller method. If you initialize Rails models and controllers through &lt;code&gt;rails generate&lt;/code&gt;, they will not automatically render these nested resources even if relationships were set properly upon migration. &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UoBuDfcU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y9wurhfzxptwzznhvej8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UoBuDfcU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y9wurhfzxptwzznhvej8.png" alt="Screen Shot 2021-05-27 at 4.33.31 PM"&gt;&lt;/a&gt;&lt;br&gt;
One other key thing to keep in mind is where the fetch calls are being sent, and if your routes are set up properly to handle this. In this project I left Liked Songs under Libraries which were under Users. Ensure that you make the fetch call to the right route and with the proper method in order to end up rendering your desired nested resources. &lt;strong&gt;Saving data such as IDs to simulate a logged in experience is possible through using Local Storage and Session Storage.&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yd6NFUpW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c9j9fhgv1fzm5c1vx9an.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yd6NFUpW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c9j9fhgv1fzm5c1vx9an.png" alt="Screen Shot 2021-05-27 at 4.44.58 PM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kz0C5cHo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/02mzl0m3vd9ftpqxwbui.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kz0C5cHo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/02mzl0m3vd9ftpqxwbui.png" alt="Screen Shot 2021-05-27 at 4.42.26 PM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At this point it really is up to the developer how they want to utilize and present this information from this relationship map. For example, my application was essentially a mock Spotify Library, and if a Song was liked by a User, it would re-render all of the Liked Songs in the library so that it would include the new Liked Song. Another example could be an apartment finding site where a User class can like an Apartments Class that is kept track of in LikedApartments Class. When passing back a Liked Apartment, you can also pass the Apartment info.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pfmylk9u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n88ay62un3v7lv8rypwg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pfmylk9u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n88ay62un3v7lv8rypwg.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Two Objects, Yet So Many Relationships</title>
      <dc:creator>Ryan Erricson</dc:creator>
      <pubDate>Fri, 30 Apr 2021 17:12:18 +0000</pubDate>
      <link>https://dev.to/rickysonz/two-objects-yet-so-many-relationships-4jnf</link>
      <guid>https://dev.to/rickysonz/two-objects-yet-so-many-relationships-4jnf</guid>
      <description>&lt;p&gt;Rails was by far the most challenging part of the Flatiron Course for me so far, but after completing my project my understanding has grown vastly. Ruby on Rails allows us to create multidimensional relationships between two objects in a really easy way. The use of partials help render the proper forms to submit data based on whether a relationships currently exist. In my case, I delved into two different relationships between my User Object and my Jobs Object. &lt;/p&gt;

&lt;h2&gt;
  
  
  Models
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fegun6ev74hpkra7fclfg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fegun6ev74hpkra7fclfg.png" alt="image"&gt;&lt;/a&gt;&lt;br&gt;
 &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmtvr7l8nutvv22qto2c4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmtvr7l8nutvv22qto2c4.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  User_Job
&lt;/h2&gt;

&lt;p&gt;The first relationship to explain here is the has_many through user_jobs relationship. The User can have many jobs through user jobs and vice versa. There are also boolean attributes that can indicate whether a User is, in this case, interested or has "applied" to this job. * Also to be clear this would have been easier to understand in hindsight if I called this relationship something like interests.&lt;/p&gt;
&lt;h2&gt;
  
  
  Schema of Related Tables
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvg5kmzakle31x6ldfq1e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvg5kmzakle31x6ldfq1e.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Rendering With Partials
&lt;/h2&gt;

&lt;p&gt;This relationship is used to create an interest field at the top of the Job objects show field. This is done through partials rendered depending on this following code&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;&amp;lt;% @user_job =  @user_jobs.find_by(job_id: @job.id, user_id: current_user.id)%&amp;gt;&lt;br&gt;
&amp;lt;%= render :partial =&amp;gt; "/user_jobs/edit", locals: {user_job: @user_job} %&amp;gt;&lt;br&gt;
&amp;lt;% else %&amp;gt;&lt;br&gt;
&amp;lt;% @user_job = UserJob.new %&amp;gt;&lt;br&gt;
&amp;lt;%= render :partial =&amp;gt; "/user_jobs/new", locals: {user_job: @user_job} %&amp;gt;&lt;br&gt;
&amp;lt;% end %&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Based on this function the application will render a partial to either create a new relationship between User and Job or edit an existing relationship. &lt;br&gt;
 &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqt6qb6z10gd6rqt09z9w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqt6qb6z10gd6rqt09z9w.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once that form is submitted the User_Job_Controller determines whether the params passed through are valid to update the database. The create and update are almost identical so I only show create here.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbh0e1h0gjqcyeogcb3tj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbh0e1h0gjqcyeogcb3tj.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Reviews: Need For Relationship Independence
&lt;/h2&gt;

&lt;p&gt;After getting this set up though, reviews was the next step and I did not want anytime a User says their interested/applying to a job that this would inherently establish a review as well. When it comes down to it on any job posting site, reviews left for a job should function independently of a User being interested in a job.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reviews Model
&lt;/h2&gt;

&lt;p&gt;This is where I had to build in a reviews model. A User and a Job can have many reviews but a review can only belong to one User and one Job. This relationship is a little more simple than the previous model. Here a User can have many reviews, a Job can have many reviews, but a Review belongs to a job and a user.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Friucrl4s3hkvt1sahwsm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Friucrl4s3hkvt1sahwsm.png" alt="image"&gt;&lt;/a&gt;&lt;br&gt;
 With that established now all that was needed was to make the resources to be able to CRUD these reviews. On top of that a User should be able to leave a review at the bottom of a Job show page. Utilizing a nested new form I am able to give the user the ability to submit that nested review. The nested form utilizes this function below that basically says "Hey! If there is an instance of job associated with the new review being written on this page, do not allow the user to select another job to associate this review with!". As you can see below if there is no associated job than a dropdown will allow you to choose. &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6nx8bc6ioc0e0gajlwy1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6nx8bc6ioc0e0gajlwy1.png" alt="image"&gt;&lt;/a&gt;&lt;br&gt;
Below that nested form on the Job show page all past reviews for this job are shown. This was accomplished through an each loop and displays the review title, content, and author. &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff0bpfds4kezode1hjm3g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff0bpfds4kezode1hjm3g.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This rails section has blown me away with what I am now able to achieve and the most daunting topic, OOP, is becoming more and more clear. These Show pages could be cleaned up with more partials and I'm going to be implementing those in short time. All in all though I am impressed with what I can now comprehend after only four weeks of exposure to this framework and I cannot wait to build further projects that are even more expansive and intuitive. &lt;/p&gt;

</description>
      <category>rails</category>
      <category>ruby</category>
    </item>
    <item>
      <title>Following the Path to Success</title>
      <dc:creator>Ryan Erricson</dc:creator>
      <pubDate>Fri, 26 Mar 2021 18:03:57 +0000</pubDate>
      <link>https://dev.to/rickysonz/following-the-path-to-success-3ibb</link>
      <guid>https://dev.to/rickysonz/following-the-path-to-success-3ibb</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Fn1ZVRI8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/od87gb9p6z6uefriur1f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Fn1ZVRI8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/od87gb9p6z6uefriur1f.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two months of the program are officially in the books and I cannot be prouder! Phase 2 was a lot of information but it really all came together once I got this project put together. I decided to make an application that would allow you to input predictions for upcoming games in the English Premier League. A lot of aspects of this project were learning experiences and were difficult to build out, but the following feature in my program was definitely my favorite and most challenging piece.&lt;/p&gt;

&lt;p&gt;I wanted to create a User model that could have many relationships with other users. In that sense I wanted my Users to not only be able to follow other users, but also to be a followed by other users. After a ton of googling and speaking with my cohort leads I realized a model of Follow that could be aliased for a multidirectional relationship would be the best course of action for this program. &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--khxUyw14--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w6t64n02plnspul8djuz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--khxUyw14--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w6t64n02plnspul8djuz.png" alt="image"&gt;&lt;/a&gt;&lt;br&gt;
Above illustrates my User model where I set up a relationship where User can have many follows in line 9. Then in line 11 and 12 outline we are saying there is a table that ActiveRecord is going to make up called Follower_Relationships, through this a foreign key of following_id is set. The next line then aliases this key as follower so that we can call followers on a User to see who follows them. The same thing happens for lines 14 and 15 however it is just in the opposite direction. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9DVoMAba--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n7is617i99s94op6mu6g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9DVoMAba--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n7is617i99s94op6mu6g.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next we set the belongs to relationship in the Follow class to establish these aliases as the belong to relationship. No when we call the follower or following methods on our User class it will tell you who is a follower or following correctly, based on the direction of the relationship (which is based off of two user ID's). This is a pretty complex relationship as it using a has many relationship with the Follow class but what we are actually accomplishing is using Follow as a placeholder for ID's so we can refer back and see which users have this relationship.&lt;/p&gt;

&lt;p&gt;Now that we have this relationship we can also set up a pretty useful helper method called following?.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DAX7Wh_x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ld8vdy4bkv4olc44n99j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DAX7Wh_x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ld8vdy4bkv4olc44n99j.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This allows us to set certain conditions across the program that make features inaccessible if other users are not following the user they are trying to access. For example, in my program other users cannot see score predictions from other users unless they are following them. &lt;/p&gt;

&lt;p&gt;All in all, this project was great experience and this is clean easy code that should be widely repeatable in many future programs. To go with that, I hope to build this project out further so that we can pull data from an API or scrape it to pull the actual team matchups for the EPL weekend games as well as follow requests so users need permission to follow another user. &lt;/p&gt;

&lt;p&gt;If I could give any advice to another programmer going through this course is to hang in there, once you see the big picture all of the things you learned will make more sense. Additionally, if anyone needed to create this relationship this is a great model to use. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>1 Month, 1 Project, A Moment of Reflection, and DON'T FORGET TO TEST YOUR CODE!!!!</title>
      <dc:creator>Ryan Erricson</dc:creator>
      <pubDate>Fri, 26 Feb 2021 17:03:58 +0000</pubDate>
      <link>https://dev.to/rickysonz/1-month-1-project-a-moment-of-reflection-and-don-t-forget-to-test-your-code-1l26</link>
      <guid>https://dev.to/rickysonz/1-month-1-project-a-moment-of-reflection-and-don-t-forget-to-test-your-code-1l26</guid>
      <description>&lt;p&gt;Since starting this journey at Flatiron, I probably have experienced every emotion imaginable. The feelings of doubt, of not being god enough, and loads and loads of frustration, but my greatest emotion now is pride. I am really proud of getting to this point, and if you are a new FI student reading this I promise it is worth every bit of perseverance that this program requires.&lt;/p&gt;

&lt;p&gt;My first project was a CLI application that pulled from an open API called TV Maze. This program pulls one webpage from their show lists randomly and lists 20 shows that would be options. From there the user selects a show to learn more about that particular show. I found a few aspects of building this program out to be challenging that I will detail further. &lt;/p&gt;

&lt;p&gt;The first challenging aspect was building out the CLI logic which took me a while. I based some of it off of how I solved my Tic Tac Toe lab, but the first challenge I had was validating inputs correctly. I realized I could exit the loop by just having my check_input method puts a message when you input exit and not allow it to loop back to the check_input function.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;def check_input&lt;br&gt;
        input = gets.strip&lt;br&gt;
        puts "-----------------------------------------------------------------------"&lt;br&gt;
        if input.to_i &amp;lt; 21 &amp;amp;&amp;amp; input.to_i &amp;gt; 0 &amp;amp;&amp;amp; input =~ /^\d+$/&lt;br&gt;
            display_info(input)&lt;br&gt;
            puts "-----------------------------------------------------------------------"&lt;br&gt;
            puts "If you would like to see another show, please put in a number (1-20)".colorize(:yellow)&lt;br&gt;
            puts "-----------------------------------------------------------------------"&lt;br&gt;
            check_input&lt;br&gt;
        elsif input.downcase == "list"&lt;br&gt;
            list_shows&lt;br&gt;
            check_input&lt;br&gt;
        elsif input.downcase == "exit" || input.downcase =="end"&lt;br&gt;
            puts "Thank you for using the New Series Suggester."&lt;br&gt;
            puts "Goodbye!"&lt;br&gt;
            puts "-----------------------------------------------------------------------"&lt;br&gt;
        else&lt;br&gt;
            puts "I'm sorry but that is not a correct input".colorize(:light_red)&lt;br&gt;
            puts "Only numbers 1 - 20, list, exit, or end are valid inputs".colorize(:light_red)&lt;br&gt;
            puts "-----------------------------------------------------------------------"&lt;br&gt;
            check_input&lt;br&gt;
        end&lt;br&gt;
    end&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;From there I had error messages being thrown because of Show Objects with a nil value for the Summary attribute. This was being thrown because the gsub methods were trying to work on a nil value which is not allowed. As you can see, an if statement can be used within a line of code to give your program more flexibility. Another type of input validation that had to be worked out was to ensure only integers were accepted as a valid input. I utilized a regex pattern as another condition for my if statement to achieve this. If that Regex was left out, as long as a string start with an integer 1-20 it would accept it.&lt;/p&gt;

&lt;p&gt;There is a key lesson in this, test your code! I would have never caught any of these issues above if I did not test my code a thousand times. As of writing this I have not done my review, and I am very grateful that I caught this when I did.&lt;/p&gt;

&lt;p&gt;The final topic I wanted to review with my code is the separation of concerns when it comes to objects. As a new student I really urge you to take a step back and think about what you are doing when constructing objects. When I first made my program I added this display method to the show object. After speaking to my cohort lead he got me thinking, should the display method be in the object: Show, after all the CLI is the part of the program we want display the show information. From there I refactored my code to have proper separation of concerns and built this display method into the CLI class.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;def display_info(input)&lt;br&gt;
        newshow = ShowFinder::Show.all[input.to_i - 1]&lt;br&gt;
        puts "Name: #{newshow.name}"&lt;br&gt;
        puts "Genres: #{newshow.genre}"&lt;br&gt;
        puts "Language: #{newshow.language}"&lt;br&gt;
        puts "Network: #{newshow.network}"&lt;br&gt;
        puts "Country: #{newshow.country}"&lt;br&gt;
        puts "Premiered On: #{newshow.premiered}"&lt;br&gt;
        puts "Status: #{newshow.status}"&lt;br&gt;
        puts "Run Time: #{newshow.run_time} minutes"&lt;br&gt;
        puts "Official Website: #{newshow.official_site}"&lt;br&gt;
        puts "Summary: #{newshow.summary.gsub("&amp;lt;p&amp;gt;", "").gsub("&amp;lt;/p&amp;gt;", "").gsub("&amp;lt;b&amp;gt;", "").gsub("&amp;lt;/b&amp;gt;", "").gsub("&amp;lt;i&amp;gt;", "").gsub("&amp;lt;/i&amp;gt;", "")}" if newshow.summary != nil&lt;br&gt;
    end&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Flatiron has been a challenging experience that definitely has its ups and downs, but the sense of pride you will feel when completing projects is unreal. I feel more and more confident by the day about writing code and I really hope my story can inspire even just one other person to try out coding!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>GIT - Committing Changes</title>
      <dc:creator>Ryan Erricson</dc:creator>
      <pubDate>Tue, 09 Feb 2021 15:11:44 +0000</pubDate>
      <link>https://dev.to/rickysonz/git-committing-changes-2gbf</link>
      <guid>https://dev.to/rickysonz/git-committing-changes-2gbf</guid>
      <description>&lt;p&gt;Change. Commitment. Two words that are synonymous with this new venture I have taken on in my career. One does not happen without the other. Software engineering is a truly daunting career path but commitment is the vessel to take me through this journey. I knew my first job out of college in logistics was not the career path I truly wanted, so I committed to a change....&lt;/p&gt;

&lt;p&gt;Through one week and a few days of the SE course, I feel completely empowered by my decision. As I dive through the Ruby docs I see methods and functions that I can call, making complex problems easier to solve by the day. When running code through a terminal, seeing 10 examples, 0 failures has become one of the most rewarding feelings I have had in a long time. To know that I am not only learning the code but applying in certain use cases shows me that this career, while challenging as anything I have ever done, is manageable with the correct approach. &lt;/p&gt;

&lt;p&gt;What excites me most is seeing what is possible, and what we will be able to create from now until our final project. I mean right now, creating a CLI application seems like it will be the test of a lifetime, let alone a final project. But by the end of this course, I hope to be the better person for it and cannot wait to see what I can create. Committing on a daily basis to this journey is the only way to get the desired change to not only create what I would like to create, but also change my life for the better.&lt;/p&gt;

&lt;p&gt;git committing changes ..... done.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
