<?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: John Glennan</title>
    <description>The latest articles on DEV Community by John Glennan (@glennanj1).</description>
    <link>https://dev.to/glennanj1</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%2F475391%2F479b3dd8-dc95-4f02-95ec-6b3cf1876fa4.jpg</url>
      <title>DEV Community: John Glennan</title>
      <link>https://dev.to/glennanj1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/glennanj1"/>
    <language>en</language>
    <item>
      <title>Flatiron School</title>
      <dc:creator>John Glennan</dc:creator>
      <pubDate>Mon, 07 Jun 2021 18:18:56 +0000</pubDate>
      <link>https://dev.to/glennanj1/flatiron-school-100g</link>
      <guid>https://dev.to/glennanj1/flatiron-school-100g</guid>
      <description>&lt;p&gt;My time at the flatiron school has been meaningful and rewarding. All the hard work I put in finally is showing as I finished up my last project review. I remember starting in Phase 1 learning the command line and core ruby. My first project acted as a gateway into the world of programming. Learning how to produce returns on the command line was no easy task for someone who never coded before. Phase 2 is where the fun began. I started to see that the OO code that I was writing was finally showing up in a web browser. I was hooked. Seeing your code turn into a real operational master piece leaves you wanting more. My favorite part was combining the cli scraper logic into my second project, acting as an api that fetched data for my views. In Phase 3 came Ruby on Rails. The framework that I have been so eager to learn since I first heard the name. Rails lives up to its name and learning it is quite the ride. This framework has it all! I'm a huge fan of convention over configuration. This framework allowed me to separate out routing, controller actions, models and so much more. Once I finished with rails I realized quickly that I had to switch gears into JavaScript. Phase 4 is where I learned the most about how web development works, it wasn't easy. With hard work, long nights and dedication I was able to overcome such a difficult challenge. Lesson after lesson I plugged away all to figure out how to 'wire up' a backend to a front end and vice versa. I can't forget how lucky I was to have Flatiron as support system. I was able to ask questions and get answers that left me inspired after much frustration and debugging. In the last phase I learned to develop a React frontend. It feels more natural and the way you're able to separate out containers, components and routing felt similar to rails almost as if they were made to work together. My journey was long but I'm happy to say I passed my final review and can look forward to the projects ahead. Flatirons job ready curriculum has me prepared to take on any challenge. Most importantly I learned how to learn. &lt;/p&gt;

&lt;p&gt;Image by &lt;a href="https://pixabay.com/photos/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=768783"&gt;Free-Photos&lt;/a&gt; from &lt;a href="https://pixabay.com/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=768783"&gt;Pixabay&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rails</category>
      <category>ruby</category>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>TailSwipes</title>
      <dc:creator>John Glennan</dc:creator>
      <pubDate>Thu, 03 Jun 2021 15:04:31 +0000</pubDate>
      <link>https://dev.to/glennanj1/tailswipes-3963</link>
      <guid>https://dev.to/glennanj1/tailswipes-3963</guid>
      <description>&lt;h2&gt;
  
  
  The end of the beginning
&lt;/h2&gt;

&lt;p&gt;Finalizing pushes to github from both repositories and the feeling of accomplishment rushes over me. I quickly realized this wasn't the end this was just the beginning. My time at flatiron school has prepared me for this moment. A moment to look at all that I have accomplished in just six months. This brings me to my new app tail swipes. The inspiration came from the start of the pandemic when my golden doodle Ozzy had no one to socialize with. When I started flatiron I knew that I wanted to save my favorite idea for last. Using create-react-app made this dream a reality. A mock app that simulates matching with other dogs to message and have play dates. This seemed easy enough, right? &lt;br&gt;
&lt;a href="https://i.giphy.com/media/SggILpMXO7Xt6/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/SggILpMXO7Xt6/giphy.gif" alt="dog-giphy"&gt;&lt;/a&gt;&lt;br&gt;
I was very wrong. Planning this app required me to learn all facets of react and its best friend rails very quickly.Let me walk you through how I started my profile object from back to front. I scaled up a rails backend with postgres flags so that it was easily deployable on heroku. I then started by generating profile controller, model and fast-json's serializer. I knew my profile model would consist of a name, image, and a match boolean. I checked the pending migration then migrated once everything looked good. Now it was time to gather some seed data.&lt;br&gt;
&lt;a href="https://i.giphy.com/media/mDBBU8K7Np2UQs9Dqy/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/mDBBU8K7Np2UQs9Dqy/giphy.gif" alt="seed-giphy"&gt;&lt;/a&gt;&lt;br&gt;
Using my plans I generated json data in the seed file and realized I don't have an easy way to get pictures for my profile. I have a million pictures of my golden doodle but this wouldn't satisfy variety in a mock profile system. This is where &lt;a href="https://placedog.net/" rel="noopener noreferrer"&gt;https://placedog.net/&lt;/a&gt; came in handy. This website is able to generate photos of random dogs and allows you to edit the url to include sizing and ids if you want consistant pictures. Next it was time to generate fake names and matches. For names I used the faker gem. For matches I used rubys rand() method to generate match booleans &lt;code&gt;0.5 &amp;lt; rand(1)&lt;/code&gt; and that did the trick. &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%2Fej6m2jqnw59zay3jc5vr.jpeg" 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%2Fej6m2jqnw59zay3jc5vr.jpeg" alt="lego-2310286_640"&gt;&lt;/a&gt; Image by &lt;a href="https://pixabay.com/users/aitoff-388338/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=2310286" rel="noopener noreferrer"&gt;Andrew Martin&lt;/a&gt; from &lt;a href="https://pixabay.com/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=2310286" rel="noopener noreferrer"&gt;Pixabay&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;I checked out &lt;code&gt;localhost:3000/profiles&lt;/code&gt; and everything looked good. Now it was time to &lt;code&gt;create-react-app tailswipes&lt;/code&gt;. I &lt;code&gt;npm i &amp;amp;&amp;amp; npm start&lt;/code&gt; then removed the default logo and components. &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%2Fke06wiguhofis1o8wxno.gif" 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%2Fke06wiguhofis1o8wxno.gif" alt="https://revelry.co/resources/design/ux-design-react-native/"&gt;&lt;/a&gt;&lt;br&gt;
I'm using redux for state management in this application so I imported redux and created my store in index.js. This allowed me to import provider and wrap the entire app component. &lt;br&gt;
Next I made the profile container component, profile component, fetchProfile action and profile reducer. At this point I had to import redux-thunk middle ware so that I could use return functions in my actions. After applying the middle ware I started coding out the fetch to the backend. Testing this made it so much easier to make sure I was getting the data I wanted.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Chrome Console

fetch ('http://localhost:3000/profiles').then(r =&amp;gt; r.json())

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which returned a promise that I was pleased to see.&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%2F380epouenasktbxpip8d.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%2F380epouenasktbxpip8d.png" alt="image"&gt;&lt;/a&gt;&lt;br&gt;
I then started writing out my reducer functions so that when my actions are dispatched they can call on the reducer to return the state and loading objects (pure functions) based on the dispatched action type. I then proceeded to my profile container and connected my profile container to the store &lt;code&gt;import { connect } from 'react-redux'&lt;/code&gt;. This allowed me to mapStateToProps and mapDispatchToProps. I used &lt;code&gt;componentDidMount()&lt;/code&gt; and started the initial pull of data using &lt;code&gt;fetchProfiles()&lt;/code&gt; dispatch action from props.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Then I mapped over the props state data and created profiles. Once the profiles were showing up in my front-end localhost:3001 I was able to get to work styling and working on different parts of the functionality.&lt;/p&gt;

&lt;p&gt;This is the basic flow of how I created my profile object from back to front. In my next article I will be reviewing react-tinder-card&lt;br&gt;
 and how I started my message feature. Let me know your thoughts in the comments. Thanks for reading!&lt;/p&gt;

</description>
      <category>react</category>
      <category>rails</category>
      <category>redux</category>
    </item>
    <item>
      <title>Troubleshooting SPA</title>
      <dc:creator>John Glennan</dc:creator>
      <pubDate>Mon, 19 Apr 2021 23:22:04 +0000</pubDate>
      <link>https://dev.to/glennanj1/troubleshooting-spa-5a95</link>
      <guid>https://dev.to/glennanj1/troubleshooting-spa-5a95</guid>
      <description>&lt;h2&gt;
  
  
  Does practice make perfect or practice make permanent? I was quickly able to answer &lt;strong&gt;'this'&lt;/strong&gt; after learning Javascript in just three weeks.
&lt;/h2&gt;

&lt;p&gt;Excited to get started, I began coding my single page application in one index.js file. This felt very unnatural. When that became too overwhelming I started to use es6 classes to take advantage of javascript's object oriented programming. This was not an easy task. I separated all my objects into source files and made sure they were included in the html body. The most tedious part of the project was making sure the data was being fetched correctly after abstraction. To accomplish this I had to become best friends with Ruby's pry and Chrome's debugger. Let's break it down troubleshooting a front end and a backend using my sports model. Upon page load the scripts are loaded in and the apiCall method fetchSports() is executed. This calls on the apiCall class that I abstracted to handle AJAX fetch requests.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--q5biuKiM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h466s0b1uzowlmvzov5m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q5biuKiM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h466s0b1uzowlmvzov5m.png" alt="image"&gt;&lt;/a&gt;&lt;br&gt;
 Inside the method is a fetch that triggers a get request to the rails server @ localhost:3000/sports through the variable sportUrl.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dnPM-iTq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ml69akuzv42uwef0trif.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dnPM-iTq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ml69akuzv42uwef0trif.png" alt="image"&gt;&lt;/a&gt;&lt;br&gt;
I used binding.pry here to see the params being sent from the fetch request and I'm able to see that rails has routed the request to my index action with the following params. So far so good.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vIN-vH9C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m2ju6he77lffbixcu321.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vIN-vH9C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m2ju6he77lffbixcu321.png" alt="Screen Shot 2021-04-19 at 3.57.46 PM"&gt;&lt;/a&gt;&lt;br&gt;
From here I set a local variable sports equal to Sport.all an active record method to pull all sports from the database. The controller then calls on fastJSON's sport serializer. This class then wraps the sports variable into a big string to be sent back to the front end. Whats sent is a fetch promise with a response object. The response object holds all of data from the backend sports model. I used debugger here in the fetch to see the data &lt;code&gt;data['data']&lt;/code&gt;. Now it's time to compare the response data to the data from localhost:3000/sports.&lt;br&gt;
Sports Fetch:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eXXtKPgk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ji6v763zlcu6akld9ftd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eXXtKPgk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ji6v763zlcu6akld9ftd.png" alt="image"&gt;&lt;/a&gt;&lt;br&gt;
Local Host:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mFtecwhJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tq582qpdhg4f9sx8nowi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mFtecwhJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tq582qpdhg4f9sx8nowi.png" alt="image"&gt;&lt;/a&gt; &lt;br&gt;
Chrome Console:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4K-Dm1-a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wqko2jvx6fmx54ag9878.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4K-Dm1-a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wqko2jvx6fmx54ag9878.png" alt="image"&gt;&lt;/a&gt; &lt;br&gt;
Looking at Chrome console the array of sports objects from the promises response mirror the backend data. We can see that the objects are ready to be iterated over, instantiated/deconstructed and then rendered on the dom. &lt;br&gt;
Instantiation:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ByZMw1m7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u65q7d6kbn0agucheuwh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ByZMw1m7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u65q7d6kbn0agucheuwh.png" alt="image"&gt;&lt;/a&gt;&lt;br&gt;
Load:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--U3ebO7Ci--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xwfez7fu1agcawk67hms.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--U3ebO7Ci--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xwfez7fu1agcawk67hms.png" alt="image"&gt;&lt;/a&gt;&lt;br&gt;
Render:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--enqrb6BQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x3uoinvec1cevttenxsb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--enqrb6BQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x3uoinvec1cevttenxsb.png" alt="image"&gt;&lt;/a&gt;&lt;br&gt;
Since the data matched up I'm able to focus on creating the next controller, model and view. Then the cycle repeats. When I originally started the project I constantly had to double check permitted params, and serializer attributes. It's also worth noting that formatting your api endpoint data or seed data will greatly benefit structure for fetches. Using debugger helped make sense of the fetch request documentation I was learning. This also helped me understand how rails and javascript are communicating. Theres a lot of moving parts with single page applications. If you are able to practice working with the data each step of the way, you can manipulate it to your needs. Practice makes permanent. Take the time to practice using the tools given and you can troubleshoot anything. &lt;/p&gt;

&lt;p&gt;Cover Image by &lt;a href="https://pixabay.com/users/milivigerova-742747/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=2082937"&gt;Milada Vigerova&lt;/a&gt; from &lt;a href="https://pixabay.com/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=2082937"&gt;Pixabay&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>ruby</category>
      <category>rails</category>
      <category>api</category>
    </item>
    <item>
      <title>The Rails Rollercoaster</title>
      <dc:creator>John Glennan</dc:creator>
      <pubDate>Sat, 20 Mar 2021 15:58:58 +0000</pubDate>
      <link>https://dev.to/glennanj1/the-rails-rollercoaster-12cl</link>
      <guid>https://dev.to/glennanj1/the-rails-rollercoaster-12cl</guid>
      <description>&lt;p&gt;Rails is so complex it took me a day alone to think about structure. What is a good rollercoaster without a solid foundation? Between my data base, seed data, and models themselves I knew this wouldn't be easy. The challenge: Deciding which routes to take (no pun intended). My initial thought was to nest all routes that had a relationship. 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;schema.rb

create_table "bets", force: :cascade do |t|
    t.boolean "placed"
    t.datetime "time"
    t.integer "odds"
    t.integer "event_id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "betslips", force: :cascade do |t|
    t.boolean "placed"
    t.integer "amount"
    t.string "status"
    t.integer "bet_id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "events", force: :cascade do |t|
    t.string "name"
    t.datetime "time"
    t.integer "league_id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "leagues", force: :cascade do |t|
    t.string "name"
    t.integer "sport_id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "sports", force: :cascade do |t|
    t.string "name"
    t.string "type"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
    resources: sports, only: [:index] do 
      resources: leagues, only: [:index] do
        resources: events, only: [:index, :show] do 
          resources: bets, shallow: true do 
            resources: betslip, shallow: true 
          end
        end
      end
    end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7_zb3Ihx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bstpmth2ctkos9d21ac6.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7_zb3Ihx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bstpmth2ctkos9d21ac6.jpeg" alt="Alt Text"&gt;&lt;/a&gt;As you can see this could get very complicated, very quickly. I thought back to my school lessons and did some googling. The general rule of thumb is routes should never go more than one level deep. This made sense, it was time for a complete make over. I started by connecting to an api endpoint then structured my database, routes and relationships. Using this convention I was able to separate concerns and make restful routing much less complicated. 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;
  create_table "bets", force: :cascade do |t|
    t.integer "odd_id"
    t.integer "user_id"
    t.integer "amount"
    t.string "team"
    t.integer "odds"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "odds", force: :cascade do |t|
    t.integer "sport_id"
    t.string "sport_key"
    t.string "sport_nice"
    t.string "teams"
    t.string "home_team"
    t.datetime "commence_time"
    t.string "site_and_odds"
    t.string "odds"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "sports", force: :cascade do |t|
    t.string "key"
    t.boolean "active"
    t.string "group"
    t.string "details"
    t.string "title"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
  resources :sports, only: [:index] do
    resources :odds, only: [:index]
  end

  resources :odds, only: [:show] do 
    resources :bets, shallow: true
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running &lt;code&gt;rake routes&lt;/code&gt; before the restructure gave me a huge daisy chain of path helpers that were practically unreadable. The make over enabled me to accomplish my goal and continue to practice restful convention. &lt;/p&gt;

&lt;p&gt;Picture Credit: Pixabay Image by &lt;a href="https://pixabay.com/users/jackkoppa-1144334/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=818322"&gt;Jack Koppa&lt;/a&gt; from &lt;a href="https://pixabay.com/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=818322"&gt;Pixabay&lt;/a&gt;&lt;br&gt;
Image by &lt;a href="https://pixabay.com/users/eak_kkk-907811/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=1044889"&gt;Eak K.&lt;/a&gt; from &lt;a href="https://pixabay.com/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=1044889"&gt;Pixabay&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>routes</category>
      <category>nesting</category>
    </item>
    <item>
      <title>Sinatra MVC CRUD Bet Tracker</title>
      <dc:creator>John Glennan</dc:creator>
      <pubDate>Mon, 08 Feb 2021 15:37:51 +0000</pubDate>
      <link>https://dev.to/glennanj1/sinatra-mvc-crud-bet-tracker-3bhk</link>
      <guid>https://dev.to/glennanj1/sinatra-mvc-crud-bet-tracker-3bhk</guid>
      <description>&lt;p&gt;My first DSL project is complete! This project follows an MVC architecture that is able to create, read, update and delete objects. My web apps scope focuses on the creation of bets and displays them for all users to see. Users are only allowed to create, edit and delete their bets but have the viewing pleasure to see other users placed bets. After table creation/migration it was time to test and seed some data. One of my favorite gems is called Faker. It helped me create fake data and 'seed' it into my project. This gem has so much to offer. You can use it to test relationships to see that they work as expected. Users have many Bets and Bets belong to a User. This relationship fostered by active records macro mechanics, made it possible for me to create users and their associated bets using the seed file (db/seeds.rb). 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;10.times do 
    User.create!(username: Faker::Name.name, password_digest: BCrypt::Password.create('1234'))
end 

10.times do 
    Bet.create!(amount: rand(100), team: Faker::Sports::Football.team, date: "Today", user: User.offset(rand(10)).first)
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How exactly do you seed data? You can seed data using a built in rake task 'rake db:seed'. So how do you test these relationships? I used a custom rake task in my rakefile that uses the pry gem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;task :console do 
   Pry.start
end 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I then proceeded to make sure that my relationships were working as expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;u = User.first
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This returned my first User! Perfect! Now to test and see if he has any seeded bets:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Vu16YeJr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/o4imrp9wbm533hy9ijpm.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Vu16YeJr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/o4imrp9wbm533hy9ijpm.JPG" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
Awesome! It worked. I was now able to continue coding and create my controllers and views. To use faker in your project all you need to do is add gem 'faker' to your gemfile. I suggest reading fakers documentation (link: &lt;a href="https://github.com/faker-ruby/faker"&gt;https://github.com/faker-ruby/faker&lt;/a&gt;). If you use bundler make sure to bundle install. You can even use IRB to play around with the faker gem. Cheers!&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>sinatra</category>
      <category>mvc</category>
      <category>crud</category>
    </item>
    <item>
      <title>Sinatra Sports App CRUD MVC</title>
      <dc:creator>John Glennan</dc:creator>
      <pubDate>Mon, 26 Oct 2020 02:07:43 +0000</pubDate>
      <link>https://dev.to/glennanj1/sinatra-sports-app-crud-mvc-2jmb</link>
      <guid>https://dev.to/glennanj1/sinatra-sports-app-crud-mvc-2jmb</guid>
      <description>&lt;p&gt;I used corneal to generate the file structure for my first Sinatra app. This structure helped me prepare for the long route ahead. I started making sure my active record gem was set to version 5.2. It runs better with sqlite. I then went ahead and created a simple user table and bets table and migrated them using rake. I then made sure my models were in place (user and bet) and inheriting from active records base. My models also have relationships to each other. For example my bet class belongs to users and my users have many bets. I seeded fake data and made sure that my associations were working correctly using my custom rake console. Rake console has helped me a lot especially when I need to look up methods on my created objects. I then began to meticulously use my HTTP verbs I learned, and routed out my controllers and corresponding embedded ruby views. These views present the user with an interface. Running shotgun allows you to visit localhost:9393 where the development site lives. This app allows you to keep track of sports wagers placed on games. I'm proud of how far I've come. This simple app has a lot of potential and plan to continue working on it in the next framework Rails.  &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Parsing the Interwebs</title>
      <dc:creator>John Glennan</dc:creator>
      <pubDate>Fri, 25 Sep 2020 20:51:04 +0000</pubDate>
      <link>https://dev.to/glennanj1/parsing-the-interwebs-4bk2</link>
      <guid>https://dev.to/glennanj1/parsing-the-interwebs-4bk2</guid>
      <description>&lt;p&gt;My first cli project I created from scratch used Nokogiri. I found that using the The Bastards Book of Ruby was a great resource. I highly recommend checking out their website to refer to, if your looking to make a web scraper cli. Grabbing css selectors for the first time was not an easy task. The internet is deep and so are its selectors. You might be asking yourself how do you grab selectors? Using Nokogiri a ruby gem you parse the url creating nodes that you can then iterate over and use to present data to the end user. If you inspect the page and grab the css selector from the html you parsed, you can grab very specific data. I found that not every website could be scraped and that was my biggest setback. As a beginner in software development sometimes its better to take a step back, realizing that its not your fault your not getting the results you expect. The key here is to keep trying and don't give up. You will produce results with perseverance and patience.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>scraping</category>
      <category>beginners</category>
      <category>nokogiri</category>
    </item>
  </channel>
</rss>
