<?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: JesseNReynolds</title>
    <description>The latest articles on DEV Community by JesseNReynolds (@jessenreynolds).</description>
    <link>https://dev.to/jessenreynolds</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%2F476961%2Fdbaa1572-b351-436c-84e0-4b6e6e263cd7.png</url>
      <title>DEV Community: JesseNReynolds</title>
      <link>https://dev.to/jessenreynolds</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jessenreynolds"/>
    <language>en</language>
    <item>
      <title>React Class vs Functional Components, Part 3: Lifecycle Methods</title>
      <dc:creator>JesseNReynolds</dc:creator>
      <pubDate>Fri, 30 Apr 2021 23:09:56 +0000</pubDate>
      <link>https://dev.to/jessenreynolds/react-class-vs-functional-components-part-3-lifecycle-methods-3k1e</link>
      <guid>https://dev.to/jessenreynolds/react-class-vs-functional-components-part-3-lifecycle-methods-3k1e</guid>
      <description>&lt;p&gt;Bad news; There's not exactly a one-to-one comparison here. Functional components have access to useEffect, which can give us most of the functionality we got from methods like componentWillUpdate, componentDidUpdate, componentDidMount, componentWillUnmount, etc, but it's not quite the same.&lt;/p&gt;

&lt;h2&gt;
  
  
  The basics
&lt;/h2&gt;

&lt;p&gt;If you want to make use of useEffect, you'll need to import it (it's a named export of React). useEffect takes a callback function and an optional array. This could be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useEffect(() =&amp;gt; console.log('You can define in line'))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const someFunction = () =&amp;gt; {
  console.log('You can pass a function')
}

useEffect(someFunction)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These examples will call the effect every time the component renders or rerenders. This could be costly, if we don't want to call the effect every time, we need to pass a dependency array&lt;/p&gt;

&lt;h1&gt;
  
  
  Dependencies
&lt;/h1&gt;

&lt;p&gt;If we only want to call the effect after the initial render, we can pass an empty dependency array to the hook.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useEffect(someFunction, [])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can also have useEffect call the effect whenever certain things change by adding those values or references to the dependency array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [name, setName] = useState('')
useEffect(someFunction, [props.someValue, name])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, we will call the effect someFunction on initial render, as well as when the value of either props.someValue or name changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cleanup
&lt;/h2&gt;

&lt;p&gt;We might have effects that require cleanup, for example an asynchronous function or subscription. In this case, we need to make sure to include a cleanup function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [name, setName] = useState('')
useEffect(() =&amp;gt; {
  someFunctionThatWillNeedCleanup()  
  return someFunctionToDoCleanup()
}, [props.someValue, name])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more information about effects and cleanup, visit &lt;a href="https://reactjs.org/docs/hooks-effect.html#effects-with-cleanup"&gt;the Effects with Cleanup section of the react docs&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>React Class vs Functional Components, Part 2: State</title>
      <dc:creator>JesseNReynolds</dc:creator>
      <pubDate>Fri, 23 Apr 2021 19:56:24 +0000</pubDate>
      <link>https://dev.to/jessenreynolds/react-class-vs-functional-components-part-2-state-31di</link>
      <guid>https://dev.to/jessenreynolds/react-class-vs-functional-components-part-2-state-31di</guid>
      <description>&lt;h2&gt;
  
  
  State
&lt;/h2&gt;

&lt;p&gt;In the before times we only had access to state methods in class components, and a controlled form for first and last name looked 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;class OurComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      givenName: '',
      surName: ''
    };
  }

    handleGivenNameChange = event =&amp;gt; {
    this.setState({
      givenName: event.target.value
    })
  }

  handleSurNameChange = event =&amp;gt; {
    this.setState({
      surName: event.target.value
    })
  }

  handleSubmit = event =&amp;gt; {
    //not relevant here, nothing will change in the body of 
    //this function unless you're dealing with a callback  
    //that references state or props
  }
  render() {
    return (
      &amp;lt;form onSubmit={this.handleSubmit(event)}&amp;gt;
        &amp;lt;input type="text"
        onChange={event =&amp;gt; this.handleGivenNameChange(event)} 
        value={this.state.givenName} /&amp;gt;
        &amp;lt;input type="text"
        onChange={event =&amp;gt; this.handleSurNameChange(event)} 
        value={this.state.surName} /&amp;gt;
      &amp;lt;/form&amp;gt;
    )
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But now we can use hooks to write functional components that are stateful. We need to import useState, and the we set one or more state variables to track state, and and a name for the function to update the state. Those variables can be directly referenced, and we can call the function to set the new value.&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, { useState } from 'react';

function OurComponent(props) {

    const [givenName, setGivenName] = useState('')

    const [surName, setSurName] = useState('')

    const handleGivenNameChange = event =&amp;gt; {
      setGivenName(event.target.value)
    }

    const handleSurNameChange = event =&amp;gt; {
      setSurName(event.target.value)
    }

    const handleSubmit = event =&amp;gt; {
      //not relevant here, nothing will change in the body of 
      //this function unless you're dealing with a callback  
      //that references state or props
    }

    render() {
      return (
        &amp;lt;form onSubmit={event =&amp;gt; handleSubmit(event)}&amp;gt;
          &amp;lt;input type="text"
          onChange={event =&amp;gt; handleGivenNameChange(event)} 
          value={givenName} /&amp;gt;
          &amp;lt;input type="text"
          onChange={event =&amp;gt; handleSurNameChange(event)} 
          value={surName} /&amp;gt;
        &amp;lt;/form&amp;gt;
      )
    }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We haven't reduced our number of lines by that much, but we have made everything more compact; referencing givenName is certainly more concise than referencing this.state.givenName. In fact, now that our variables are more terse, we could do a little refactoring here that would have left some longer, hard to read lines in the class component...&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, { useState } from 'react';

function OurComponent(props) {

    const [givenName, setGivenName] = useState('')

    const [surName, setSurName] = useState('')

    const handleSubmit = event =&amp;gt; {
      //not relevant here, nothing will change in the body of 
      //this function unless you're dealing with a callback  
      //that references state or props
    }

    render() {
      return (
        &amp;lt;form onSubmit={event =&amp;gt; handleSubmit(event)}&amp;gt;
          &amp;lt;input type="text"
          onChange={event =&amp;gt; setGivenName(event.target.value)} 
          value={givenName} /&amp;gt;
          &amp;lt;input type="text"
          onChange={event =&amp;gt; setSurName(event.target.value)} 
          value={surName} /&amp;gt;
        &amp;lt;/form&amp;gt;
      )
    }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This wouldn't be a good refactor if you were controlling to prevent bad inputs or to do anything complex, but we can see the sorts of refactors that having shorter ways to reference and change state opens up&lt;/p&gt;

&lt;p&gt;Come back next week for useEffect, and how it can replace the class based lifecycle methods like componentDidMount, componentWillUpdate, etc.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>React Functional vs Class Components Part 1: Props</title>
      <dc:creator>JesseNReynolds</dc:creator>
      <pubDate>Sat, 17 Apr 2021 00:17:32 +0000</pubDate>
      <link>https://dev.to/jessenreynolds/react-functional-vs-class-components-part-1-props-3l3n</link>
      <guid>https://dev.to/jessenreynolds/react-functional-vs-class-components-part-1-props-3l3n</guid>
      <description>&lt;h1&gt;
  
  
  The Times, They are a Changin'
&lt;/h1&gt;

&lt;p&gt;If you, like me, learned React with class components doing all the lifting you may be wondering what's new with these functional components and their hooks that people are talking about? Maybe when you were learning React the curriculum you were following said to use functional components when you didn't need state or access to lifecycle methods. Now you're looking at React again and people are talking about hooks and how functional components are &lt;strong&gt;&lt;em&gt;SO MUCH BETTER&lt;/em&gt;&lt;/strong&gt;. What happened?&lt;/p&gt;

&lt;p&gt;In React 16.8, hooks were introduced. Don't worry, though, the stuff you learned about React is still true. There's no big shakeups to how class components work, though you may run into a deprecated method here and there. So don't worry, you didn't just inherit a huge technical debt on that side project you used react for a while back and want to add a feature to now.&lt;/p&gt;

&lt;p&gt;React's bread and butter are props and state, we'll address how functional and class components deal with props in this article, then we'll address state, and finally lifecycle methods in their own posts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Props
&lt;/h2&gt;

&lt;p&gt;Just as a refresher, when you pass props to a class component it 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;&amp;lt;OurComponent color={'purple'}/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Good news, no change there! It doesn't matter if you're declaring a class or functional component, you pass it props the same way.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Welcome extends React.Component {
  render() {
    return &amp;lt;h1&amp;gt;Hello, {this.props.color}&amp;lt;/h1&amp;gt;;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a class component props are handled by the constructor method from React.Component and we reference them with &lt;code&gt;this.props.color.&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function OurComponent(props) {
  return &amp;lt;h1&amp;gt;Hello, {props.color}&amp;lt;/h1&amp;gt;;
}

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

&lt;/div&gt;



&lt;p&gt;In a functional component, we accept props as an argument to the top level function, and can reference the color key in the props object with &lt;code&gt;props.color&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next week, we'll tackle state! Be excited, because we're going to meet our first functional hooks.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>My Experience with Flatiron School</title>
      <dc:creator>JesseNReynolds</dc:creator>
      <pubDate>Thu, 25 Mar 2021 22:11:57 +0000</pubDate>
      <link>https://dev.to/jessenreynolds/my-experience-with-flatiron-school-pek</link>
      <guid>https://dev.to/jessenreynolds/my-experience-with-flatiron-school-pek</guid>
      <description>&lt;p&gt;I've now completed my final project review, and am starting to look for jobs. It seems like so long ago and also only yesterday that I started the Flatiron School Software Engineering program. I've learned so much, met some wonderful people, and developed a passion for development and the ability to solve problems and build solutions that I have been able to acquire so far.&lt;/p&gt;

&lt;p&gt;The curriculum can be frustrating at points, parts almost seemed out of order. The majority of it, though, is good. Most lessons were well written, with good supplementary information linked in case the student is struggling. The curriculum did a great job teaching concepts, which, I've been told by people I know in the field some bootcamps miss on. It sounds cheesy, but I really do feel the curriculum did a good job of teaching how to think like a software engineer and not just someone who can only regurgitate the patterns they've seen before.&lt;/p&gt;

&lt;p&gt;I know a lot of bootcamps have moved to 100% javascript, but I am very happy to have learned Ruby and Rails on the way. Seeing how similar concepts are handled by different languages helps peel back the layers and see the workings with more context. Rails is also an incredibly streamlined back-end for personal projects that I'm sure I'll use again even if I land in a shop with a different stack.&lt;/p&gt;

&lt;p&gt;I know that this is just the start of a career, and there's so much left to learn and to explore, but I feel I have been well prepared to continue that exploration on my own, or in the context of a professional team. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>In which I Sing the Praises of Redux Toolkit</title>
      <dc:creator>JesseNReynolds</dc:creator>
      <pubDate>Thu, 18 Mar 2021 21:52:21 +0000</pubDate>
      <link>https://dev.to/jessenreynolds/in-which-i-sing-the-praises-of-redux-toolkit-5327</link>
      <guid>https://dev.to/jessenreynolds/in-which-i-sing-the-praises-of-redux-toolkit-5327</guid>
      <description>&lt;p&gt;Using Redux to store data that will be used across components has obvious advantages, but it also comes with some specific (at least potential) drawbacks.&lt;/p&gt;

&lt;p&gt;Configuring, accessing, and updating the store all become significantly more dense as the store grows. This leads to an increasingly complex configuration and larger and larger chunks of boilerplate, not to mention the increase in potential for bugs that could become harder to trackdown in a dense and not inherently well managed codebase.&lt;/p&gt;

&lt;p&gt;Enter Redux Toolkit. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First let's talk about some bonuses:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Redux Toolkit adds an immutability (courtesy of Immer) layer to take some of the mental overhead out of writing dispatches&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Redux Toolkit by default utilizes Redux Devtools to make it easy to view state and its changes during development. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Redux Toolkit makes it easy to configure the store and easy to access and update only the parts of the store that any component needs to interact with. Each top-level segment of the store can be extracted to its own file, and much of the boilerplate can be abstracted away. These segments are referred to as &lt;a href="https://redux-toolkit.js.org/api/createSlice"&gt;slices&lt;/a&gt;. By thinking of each of these as their own mini store, and compartmentalizing them, we can separate the concerns of the various parts of the store and then bring them together easily when we &lt;a href="https://redux-toolkit.js.org/api/configureStore"&gt;configureStore&lt;/a&gt;. Since we can do so without the need for a root reducer, any troubleshooting later is that little bit less taxing. &lt;/p&gt;

&lt;p&gt;By bringing convention to the whole system, we can more quickly navigate to the code we're looking for, and make modifications to the codebase with less lines of code and less potential for errors. Those cleaner sections of code will also be easier for other developers to find, understand, and add to later. Our system will be easier to develop with, since we can use Redux DevTools to watch our state.&lt;/p&gt;

&lt;p&gt;I realize I haven't shown any references in this post, that's because I could not hope to give a better understanding of using Redux Toolkit than the documentation does by going through &lt;a href="https://redux-toolkit.js.org/tutorials/quick-start"&gt;a sample project&lt;/a&gt;. Please, if you are starting a project and plan to use Redux, have a look at Redux Toolkit. Consider if it's right for your project. The ease of use, scalability, and convenience have absolutely made me a fan.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Iteratively Creating Select Options in JavaScript</title>
      <dc:creator>JesseNReynolds</dc:creator>
      <pubDate>Wed, 03 Feb 2021 22:24:37 +0000</pubDate>
      <link>https://dev.to/jessenreynolds/what-creating-select-menus-taught-me-about-javascript-4fei</link>
      <guid>https://dev.to/jessenreynolds/what-creating-select-menus-taught-me-about-javascript-4fei</guid>
      <description>&lt;p&gt;I recently completed a Vanilla JavaScript app that charts music in a modified form of the &lt;a href="https://en.wikipedia.org/wiki/Nashville_Number_System"&gt;Nashville Number System&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;The composition is handled by a form that is a bunch of grouped selects, each measure is divided into two half measures which each have two selects representing interval from the tonic and any character modifications to the chord. The form is generated from a JSON object stored in a database row on my back end, and when modified and saved the form is transformed into a JSON object to be persisted in the same way.&lt;/p&gt;

&lt;p&gt;The thing I want to talk about in this article, though, is the selects themselves. As you can see, even in a fairly simple song, there are a lot of them.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CsAztm1H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pfqyui5m1ea16tpvylve.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CsAztm1H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pfqyui5m1ea16tpvylve.png" alt="Intervals of chords"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;And each of them has a lot of options. In the future, the second set of options, the chord modifiers, might well be expanded upon or referenced elsewhere, so we need to make sure that if there's an update to the supported modifiers it's an easy update in our app.&lt;/p&gt;

&lt;p&gt;I addressed both concerns (the large list of options, and the probability that list would be added to later) by making each of these lists of options into arrays and then adding them to the selects when the selects are created and appended to the DOM.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const INTERVALS = ["", "1", "b2", "2", "b3", "3", "b4", "4", "b5", "5", "b6", "6", "b7", "7"]
const MODIFIERS = ["", "maj", "min", "maj7", "min7", "maj9", "min9", "dim"]

...

    static buildSelectsFromHalfMeasure(halfMeasure, targetDiv) {
        const intervalSelect = document.createElement('select')
        targetDiv.appendChild(intervalSelect)

        const modifierSelect = document.createElement('select')
        targetDiv.appendChild(modifierSelect)

        INTERVALS.forEach(interval =&amp;gt; {
            const option = document.createElement('option')
            option.text = interval
            intervalSelect.add(option)
        })

        MODIFIERS.forEach(modifier =&amp;gt; {
            const option = document.createElement('option')
            option.text = modifier
            modifierSelect.add(option)
        })

        intervalSelect.value = halfMeasure["interval"]
        modifierSelect.value = halfMeasure["modifier"]

        intervalSelect.addEventListener('change', Song.addSaveButtonIfNonePresent)
        modifierSelect.addEventListener('change', Song.addSaveButtonIfNonePresent)
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For each half measure, we create a div. We append that div to the div that belongs to the measure, and to the half-measure div, we append two selects, then we iterate over our list of intervals and modifiers to populate the options for the selects. If in the future I want to add seemingly bizarre chord modifiers like "13sus4add2" I can do that in one place and know that everywhere I'm referencing all available modifiers, it's been addressed.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>A simple MVC group invite feature in rails.</title>
      <dc:creator>JesseNReynolds</dc:creator>
      <pubDate>Thu, 07 Jan 2021 05:34:14 +0000</pubDate>
      <link>https://dev.to/jessenreynolds/a-simple-mvc-group-invite-feature-in-rails-5h4g</link>
      <guid>https://dev.to/jessenreynolds/a-simple-mvc-group-invite-feature-in-rails-5h4g</guid>
      <description>&lt;h1&gt;
  
  
  First, a quick introduction
&lt;/h1&gt;

&lt;p&gt;I struggle with these blogs. For those not following along at home, I'm doing a development bootcamp; one of the requirements is to do a technical blog after each milestone project. It's a struggle for me because I've been coding in earnest for all of 3 months now; what could I have to say that anyone would, could, or should care about?&lt;/p&gt;

&lt;p&gt;I reached out to some of my friends in the program and asked them to have a look at my project, OpenStage (be patient if it takes a moment to spin up, it's hosted on heroku) and tell me if there was anything they wanted to know about. My friend Bella said she'd like to know more about how I managed the invitations to bands, so that's what this blog will be about. At least I know there's one person who will think it's interesting.&lt;/p&gt;

&lt;h1&gt;
  
  
  Invites?
&lt;/h1&gt;

&lt;p&gt;Yeah, so my app has a few goals.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Help musicians form bands&lt;/li&gt;
&lt;li&gt;Help bands find open stage time to play casual gigs&lt;/li&gt;
&lt;li&gt;Help venues draw traffic by having bands play&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To have bands, which are made of multiple Muscians (users of class User in my models), you need to be have a join table. There are a number of questions to be asked about how to handle who has privileges in a band, but for this demonstration I decided the user that created the band (the band leader) would have the unilateral power to request gigs and invite members. We'll need a join table so that users can have many bands and bands can have many users, and we've called this join table band_members.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class BandMember &amp;lt; ApplicationRecord

belongs_to :user
belongs_to :band

validates_uniqueness_of :user_id, scope: :band_id
end

class User &amp;lt; ApplicationRecord

has_secure_password

has_many :lead_bands, class_name: "Band", foreign_key: :leader_id
has_many :band_members
has_many :bands, through: :band_members
has_many :gigs, through: :bands

validates :name, presence: true 
validates :email, presence: true 
validates :email, uniqueness: true
end

class Band &amp;lt; ApplicationRecord

belongs_to :leader, class_name: "User", foreign_key: :leader_id
has_many :band_members
has_many :users, through: :band_members
has_many :gigs

validates :name, presence: true

def empty_roster
    self.band_members.each do |band_member|
        band_member.delete
    end
end

def unclaim_all_gigs
    self.gigs.each do |gig|
        gig.band_id = nil
        gig.status = nil
        gig.save
    end
end

def clear_associations_before_deletion
    self.empty_roster
    self.unclaim_all_gigs
end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Wait, I thought you were going to talk about your invite model?
&lt;/h1&gt;

&lt;p&gt;There's no invite model. Let me explain.&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 "band_members", force: :cascade do |t|
    t.integer "band_id"
    t.integer "user_id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.string "status"
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's no invite model, because a band_member entry with status= "Pending" is an invite.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class UsersController &amp;lt; ApplicationController

...

  def invite_member
    user = User.find(params[:user_id])
    invite = BandMember.new(user_id: params[:user_id], band_id: params[:band_id], status: "pending")
    if invite.save
      redirect_to user, notice: "Invite sent."
    else
      redirect_to user, notice: "Either something went wrong, or this user is already in that band. Please try again later."
    end
  end

  def invites
  end

  def accept_invite
    invite = BandMember.find(params[:id])
    invite.status = "Accepted"
    if invite.save
      redirect_to invite.band, notice: "You've joined #{invite.band.name}."
    else
      redirect_to invites_path, notice: "An error occured, please try again later."
    end
  end

 ...

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

&lt;/div&gt;



&lt;p&gt;"Invites" are just BandMember records with status "Pending", which, when initially created, all BandMember records are (with the exception of the record that is created for the band leader, which happens when the band is created). A user has to post to the accept invite path to change the status of the record to "Accepted"&lt;/p&gt;

&lt;p&gt;Users interact with these controller actions from the views:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;views/users/show.html.erb
...
&amp;lt;% if current_user_is_band_leader? &amp;amp;&amp;amp; current_user.id != @user.id %&amp;gt;
    &amp;lt;div class='invite-wrapper'&amp;gt;
        &amp;lt;%= form_with(url: 'bands/band_members/new', method: 'post') do |form| %&amp;gt;
            &amp;lt;%= form.hidden_field :user_id, value: @user.id %&amp;gt;
            &amp;lt;%= form.label "Invite to:" %&amp;gt; 
            &amp;lt;br&amp;gt;
            &amp;lt;%= form.collection_select(:band_id, current_user.lead_bands, :id, :name) %&amp;gt;
            &amp;lt;br&amp;gt;
            &amp;lt;%= form.submit "Invite", class: 'button' %&amp;gt;
        &amp;lt;% end %&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;% end %&amp;gt;
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When viewing a musicians show page, if the viewing user is a band leader, they get a form that's just a drop-down with the bands they lead and a button that says "Invite".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6k_L6JPy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vbagvoud3acyxllsmit6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6k_L6JPy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vbagvoud3acyxllsmit6.png" alt="A musician's show page, viewed as a band leader."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The user then has an "invite" so when they view the invites path, they see this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IrfATpHi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ec2fz9hqkdawt4q0ky8q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IrfATpHi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ec2fz9hqkdawt4q0ky8q.png" alt="A user's invite page with a pending invite."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If they accept, the form is submitted to the accept invite path, and the entry for the associated BandMember record is updated, and those updates are persisted.&lt;/p&gt;

&lt;p&gt;The user is redirected to the page for the band that they've joined, and a button to leave the band is now present, so that they have the ability to un-join, as it where.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GQAfpcVz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/v0it2bmvx3o7tkhpyped.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GQAfpcVz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/v0it2bmvx3o7tkhpyped.png" alt="A logged in user's view of a show page for a band which they are a member of."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that is, more or less, the life-cycle of an invite in this model. A user can't decline an invite, they can only let it sit unaccepted, because frankly figuring out how to build a protection against invite-again-on-rejection-abuse seemed like a big hassle to include in the MVP.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Iterating to create dynamic web elements.</title>
      <dc:creator>JesseNReynolds</dc:creator>
      <pubDate>Sun, 22 Nov 2020 23:06:31 +0000</pubDate>
      <link>https://dev.to/jessenreynolds/iterating-to-create-dynamic-web-elements-2pbj</link>
      <guid>https://dev.to/jessenreynolds/iterating-to-create-dynamic-web-elements-2pbj</guid>
      <description>&lt;p&gt;I have a confession to make: I hate writing these blog posts. It's not as though I'm going to have some greate contribution to make to the understanding of software development at this point. I've been doing it all of two months, and although I think I'm doing well, I'm certainly no expert. Nothing I do here is going to be truly novel or innovative; clever, maybe, at best.&lt;/p&gt;

&lt;p&gt;So anyway, let me walk you through some of the hopefully clever workflows I developed in this project.&lt;/p&gt;

&lt;p&gt;By using the attributes of ruby objects that mimic database rows and iterating over collections of those objects, we can dynamically create elements on our webpage that contain the data of our database in visually pleasing ways. If we want to display all books, for example this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9CTf6p8---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/px40gpxxja81s9tap86n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9CTf6p8---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/px40gpxxja81s9tap86n.png" alt="an ERB file that iterates over books and generates &amp;lt;a&amp;gt; tags with information displayed in card-format"&gt;&lt;/a&gt;&lt;br&gt;
(please forgive the improper class name formatting)&lt;br&gt;
and this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AUwUhRR1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pj6bymj9v3urg3o9xo8d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AUwUhRR1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pj6bymj9v3urg3o9xo8d.png" alt="css rules to style the a tags as flex-elements"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;becomes this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PGMVLrG7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/trnpxy9m7p6upsj8masp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PGMVLrG7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/trnpxy9m7p6upsj8masp.png" alt="a bunch of flex clickable flex objects that contain information about a book"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The thing I'm most proud of achieving in this view is probably that each of those book card elements is actually an a-tag that's modified to be a flex-box object, meaning I have modern feeling "clicky-divs" without using any javascript, and because each of these cards is generated from database data, what cards you'll get is determined by what books are represented on the database. If a user adds a book, it just shows up, and if a user removes a book, it just won't be there next time you load the page.&lt;/p&gt;

&lt;p&gt;It's not an earth-shattering idea, I'm sure someone else has done this before. But hey, I think it's clever, and there's a lot of places on this app that I got to create a solution to a problem like "how should I display all the books?" and when I had the solution working and styled I thought to myself "hey, that looks good, and the way it happens is pretty clever".&lt;/p&gt;

&lt;p&gt;I guess what I'm saying is that when talking about the adventure of learning to code, maybe the real treasure is all the "heh, I'm clever" moments we had along the way. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>My first project </title>
      <dc:creator>JesseNReynolds</dc:creator>
      <pubDate>Sat, 24 Oct 2020 00:37:01 +0000</pubDate>
      <link>https://dev.to/jessenreynolds/my-first-project-3lpd</link>
      <guid>https://dev.to/jessenreynolds/my-first-project-3lpd</guid>
      <description>&lt;p&gt;When I signed up for Flatiron School, I started keeping a little idea log for apps to build. I opened that idea log up when it was time to plan my first project, and I grabbed one I thought would be fun and could be factored well into the project requirements. What I found surprising was how quickly my minimum viable product came together! Sure, it didn't check off all the boxes I wanted to, but it did what the app wants to do at it's heart.&lt;/p&gt;

&lt;p&gt;From there it was a matter of adding features, refactoring things that are not best practices, improving the interface, streamlining the logic, etc.&lt;/p&gt;

&lt;p&gt;What seemed a few weeks ago like it would be a big job seems easy now, at least in recollection. Of course there were moments of frustration; there were things that made me confused, things that I just  &lt;strong&gt;could not&lt;/strong&gt; get working for the longest time, but every time I checked something off my features wish-list, I got a nice hit of dopamine that made the whole process very enjoyable.&lt;/p&gt;

&lt;p&gt;It's not perfect, it's not finished &lt;strong&gt;&lt;em&gt;but it works, and I built it&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I learned some stuff, like using a while loop to control for answers to prompts that aren't understandable or would create problems down the line, instead of using recursion.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def filter_price
        complete = false

        while complete == false
            puts "Do you want to filter by price? (y/n)"
            answer = gets.chomp
            if answer.downcase == "y" || answer.downcase == "yes"
                puts "Restaurants are given price ranges from 1 to 4, where 4 is the highest."

                puts "Please enter a minimum price range from 1 to 4 (decimals NOT OK!)"
                min_price = gets.chomp.to_i

                puts "Please enter a maximum price range from 1 to 4(decimals NOT OK!)"
                max_price = gets.chomp.to_i

                complete = true

                if min_price &amp;gt; max_price 
                    puts "Please enter a maximum price range that is higher than or equal to your minimum price range."
                    complete = false
                end

            elsif answer.downcase == "n" || answer.downcase == "no"
                min_price = 1
                max_price = 4
                complete = true
            else
                puts "Sorry, I don't understand, please respond with y or n"
            end
        end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I got more practice writing methods from scratch, passing data around, creating objects with that data, and iterating over the objects to actually &lt;strong&gt;do stuff&lt;/strong&gt; with the data inside.&lt;/p&gt;

&lt;p&gt;The jump from the JSON data that Yelp returned to properly instantiated data attached to objects created a fun challenge that I was able to solve with meta-programming to help improve scalability and compatibility in the future.&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.new_from_json(parsed_data)
        parsed_data["businesses"].each do |business|
            new_restaurant = Restaurants.new

            business.each do |key, value|
                new_restaurant.class.send(:attr_accessor, "#{key}")
                # creates attr_accessor for each key in the imported hash  
                new_restaurant.send("#{key}=", value)
            end

            new_restaurant.save
        end
    end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Overall, I think my favorite part of having the chance to do something like this, to build something that I wanted, see the finished product work, and even using it here and there in my daily life, is a familiar feeling in an odd way. I've long been an advocate in my personal life for productive hobbies like leatherworking, woodworking, sewing, or knitting. I think so often we live lives of abstract productivity, rarely seeing a product or process through from start to finish, and there's great empowerment in the manifestation of something from material and desire. The fact that that feeling of empowerment and achievement is present in developing code makes me feel more certain that I've made a choice in changing careers that will bring great satisfaction to my life; and I think that's really pretty cool.&lt;/p&gt;

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