<?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>Forem: Michael Davis</title>
    <description>The latest articles on Forem by Michael Davis (@mikedavissoftware).</description>
    <link>https://forem.com/mikedavissoftware</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%2F974431%2F40dbfb54-f833-4885-98e8-4dc32720d501.jpg</url>
      <title>Forem: Michael Davis</title>
      <link>https://forem.com/mikedavissoftware</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mikedavissoftware"/>
    <language>en</language>
    <item>
      <title>Intro to Building a Ruby on Rails Back End</title>
      <dc:creator>Michael Davis</dc:creator>
      <pubDate>Tue, 31 Jan 2023 19:06:36 +0000</pubDate>
      <link>https://forem.com/mikedavissoftware/intro-to-building-a-ruby-on-rails-back-end-3nlk</link>
      <guid>https://forem.com/mikedavissoftware/intro-to-building-a-ruby-on-rails-back-end-3nlk</guid>
      <description>&lt;p&gt;&lt;em&gt;Follow along with my &lt;a href="https://github.com/mikedavissoftware/intro-to-building-a-ruby-on-rails-back-end" rel="noopener noreferrer"&gt;example repo&lt;/a&gt;, which has a solution branch.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So, you wanna be a Ruby on Rails back end engineer, huh?? Then you came to the right place. 👊🙂&lt;/p&gt;

&lt;p&gt;As of the posting of this article, I am finishing up my fourth phase of Flatiron School's full-stack software engineering boot camp. Phase 4 was focused on the topic of this article: Ruby on Rails. As an abstraction of Ruby, Rails expedites many of the tasks necessary to set up a Ruby database. What's the best way to do this, you ask? Well, let's find out! But first, let me briefly outline the data examples to best illustrate how our back end is built.&lt;/p&gt;

&lt;p&gt;I'm a big music fan, and a full album listener at that, so I'd like to use the example of &lt;strong&gt;music fans&lt;/strong&gt; giving &lt;strong&gt;ratings&lt;/strong&gt; to particular &lt;strong&gt;albums&lt;/strong&gt;. Each &lt;strong&gt;music fan&lt;/strong&gt; can rate many different &lt;strong&gt;albums&lt;/strong&gt;, and each &lt;strong&gt;album&lt;/strong&gt; can be rated by many different &lt;strong&gt;music fans&lt;/strong&gt;. It would make sense to have each &lt;strong&gt;music fan&lt;/strong&gt; to only be able to rate each &lt;strong&gt;album&lt;/strong&gt; once, because otherwise it would get confusing. Lastly, each &lt;strong&gt;rating&lt;/strong&gt; will belong to one &lt;strong&gt;music fan&lt;/strong&gt; and one &lt;strong&gt;album&lt;/strong&gt;, so &lt;strong&gt;ratings&lt;/strong&gt; will act as our &lt;em&gt;join table&lt;/em&gt; with a &lt;em&gt;foreign key&lt;/em&gt; for each of the other tables named &lt;strong&gt;music fans&lt;/strong&gt; &amp;amp; &lt;strong&gt;albums&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So, each of our tables will have these attributes/columns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Music Fans&lt;/strong&gt; - &lt;em&gt;:name&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Albums&lt;/strong&gt; - &lt;em&gt;:title, :artist, :release_year&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ratings&lt;/strong&gt; - &lt;em&gt;:score, :music_fan_id, :album_id&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Creating our associations will come into play later on, but now that we know what data we're going to be working with, let's review our Rails resources...&lt;/p&gt;

&lt;h1&gt;
  
  
  Rails Resources
&lt;/h1&gt;

&lt;p&gt;In a Ruby on Rails application, there are a few essential things to keep an eye on at the highest level of our file hierarchy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gemfile&lt;/strong&gt; &lt;em&gt;(list of gems to install)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;db/&lt;/strong&gt; &lt;em&gt;(database folder)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;config/&lt;/strong&gt; &lt;em&gt;(configurations folder)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;app/&lt;/strong&gt; &lt;em&gt;(application folder)&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are in the habit of paying attention to these files and folders, then you won't be caught off guard by any of the basic issues with building out your Rails back end!&lt;/p&gt;

&lt;p&gt;We do have a single terminal command that will build out all of the aforementioned resources for us, in the form of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails g resource class_name attribute_name:attribute_type
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...BUT, it's really important to understand all of the things that this command is doing, and how to properly write the command based on your particular dataset. So, let's start from the top.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's Break it Down by Each Resource...
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Gemfile
&lt;/h3&gt;

&lt;p&gt;As mentioned above, this is where we list our gems to be installed - these are our Ruby tools that make our life easier when building this code. For our purposes, we want to make sure our gemfile includes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s2"&gt;"active_model_serializers"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 0.10.12"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...and then to install these gems for use in development and testing, we enter this in our terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bundle install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; All of your other needed gems should be included if you properly created your rails application with:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails my_music_app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After creating our app's file structure and installing our gems, we can move on and start building out our data structure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Database Folder - &lt;em&gt;db/&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Now the fun begins. Our database folder is going to contain &lt;strong&gt;FOUR important things:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;db/migrate&lt;/strong&gt; (migrations folder)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;schema.rb&lt;/strong&gt; (database structure file, based on migrations)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;seeds.rb&lt;/strong&gt; (seed data, formatted for schema.rb)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;development.sqlite3&lt;/strong&gt; (final rendered database file)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's break it down...&lt;/p&gt;

&lt;h4&gt;
  
  
  1. db/migrate - &lt;em&gt;(migrations)&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;This is the folder is where it all begins. Our migration files set up the data structure for each of our tables, including both the name of the table itself and the labels for each column attribute. Each table will have its own migrations. For our &lt;strong&gt;Ratings&lt;/strong&gt; table (the join table with foreign keys), this is what our initial migration file would look like if we built it manually &lt;em&gt;(but hold off on this for just a minute)&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CreateRatings&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Migration&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;6.1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;change&lt;/span&gt;
    &lt;span class="n"&gt;create_table&lt;/span&gt; &lt;span class="ss"&gt;:ratings&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;integer&lt;/span&gt; &lt;span class="ss"&gt;:score&lt;/span&gt;
      &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;integer&lt;/span&gt; &lt;span class="ss"&gt;:music_fan_id&lt;/span&gt;
      &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;integer&lt;/span&gt; &lt;span class="ss"&gt;:album_id&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. schema.rb - &lt;em&gt;(database structure)&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;Our schema file will act as the data structure resulting from the migrations for all of our tables, acting as a filter for our incoming seed data. This file will look similar to our migrations, but will include all the tables. To create our schema file manually &lt;em&gt;(again, hold off on this too unless you want practice)&lt;/em&gt;, we need to run this in our terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails db:migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our resultant file should look something like this, including all three of our table migration structures:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;version: &lt;/span&gt;&lt;span class="mi"&gt;2023_01_20_164246&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;create_table&lt;/span&gt; &lt;span class="s2"&gt;"albums"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;force: :cascade&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt; &lt;span class="s2"&gt;"title"&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt; &lt;span class="s2"&gt;"artist"&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;integer&lt;/span&gt; &lt;span class="s2"&gt;"release_year"&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;datetime&lt;/span&gt; &lt;span class="s2"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;precision: &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;null: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;datetime&lt;/span&gt; &lt;span class="s2"&gt;"updated_at"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;precision: &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;null: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;create_table&lt;/span&gt; &lt;span class="s2"&gt;"music_fans"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;force: :cascade&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt; &lt;span class="s2"&gt;"name"&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;datetime&lt;/span&gt; &lt;span class="s2"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;precision: &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;null: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;datetime&lt;/span&gt; &lt;span class="s2"&gt;"updated_at"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;precision: &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;null: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;create_table&lt;/span&gt; &lt;span class="s2"&gt;"ratings"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;force: :cascade&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;integer&lt;/span&gt; &lt;span class="s2"&gt;"score"&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;integer&lt;/span&gt; &lt;span class="s2"&gt;"music_fan_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;null: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;integer&lt;/span&gt; &lt;span class="s2"&gt;"album_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;null: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;datetime&lt;/span&gt; &lt;span class="s2"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;precision: &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;null: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;datetime&lt;/span&gt; &lt;span class="s2"&gt;"updated_at"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;precision: &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;null: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's always good to double check your schema file after performing &lt;em&gt;rails db:migrate&lt;/em&gt;, just to make sure things are looking accurate. So, now our data structure is in place for us to seed our data tables with. BUT, we can't seed our data without...&lt;/p&gt;

&lt;h4&gt;
  
  
  3. seeds.rb &lt;em&gt;(our seed data)&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;This is the file in which we set up the actual data values for our table to be populated with. Without our seeds file, we won't be able to utilize our schema, because it won't have anything to work with. Basically, without a functioning seeds file, our resulting database will be comprised of empty tables. We don't want that, so let's look at what we need to do to build our seed data.&lt;/p&gt;

&lt;p&gt;There are many Ruby methods we can use in building our seeds file, but we will keep it simple this time. If we were to seed with 3 instances each of &lt;em&gt;music_fan&lt;/em&gt; and &lt;em&gt;album&lt;/em&gt;, along with 6 unique &lt;em&gt;rating&lt;/em&gt; instances, this is what it might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"🎵 Seeding music fans..."&lt;/span&gt;
&lt;span class="no"&gt;MusicFan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"Vizmund Cygnus"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;MusicFan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"Cassandra Gemini"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;MusicFan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"Cerpin Taxt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"🎵 Seeding albums..."&lt;/span&gt;
&lt;span class="no"&gt;Album&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"DAMN. COLLECTORS EDITION."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;artist: &lt;/span&gt;&lt;span class="s2"&gt;"Kendrick Lamar"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;release_year: &lt;/span&gt;&lt;span class="mi"&gt;2017&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Album&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"In Rainbows"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;artist: &lt;/span&gt;&lt;span class="s2"&gt;"Radiohead"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;release_year: &lt;/span&gt;&lt;span class="mi"&gt;2007&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Album&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"Monsters Are People"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;artist: &lt;/span&gt;&lt;span class="s2"&gt;"Chess at Breakfast"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;release_year: &lt;/span&gt;&lt;span class="mi"&gt;2021&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"🎵 Seeding ratings..."&lt;/span&gt;
&lt;span class="no"&gt;Rating&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;score: &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;music_fan_id: &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;album_id: &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Rating&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;score: &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;music_fan_id: &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;album_id: &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Rating&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;score: &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;music_fan_id: &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;album_id: &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Rating&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;score: &lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;music_fan_id: &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;album_id: &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Rating&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;score: &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;music_fan_id: &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;album_id: &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Rating&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;score: &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;music_fan_id: &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;album_id: &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Done seeding!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;_PRO TIP: If you want to get practice using the Faker Gem to automate some of the details of your seeds file, _&lt;/p&gt;

&lt;p&gt;As you can see, our seed data is built using pretty basic Ruby object format, with keys corresponding to our table attributes and unique values for those keys in each new creation of an instance. And luckily, we don't need to hold off creating this seeds file, since we will always have to create it manually.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;NOTE: Each creation of an instance assigns &lt;strong&gt;id&lt;/strong&gt; based on the order in which they're built, so the first MusicFan (Vizmund Cygnus) will have an &lt;strong&gt;id&lt;/strong&gt; of 1, and the second (Cassandra Gemini) will have an &lt;strong&gt;id&lt;/strong&gt; of 2, and so on...&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;With our fleshed-out seed data now created, we should be in a position to seed and render our database.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. db.sqlite3 - &lt;em&gt;(rendered database)&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;Assuming our seed data and migrations are formatted correctly, we can now run this command in our terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails db:seed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once we seed, we should now have a &lt;em&gt;development.sqlite3&lt;/em&gt; file in our &lt;em&gt;db/&lt;/em&gt; folder. Right-click on this and select "Open Database". This will open up your SQLite Explorer in the bottom-left corner of your VS Code window. &lt;em&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; Make sure you've installed SQLite as an extension in VS Code, or this won't work!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you've done everything correctly up to this point, you should have three tables. For example, your &lt;strong&gt;albums&lt;/strong&gt; table should look like this:&lt;/p&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%2Fkt7jqjz3alpe6sdu4fne.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%2Fkt7jqjz3alpe6sdu4fne.PNG" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If there are ever any weird issues with the database throughout development, you can always try this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails db:reset
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...which will drop the database (make sure you actually want to drop it before you do this!) and re-seed.&lt;/p&gt;

&lt;p&gt;Now that we have a rendered database, we can &lt;em&gt;finally&lt;/em&gt; move on to &lt;strong&gt;USING&lt;/strong&gt; our data!&lt;/p&gt;

&lt;h3&gt;
  
  
  Configurations Folder - &lt;em&gt;config/&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Our config folder luckily only has one file we need to keep a close eye on: &lt;em&gt;routes.rb&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This file is where we can determine what CRUD actions to be allowed for our different controllers, as well as setting up custom routes for things like user authentication. We won't take a super close look at this here, but here's what our basic routes file would look like if we have full CRUD on albums and music fans, but only index, show, create, and destroy (excluding update) on our ratings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;draw&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:ratings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;only: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:show&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:create&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:destroy&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:music_fans&lt;/span&gt;
  &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:albums&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Doing this will ensure that we don't have any unused routes on our back end, which will speed up our rendering process.&lt;/p&gt;

&lt;p&gt;Now that we have limited our routes, to enhance efficiency, we can move on to our final resource...&lt;/p&gt;

&lt;h3&gt;
  
  
  Application Folder - &lt;em&gt;app/&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Similar to how I went over the config folder, I won't go into too much detail on our app folder, but I will give an overview of the important resources to keep an eye on, along with why. Here's a brief list:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;models&lt;/strong&gt; (foundational class models)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;controllers&lt;/strong&gt; (controllers with route actions)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;serializers&lt;/strong&gt; (serializers for preparing data output)&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  app/models - &lt;em&gt;class models&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;Our models are the foundation for the rest of our app folder, because it's where we determine our associations and our validations. First and foremost, we need to build out our associations. Here's how they will look, with a score validation between 1-10:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;rating.rb&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Rating&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:music_fan&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:album&lt;/span&gt;

  &lt;span class="n"&gt;validates&lt;/span&gt; &lt;span class="ss"&gt;:score&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;inclusion: &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;music_fan.rb&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MusicFan&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:ratings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;dependent: :destroy&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:albums&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;through: :ratings&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;album.rb&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Album&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:ratings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;dependent: :destroy&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:music_fans&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;through: :ratings&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;NOTE: Our Rating model will already have the belongs_to relationships if we use rails g resource properly. Stick around to the end to see how that's written.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;OTHER NOTE: We include &lt;strong&gt;dependent: :destroy&lt;/strong&gt; in order to engage the destroy route of all ratings associated with a particular music fan or album, when they themselves are destroyed. This makes sense because ratings without music fans or albums shouldn't technically exist and will cause issues with rendering in the front end.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Awesome! Now we can move on to our next application resource.&lt;/p&gt;

&lt;h4&gt;
  
  
  app/controllers - &lt;em&gt;with route actions&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;Our controllers will contain the methods that our &lt;em&gt;routes.rb&lt;/em&gt; file points to. As far as full CRUD, the default actions are as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;index &lt;em&gt;(READ all)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;show &lt;em&gt;(READ one)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;create &lt;em&gt;(CREATE one)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;update &lt;em&gt;(UPDATE one)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;destroy &lt;em&gt;(DELETE one)&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To demonstrate full CRUD here, we need to pick one of the models that has full CRUD. For this purpose, let's go with albums:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AlbumsController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationController&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;
    &lt;span class="n"&gt;albums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Album&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;
    &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="ss"&gt;json: &lt;/span&gt;&lt;span class="n"&gt;albums&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;status: :ok&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;show&lt;/span&gt;
    &lt;span class="n"&gt;album&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Album&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="ss"&gt;json: &lt;/span&gt;&lt;span class="n"&gt;album&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;status: :ok&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;
    &lt;span class="n"&gt;album&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Album&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;album_params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="ss"&gt;json: &lt;/span&gt;&lt;span class="n"&gt;album&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;status: :created&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;update&lt;/span&gt;
    &lt;span class="n"&gt;album&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Album&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;album&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;album_params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="ss"&gt;json: &lt;/span&gt;&lt;span class="n"&gt;album&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;status: :accepted&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;delete&lt;/span&gt;
    &lt;span class="n"&gt;album&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Album&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;album&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;destroy&lt;/span&gt;
    &lt;span class="n"&gt;head&lt;/span&gt; &lt;span class="ss"&gt;:no_content&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="kp"&gt;private&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;album_params&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;permit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:artist&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:release_year&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; we save ourselves a bit of time by defining &lt;strong&gt;album_params&lt;/strong&gt; in our &lt;strong&gt;private methods&lt;/strong&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We now have all of our CRUD methods built for albums, so all our routes should work properly for it. We can now move on to the final piece in the puzzle...&lt;/p&gt;

&lt;h4&gt;
  
  
  app/serializers - &lt;em&gt;for preparing data output&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;We're almost there! With serializers, we are basically telling our routes how to prepare our data. So let's say that when we fetch a particular album, we want to also show all the music fans that have rated that particular album. To do this, we simply need to add one line to our &lt;em&gt;album_serializer.rb&lt;/em&gt;. Here's what the file will look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AlbumSerializer&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveModel&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Serializer&lt;/span&gt;
  &lt;span class="n"&gt;attributes&lt;/span&gt; &lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:artist&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:release_year&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:music_fans&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will ensure that when we do fetch that album, the JSON response will have a &lt;em&gt;music_fans&lt;/em&gt; key and a corresponding value of an array nesting all the music fans that have rated the album.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; We don't need to include the &lt;strong&gt;through: :ratings&lt;/strong&gt; here because we have already established that association in our model.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;One cool element to serializers is that you can create your own custom ones if you need to have more specific data outputs for particular CRUD actions. I won't go into that here, but I recommend doing some research on it!&lt;/p&gt;

&lt;p&gt;Now that we've established the importance of all our resources, we  can tie it all together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tying it All Together
&lt;/h2&gt;

&lt;p&gt;Jeez. Rails has a &lt;strong&gt;LOT&lt;/strong&gt; of resources to keep track of, eh?? If we had to populate our back end with all of these resources one at a time, it would take awhile for sure. Luckily, we don't have to!&lt;/p&gt;

&lt;h3&gt;
  
  
  Generators to the Rescue
&lt;/h3&gt;

&lt;p&gt;Rails has a generator feature that will create all of these files for us. However, there is room for error here, so it's very important to understand all the resources that are created by the generator, and how to check these resources for errors. Let's take a look at what the generator commands for each class will look like in our terminal, and then break them down. First, here is the basic formula, as mentioned at the beginning of this article:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails g resource class_name attribute_name:attribute_type --no-test-framework
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; Include &lt;strong&gt;--no-test-framework&lt;/strong&gt; if you already have testing files and want to avoid overwriting them.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And now our specific class examples:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Rating&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails g resource rating score:integer music_fan:belongs_to
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;MusicFan&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails g resource music_fan name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Album&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails g resource album title artist 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; The default &lt;strong&gt;attribute_type&lt;/strong&gt; is &lt;strong&gt;string&lt;/strong&gt;, so unless a particular attribute is something else, such as integer, you don't need to actually include the type in your resource generator.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;OTHER NOTE:&lt;/strong&gt; As far as associations, we can only include &lt;strong&gt;belongs_to&lt;/strong&gt; in our resource generator, and need to manually create our &lt;strong&gt;has_many&lt;/strong&gt; associations later on in our individual models.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As you see upon execution in your terminal, this command creates ALL of the resources we have gone over in this article. Pretty cool! If you did this command the right way, you're well on your way to customizing your back end.&lt;/p&gt;

&lt;p&gt;I hope this article was helpful, and as always...&lt;/p&gt;

&lt;h2&gt;
  
  
  Happy Coding!
&lt;/h2&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>database</category>
    </item>
    <item>
      <title>Beginner's Guide to Ruby Methods</title>
      <dc:creator>Michael Davis</dc:creator>
      <pubDate>Mon, 09 Jan 2023 07:34:48 +0000</pubDate>
      <link>https://forem.com/mikedavissoftware/beginners-guide-to-ruby-methods-6h7</link>
      <guid>https://forem.com/mikedavissoftware/beginners-guide-to-ruby-methods-6h7</guid>
      <description>&lt;p&gt;If you're like me, you've only recently begun your journey into working with back-end coding languages. For you, it might be Python, C#, PHP, or even JavaScript. But for me, it has been Ruby. &lt;/p&gt;

&lt;p&gt;As a current Flatiron School student, I just finished up Phase 3 of the full-stack software engineering curriculum, which was built around a comprehensive introduction to Ruby. We learned how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create migrations for back-end data structures&lt;/li&gt;
&lt;li&gt;Migrate those data structures to create a data table&lt;/li&gt;
&lt;li&gt;Seed the table's data using class models&lt;/li&gt;
&lt;li&gt;Create custom methods within those class models, in order to manipulate the data&lt;/li&gt;
&lt;li&gt;And use Sinatra to handle &lt;strong&gt;CRUD&lt;/strong&gt; actions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Remember that &lt;strong&gt;CRUD&lt;/strong&gt; stands for (with corresponding Ruby commands):&lt;br&gt;
&lt;strong&gt;C&lt;/strong&gt;reate - &lt;strong&gt;post&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;R&lt;/strong&gt;ead - &lt;strong&gt;get&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;U&lt;/strong&gt;pdate - &lt;strong&gt;patch&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;D&lt;/strong&gt;elete - &lt;strong&gt;delete&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;All of these skills are very helpful, both functionally and conceptually, in furthering one's understanding of programming and how to practice it with confidence! I, for one, am pretty excited to now have experience with handling tasks that require these things, &lt;strong&gt;&lt;em&gt;BUT...&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Ruby has a lot of built-in methods 😐
&lt;/h2&gt;
&lt;h4&gt;
  
  
  And it can sometimes take a lot of searching to find the right ones to use...
&lt;/h4&gt;

&lt;p&gt;If your first exposure to data manipulation was in JavaScript, the transition to doing similar things in Ruby can be a bit overwhelming without a guide to the most essential methods that you might use in the process. Therefore, I decided to create one!&lt;/p&gt;
&lt;h1&gt;
  
  
  So...
&lt;/h1&gt;

&lt;p&gt;Custom Ruby methods can target one of two scopes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Class Methods&lt;/strong&gt;, which affect all instances built from a particular class model&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instance Methods&lt;/strong&gt;, which affect only one particular instance of a class model&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The difference between an instance method and a class method involves the simple addition of a "&lt;em&gt;self.&lt;/em&gt;" to the front of the method name. 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;def self.class_method_name
   logic_applied_to_array_of_class_instances
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;VS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def instance_method_name
   logic_applied_to_instance
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we've distinguished the difference between &lt;strong&gt;Class Methods&lt;/strong&gt; and &lt;strong&gt;Instance Methods&lt;/strong&gt;, let's take a look at Ruby's...&lt;/p&gt;

&lt;h1&gt;
  
  
  Built-In Methods
&lt;/h1&gt;

&lt;p&gt;By definition, Ruby's &lt;strong&gt;Built-In Methods&lt;/strong&gt; are methods that are already built into the Ruby code, thus allowing the programmer to use them immediately, as elementary tools to build out more complex/specific &lt;em&gt;custom&lt;/em&gt; methods.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Built-in methods&lt;/strong&gt; allow us to do simple tasks like filtering lists, sorting items, finding a particular item, and checking/comparing the values of multiple different items. When we are dealing with data sets that have many items (or &lt;em&gt;instances&lt;/em&gt;) containing a variety of key-value pairs, it is important to have these built-in shorthand methods to quickly accomplish the aforementioned simple tasks.&lt;/p&gt;

&lt;h3&gt;
  
  
  But what &lt;em&gt;ARE&lt;/em&gt; these methods? Let's break it down.
&lt;/h3&gt;

&lt;p&gt;To get started, it might help to have some sample data. To accomplish this, I used Active Record to make a table of randomized movie rating data with many movies and many critics. There are three models: &lt;strong&gt;Movie&lt;/strong&gt;, &lt;strong&gt;Critic&lt;/strong&gt;, and &lt;strong&gt;Review&lt;/strong&gt;. Feel free to clone &lt;a href="https://github.com/micdavis93/beginners-guide-to-ruby-methods"&gt;my example repo&lt;/a&gt; and try these methods out for yourself!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Don't forget to:&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;bundle install&lt;/strong&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;rake db:migrate db:seed&lt;/strong&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;use a table explorer like SQLite to verify your database was populated&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;rake console&lt;/strong&gt; when you want to test out your methods&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once you've done steps 1-3 above, you should be looking at three simple tables similar to this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Movies&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dL66M4in--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r19oqno6uz1zrvfu3bqe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dL66M4in--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r19oqno6uz1zrvfu3bqe.png" alt="Image description" width="880" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Critics&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xigs9f16--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2a61xin29v3srygqpx48.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xigs9f16--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2a61xin29v3srygqpx48.png" alt="Image description" width="261" height="429"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reviews&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Kko6TY5W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qr5ucxo9ui7dsfgu75of.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Kko6TY5W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qr5ucxo9ui7dsfgu75of.png" alt="Image description" width="608" height="782"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alright, that's enough setup. Now that we have data to manipulate, we can try out our methods!&lt;/p&gt;
&lt;h3&gt;
  
  
  array.map
&lt;/h3&gt;

&lt;p&gt;Let's say we want to take our critics and add a last name to all of them, using the ever-useful &lt;a href="https://github.com/faker-ruby/faker"&gt;Faker gem&lt;/a&gt;. The method definition is going to look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  def self.add_last_name
    full_names = self.all.map{|critic|
      critic.update(name: "#{critic.name} #{Faker::Name.last_name}")
    }
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we are using &lt;em&gt;self.&lt;/em&gt; at the beginning of this method name, because this is a &lt;strong&gt;Class Method&lt;/strong&gt;, intended to affect all instances of a particular class. You can certainly use &lt;em&gt;.map&lt;/em&gt; on smaller arrays of instances, too but our goal here was to use all the instances in this class. So, this map is stepping (iterating) through the array of instances and applying the change to each and every one. We can test out this method in our console by typing &lt;em&gt;rake console&lt;/em&gt; in our terminal (step 4 from above), and then entering this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Critic.add_last_name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should return a bunch of lines and successfully update our database so that all the critics have last names now. Refresh your database viewer to make sure the updates went through!&lt;/p&gt;

&lt;h3&gt;
  
  
  array.filter
&lt;/h3&gt;

&lt;p&gt;Let's switch over to the reviews table now. If we want to know all the ratings of only a particular movie, we can &lt;em&gt;.filter&lt;/em&gt; all our reviews by the &lt;em&gt;movie_id&lt;/em&gt; key. Here's what that method definition might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  def self.filter_by_movie(movie_id)
    self.all.filter{|review| review.movie_id == movie_id}
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, we are using &lt;em&gt;self.&lt;/em&gt; upfront because we are filtering down from all instances of this &lt;strong&gt;Review&lt;/strong&gt; class. This filter is stepping through and checking each review instance's value for &lt;em&gt;movie_id&lt;/em&gt; and checking it against the one passed in as an argument when the method is called, removing if this returns false. We test by entering &lt;em&gt;rake console&lt;/em&gt; again and typing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Review.filter_by_movie(1)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...and this should return a new array of review instances that have a &lt;em&gt;movie_id&lt;/em&gt; of 1!&lt;/p&gt;

&lt;h3&gt;
  
  
  .order
&lt;/h3&gt;

&lt;p&gt;What if we wanted to sort all the reviews by rating? For that, we use &lt;em&gt;.order&lt;/em&gt;, and with it we have a couple options. If we're using  integers, it will order numerically from lowest to highest (ascending) by default. In the method, we must specify the key we wish to order the instances by, which will of course by our &lt;em&gt;rating&lt;/em&gt;. Let's check it out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  def self.order_by_rating
    self.all.order(:rating)
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yet again, we are appending &lt;em&gt;self.&lt;/em&gt; to the front of the method name to specify that we are looking to sort all instances of this &lt;strong&gt;Review&lt;/strong&gt; class. And we passed in &lt;em&gt;:rating&lt;/em&gt; in symbol format to follow the syntax rules for the &lt;em&gt;.order&lt;/em&gt;. Open up your &lt;em&gt;rake console&lt;/em&gt; again and test with this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Review.order_by_rating
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should return a new array with the same number of reviews, but they will be ordered from lowest rated to highest rated! If you wish to order the reviews descending instead, simply replace the content inside the parentheses with &lt;em&gt;rating: :desc&lt;/em&gt;!&lt;/p&gt;

&lt;h3&gt;
  
  
  I have run out of time to finish this article now, but I will be returning to talk about these methods as well:
&lt;/h3&gt;

&lt;h4&gt;
  
  
  .max_by / .min_by
&lt;/h4&gt;

&lt;h4&gt;
  
  
  .sum
&lt;/h4&gt;

&lt;h4&gt;
  
  
  .count
&lt;/h4&gt;

&lt;h4&gt;
  
  
  .create
&lt;/h4&gt;

&lt;h4&gt;
  
  
  .find / .find_by
&lt;/h4&gt;

&lt;h4&gt;
  
  
  .istrue? / .isfalse?
&lt;/h4&gt;

&lt;h4&gt;
  
  
  .destroy
&lt;/h4&gt;

&lt;h1&gt;
  
  
  Thanks for reading, and happy coding!
&lt;/h1&gt;

</description>
      <category>ruby</category>
      <category>database</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>React Router for Dummies</title>
      <dc:creator>Michael Davis</dc:creator>
      <pubDate>Sun, 11 Dec 2022 03:00:29 +0000</pubDate>
      <link>https://forem.com/mikedavissoftware/reactrouterfordummies-onreadchangedummytosmarty--53nn</link>
      <guid>https://forem.com/mikedavissoftware/reactrouterfordummies-onreadchangedummytosmarty--53nn</guid>
      <description>&lt;h1&gt;
  
  
  Greetings, Friends &amp;amp; Fellow Devs 👋
&lt;/h1&gt;

&lt;p&gt;I really hope you didn't take the article title for an offense, because if you're pursuing a career (or even a side-hobby) in software engineering, you're most certainly not a dummy, and I have great respect for you. And if you &lt;em&gt;aren't&lt;/em&gt; pursuing software engineering, then I highly recommend it, because there are great benefits and &lt;em&gt;we've got jackets&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F4l3lqe0877rqonqsmqfm.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F4l3lqe0877rqonqsmqfm.gif" alt="We've got jackets." width="404" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not to mention, the original working title was:&lt;br&gt;
&lt;strong&gt;&amp;lt;ReactRouterForDummies onRead={changeDummyToSmarty} /&amp;gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Anyway...&lt;/p&gt;

&lt;p&gt;As of the publishing of this article, I am a late-Phase-2 student of Flatiron School's Software Engineering bootcamp, heading into Phase 3. This program is a full-time, intensive, no-nonsense run-through of both front-end and back-end web development technologies. At this point, we have accumulated a comprehensive understanding of the way JavaScript, HTML, and CSS can all work together to render sleek &amp;amp; responsive websites, similar to the one you're seeing at this very moment!&lt;/p&gt;
&lt;h1&gt;
  
  
  Let's Talk About Frameworks
&lt;/h1&gt;

&lt;p&gt;One way to shape this complex tapestry of web dev languages is through &lt;strong&gt;frameworks&lt;/strong&gt;. A programming framework is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"...an abstraction in which software [...] can be selectively changed by additional user-written code, thus providing application-specific software. It provides a standard way to build and deploy applications and is a universal, reusable software environment that provides particular functionality as part of a larger software platform to facilitate the development of software applications, products and solutions."¹&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pretty cool, right?&lt;/p&gt;

&lt;p&gt;Frameworks provide a TON of additional efficiencies and functionalities that are a distant fantasy for &lt;em&gt;vanilla&lt;/em&gt; (plain) code. And truly, frameworks are the logical next step once you have a solid understanding of the underlying languages &amp;amp; logic beneath them. And that brings us to our topic for this post: The &lt;strong&gt;React&lt;/strong&gt; framework, and more specifically...&lt;/p&gt;
&lt;h1&gt;
  
  
  React Router
&lt;/h1&gt;

&lt;p&gt;React Router is an extremely capable tool, allowing a React web app to accomplish the goal of &lt;strong&gt;client-side routing&lt;/strong&gt;, which manifests a dynamic website hierarchy based on the content and components within that app. Through React Router, a web developer is able to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Easily create a well-organized domain extension hierarchy&lt;/li&gt;
&lt;li&gt;Eliminate the need for a new server request upon navigation between pages within that domain&lt;/li&gt;
&lt;li&gt;Generally boost the speed and clarity of the user experience&lt;/li&gt;
&lt;/ul&gt;


&lt;h1&gt;
  
  
  Time to Break It Down...
&lt;/h1&gt;
&lt;h2&gt;
  
  
  Routers
&lt;/h2&gt;

&lt;p&gt;If you're setting up &lt;strong&gt;React Router&lt;/strong&gt; for use in your web app, you'll need to start by importing your router component itself, in the form of &lt;strong&gt;&amp;lt;BrowserRouter&amp;gt;&lt;/strong&gt; or &lt;strong&gt;&amp;lt;HashRouter&amp;gt;&lt;/strong&gt;. More information on the differences between those &lt;a href="https://v5.reactrouter.com/web/guides/primary-components" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Next, you'll need to &lt;em&gt;"&lt;strong&gt;wrap&lt;/strong&gt; your top-level &lt;strong&gt;&amp;lt;App/&amp;gt;&lt;/strong&gt; component"&lt;/em&gt; in this router component &lt;em&gt;"at the root of your element hierachy"&lt;/em&gt;². This should happen in your &lt;em&gt;index.js&lt;/em&gt; file, which should look something like this:&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 ReactDOM from 'react-dom/client'
import { BrowserRouter } from "react-router-dom"
import './index.css'
import App from './App'

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  &amp;lt;React.StrictMode&amp;gt;
    &amp;lt;BrowserRouter&amp;gt;
      &amp;lt;App /&amp;gt;
    &amp;lt;/BrowserRouter&amp;gt;
  &amp;lt;/React.StrictMode&amp;gt;
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; &lt;em&gt;You can apply a short name to longer-named imported modules using &lt;strong&gt;as&lt;/strong&gt;, which will clean up your code a bit. You can use whatever short name you want, but it's obviously best to make it relevant. The code above can be made a bit simpler with this tool, importing like so:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { BrowserRouter as Router } from "react-router-dom";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;...and replacing the component labels with that short name.&lt;/em&gt;&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;Router&amp;gt;
  &amp;lt;App /&amp;gt;
&amp;lt;/Router&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you have properly incorporated your &lt;strong&gt;Router&lt;/strong&gt; into your root component, you are then ready to move down a level in your element hierarchy and start building out the &lt;strong&gt;Router&lt;/strong&gt;'s functionality in your &lt;strong&gt;&amp;lt;App/&amp;gt;&lt;/strong&gt; component!&lt;/p&gt;

&lt;h2&gt;
  
  
  Route Matchers
&lt;/h2&gt;

&lt;p&gt;To efficiently create the website's URL hierarchy within the &lt;strong&gt;Router&lt;/strong&gt;, you employ the use of &lt;strong&gt;Route Matchers&lt;/strong&gt;, of which there are two required components: &lt;strong&gt;&amp;lt;Switch&amp;gt;&lt;/strong&gt; and &lt;strong&gt;&amp;lt;Route&amp;gt;&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remember:&lt;/strong&gt; &lt;em&gt;We have to start by importing both of these components at the beginning of &lt;strong&gt;App.js&lt;/strong&gt; before we can start building them out.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Switch, Route } from "react-router-dom"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&amp;lt;Switch&amp;gt;&lt;/strong&gt; is the parent container component here. It tells our app to read the information within it as &lt;strong&gt;Route Matching&lt;/strong&gt; information. As you might have predicted, that information is comprised of child components: these are the &lt;strong&gt;&amp;lt;Route&amp;gt;&lt;/strong&gt; components.&lt;/p&gt;

&lt;p&gt;Just like &lt;strong&gt;&amp;lt;Switch&amp;gt;&lt;/strong&gt;, &lt;strong&gt;&amp;lt;Route&amp;gt;&lt;/strong&gt; is also a container component, inside which you will place the components you want to be rendered upon the activation of that particular Route. Additionally, you will need to include a &lt;strong&gt;path&lt;/strong&gt; prop in the opening tag for each &lt;strong&gt;&amp;lt;Route&amp;gt;&lt;/strong&gt;. The &lt;strong&gt;path&lt;/strong&gt; prop will instruct the browser on what URL extension will be added to the domain name when that particular route is activated.&lt;/p&gt;

&lt;p&gt;You can now fully build your &lt;strong&gt;Route Matching&lt;/strong&gt; in the &lt;strong&gt;&amp;lt;App/&amp;gt;&lt;/strong&gt; component, like so:&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 { Switch, Route } from "react-router-dom"
import Header from "./Header.js"
import Home from "./Home.js"
import About from "./About.js"
import ContactInfo from "./ContactInfo.js"
import ContactForm from "./ContactForm.js"
import Footer from "./Footer.js"

export default function App() {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;Header /&amp;gt;
      &amp;lt;Switch&amp;gt;
        &amp;lt;Route path="/about"&amp;gt;
          &amp;lt;About /&amp;gt;
        &amp;lt;/Route&amp;gt;

        &amp;lt;Route path="/contact/form"&amp;gt;
          &amp;lt;ContactForm /&amp;gt;
        &amp;lt;/Route&amp;gt;

        &amp;lt;Route path="/contact"&amp;gt;
          &amp;lt;ContactInfo /&amp;gt;
        &amp;lt;/Route&amp;gt;

        &amp;lt;Route path="/"&amp;gt;
          &amp;lt;Home /&amp;gt;
        &amp;lt;/Route&amp;gt;
      &amp;lt;Switch&amp;gt;
      &amp;lt;Footer /&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure to place the components with the least specific pathways last, so that the browser can properly select which pathway you're actually trying to reach. For example, &lt;strong&gt;&amp;lt;Home/&amp;gt;&lt;/strong&gt; is listed last because the pathway of "/" happens to be the starting character to each route path. So if you're routing to &lt;strong&gt;&amp;lt;Home/&amp;gt;&lt;/strong&gt;, the &lt;strong&gt;&amp;lt;Switch&amp;gt;&lt;/strong&gt; recognizes that there is nothing else after the "/", it skips over every other &lt;strong&gt;&amp;lt;Route&amp;gt;&lt;/strong&gt; component until the one that only has "/", which will then render &lt;strong&gt;&amp;lt;Home/&amp;gt;&lt;/strong&gt;. This same logic is why the route with &lt;strong&gt;&amp;lt;ContactForm/&amp;gt;&lt;/strong&gt; (a component you want to be interpreted as a sub-branch of "/contact") is listed &lt;em&gt;BEFORE&lt;/em&gt; the route with &lt;strong&gt;&amp;lt;ContactInfo/&amp;gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; &lt;em&gt;If you'd prefer to order things differently, perhaps for readability's sake, you can pass the &lt;strong&gt;exact&lt;/strong&gt; prop to the particular &lt;strong&gt;&amp;lt;Route&amp;gt;&lt;/strong&gt; component. This instructs the app to look for the route with that exact pathway, no matter where in the &lt;strong&gt;&amp;lt;Switch&amp;gt;&lt;/strong&gt; it is placed.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Okay... You are &lt;em&gt;almost&lt;/em&gt; there. You just need &lt;strong&gt;one more tool&lt;/strong&gt; to complete the React Routing puzzle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Route Changers (aka Navigation)
&lt;/h2&gt;

&lt;p&gt;Now that you have set up your route pathways via &lt;strong&gt;&amp;lt;Switch&amp;gt;&lt;/strong&gt; and &lt;strong&gt;&amp;lt;Route&amp;gt;&lt;/strong&gt;, you can now place your &lt;strong&gt;Route Changers&lt;/strong&gt;. These components show up in the form of &lt;strong&gt;&amp;lt;Link&amp;gt;&lt;/strong&gt;, &lt;strong&gt;&amp;lt;NavLink&amp;gt;&lt;/strong&gt;, or &lt;strong&gt;&amp;lt;Redirect&amp;gt;&lt;/strong&gt;. All of these components have the power to change currently rendered components, based on the routes you've created in the &lt;strong&gt;&amp;lt;Switch&amp;gt;&lt;/strong&gt; component.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Route Changers&lt;/strong&gt; can be placed anywhere in the app, and they all require a &lt;strong&gt;to&lt;/strong&gt; prop, which needs to have a corresponding value that matches the path given to the route you're trying to switch to. If this is done successfully, the route will change and the desired components will render on the page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&amp;lt;Link&amp;gt;&lt;/strong&gt; is the route changer with the broadest functionality. It simply creates an &lt;strong&gt;&amp;lt;a&amp;gt;&lt;/strong&gt; element on the page that has an &lt;strong&gt;href&lt;/strong&gt; attribute equal to the value of the &lt;strong&gt;to&lt;/strong&gt; prop. This tag changes the route to the one with that matching path. You could create &lt;strong&gt;&amp;lt;Link&amp;gt;&lt;/strong&gt; components for all our routes like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Link } from "react-router-dom"

export default LinkExamples() {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;Link to="/"&amp;gt;Home&amp;lt;/Link&amp;gt;
      &amp;lt;Link to="/about"&amp;gt;About&amp;lt;/Link&amp;gt;
      &amp;lt;Link to="/contact"&amp;gt;Contact Information&amp;lt;/Link&amp;gt;
      &amp;lt;Link to="/contact/form"&amp;gt;Contact Form&amp;lt;/Link&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...Pretty straightforward!&lt;/p&gt;

&lt;p&gt;On the other hand, &lt;strong&gt;&amp;lt;NavLink&amp;gt;&lt;/strong&gt; is a route changer with a more specific purpose. As the name implies, this component is meant to be included in a navigation bar. In addition to changing the current route the same way &lt;strong&gt;&amp;lt;Link&amp;gt;&lt;/strong&gt; does, it also has the ability to change its appearance based on its status of being the currently active route. That's why this component needs &lt;strong&gt;both&lt;/strong&gt; the props &lt;strong&gt;to&lt;/strong&gt; and &lt;strong&gt;activeClassName&lt;/strong&gt;. When the corresponding route is active, the &lt;strong&gt;&amp;lt;NavLink&amp;gt;&lt;/strong&gt; will adopt the class name equal to the value of that &lt;strong&gt;activeClassName&lt;/strong&gt; prop. It is best practice to just nest these components in a navigation bar component, perhaps called &lt;strong&gt;&amp;lt;NavBar&amp;gt;&lt;/strong&gt;. This is what that component might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { NavLink } from "react-router-dom"

export default NavBar() {
  return (
    &amp;lt;nav&amp;gt;
      &amp;lt;NavLink to="/"&amp;gt;Home&amp;lt;/Link&amp;gt;
      &amp;lt;NavLink to="/about"&amp;gt;About&amp;lt;/Link&amp;gt;
      &amp;lt;NavLink to="/contact"&amp;gt;Contact Information&amp;lt;/Link&amp;gt;
      &amp;lt;NavLink to="/contact/form"&amp;gt;Contact Form&amp;lt;/Link&amp;gt;
    &amp;lt;/nav&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&amp;lt;Redirect&amp;gt;&lt;/strong&gt; is the last route changer, designed to force navigation based on certain client conditions, such as whether the user is logged in and should be able to access only certain paths. I will not demonstrate this one here - perhaps another time!&lt;/p&gt;

&lt;p&gt;Lastly, links can be used to render a route dynamically, using an &lt;strong&gt;id&lt;/strong&gt; prop and fetching a specific data object based on that, to be used in the rendering of this route. The &lt;strong&gt;id&lt;/strong&gt; is formatted into the &lt;strong&gt;&amp;lt;Link&amp;gt;&lt;/strong&gt; like so:&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 to={`/contacts/${id}`}&amp;gt;Contact Information&amp;lt;/Link&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  In Summary...
&lt;/h2&gt;

&lt;p&gt;React Routing is an efficient way to create a dynamic web app for your users. If you haven't started using this powerful tool, I highly recommend it. I hope this article has helped React Router seem more straightforward.&lt;/p&gt;

&lt;h1&gt;
  
  
  Happy Coding!
&lt;/h1&gt;




&lt;h4&gt;
  
  
  Sources
&lt;/h4&gt;

&lt;p&gt;¹&lt;a href="https://en.wikipedia.org/wiki/Software_framework" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt;&lt;br&gt;
²&lt;a href="https://v5.reactrouter.com/web/guides/primary-components" rel="noopener noreferrer"&gt;Primary Components&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>The Case for Function Trees</title>
      <dc:creator>Michael Davis</dc:creator>
      <pubDate>Fri, 18 Nov 2022 21:21:57 +0000</pubDate>
      <link>https://forem.com/mikedavissoftware/the-case-for-function-trees-2a87</link>
      <guid>https://forem.com/mikedavissoftware/the-case-for-function-trees-2a87</guid>
      <description>&lt;h2&gt;
  
  
  A little intro...
&lt;/h2&gt;

&lt;p&gt;I am currently enrolled in Flatiron School's Software Engineering bootcamp. At the time of posting this, my cohort is finishing up Phase 1 of the program (JS Basics) and preparing to enter Phase 2 (React Framework). In light of this, I think it's a great time to review some productivity tools!&lt;/p&gt;

&lt;h2&gt;
  
  
  Whether you are a beginner, jr., or sr. dev...
&lt;/h2&gt;

&lt;p&gt;You've likely been involved in countless projects (software or otherwise) where there is a clear set of expected deliverables at the end of the project. You've &lt;em&gt;also&lt;/em&gt; likely come across a myriad of different productivity tools to help build a roadmap for executing these deliverables. These tools might include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Flow charts&lt;/li&gt;
&lt;li&gt;Layout diagrams&lt;/li&gt;
&lt;li&gt;Outlines&lt;/li&gt;
&lt;li&gt;Word webs&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  In software engineering...
&lt;/h2&gt;

&lt;p&gt;Visual and conceptual productivity tools come in handy at different times for different goals, tasks, and audiences. Therefore, it's very important to understand what tools are useful to you and your teammates, dependent on the circumstances. Knowledge of the strengths of each tool can yield huge improvements in operating efficiency by reducing the need for clarification.&lt;/p&gt;

&lt;h2&gt;
  
  
  As I mentioned in my intro...
&lt;/h2&gt;

&lt;p&gt;I am entering Phase 2 of my coding bootcamp, which will cover the React Framework. From what I've been told, React engages a more conceptual approach to development, as opposed to the syntax- and fundamentals-heavy stages of learning the web development basics.&lt;br&gt;
Though I'd never rule out the use of any of the aforementioned productivity tools, I have a feeling that I'll be using one &lt;em&gt;other&lt;/em&gt; tool more often: &lt;strong&gt;THE FUNCTION TREE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QIJDLlnb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9zes3lwctgozczayb2h9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QIJDLlnb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9zes3lwctgozczayb2h9.jpg" alt="Image description" width="300" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  According to Wikipedia...
&lt;/h2&gt;

&lt;p&gt;"A function tree is a diagram showing the dependencies between the functions of a system. It breaks a problem (or its solution) down into simpler parts. When used in computer programming, a function tree visualizes which function calls another."&lt;/p&gt;

&lt;p&gt;So, I could see this being a very useful tool for taking the list of deliverables, and:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Conceptualizing the functions&lt;/li&gt;
&lt;li&gt;Figuring out the order of function declaration&lt;/li&gt;
&lt;li&gt;Mapping out the functions based on priority, scope, nesting, variable reassignment, etc.&lt;/li&gt;
&lt;li&gt;Be able to refer back to this and possibly rearrange the function tree or create multiple function trees to cover different branches of the project&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;...and do all of this in a way that is easily communicable across an entire project team. 10/10&lt;/p&gt;

&lt;h2&gt;
  
  
  In conclusion...
&lt;/h2&gt;

&lt;p&gt;I'm looking forward to using this function tree visual tool as I learn React and beyond!&lt;/p&gt;

&lt;p&gt;Sources(LOL):&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Function_tree"&gt;https://en.wikipedia.org/wiki/Function_tree&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>productivity</category>
      <category>team</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
