<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://bridgetownrb.com/" version="1.1.0">Bridgetown</generator><link href="https://jasoncharnes.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://jasoncharnes.com/" rel="alternate" type="text/html" /><updated>2025-07-09T18:04:43+00:00</updated><id>https://jasoncharnes.com/feed.xml</id><title type="html">Jason Charnes</title><subtitle>Jason Charnes is Ruby developer in Memphis, TN. He is a co-host on the Remote Ruby Podcast and an organizer of Southeast Ruby.</subtitle><author><name>Jason Charnes</name></author><entry><title type="html">2022 Wish list</title><link href="https://jasoncharnes.com/uncategorized/2022/01/01/2022-wishlist/" rel="alternate" type="text/html" title="2022 Wish list" /><published>2022-01-01T00:00:00+00:00</published><updated>2022-01-01T00:00:00+00:00</updated><id>repo://posts.collection/_posts/2022-01-01-2022-wishlist.md</id><content type="html" xml:base="https://jasoncharnes.com/uncategorized/2022/01/01/2022-wishlist/">&lt;p&gt;I’m not good at resolutions. Instead, I made a wish list of things I’d like to do in 2022.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Make better choices for my mind and body
    &lt;ul&gt;
      &lt;li&gt;Less junk food&lt;/li&gt;
      &lt;li&gt;Less alcohol&lt;/li&gt;
      &lt;li&gt;Less complaining&lt;/li&gt;
      &lt;li&gt;More meditation&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Detach from iPhone/internet more often
    &lt;ul&gt;
      &lt;li&gt;Less scrolling&lt;/li&gt;
      &lt;li&gt;Less entertainment&lt;/li&gt;
      &lt;li&gt;Less screen time&lt;/li&gt;
      &lt;li&gt;More utility&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Be present for my family and friends
    &lt;ul&gt;
      &lt;li&gt;Less iPhone&lt;/li&gt;
      &lt;li&gt;Less “not now, son”&lt;/li&gt;
      &lt;li&gt;More date nights&lt;/li&gt;
      &lt;li&gt;More conversations&lt;/li&gt;
      &lt;li&gt;More attention&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Spend less money
    &lt;ul&gt;
      &lt;li&gt;Less impulses&lt;/li&gt;
      &lt;li&gt;Less debt&lt;/li&gt;
      &lt;li&gt;More intentionality&lt;/li&gt;
      &lt;li&gt;More saving&lt;/li&gt;
      &lt;li&gt;More giving&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Donate more unused items
    &lt;ul&gt;
      &lt;li&gt;Less clutter&lt;/li&gt;
      &lt;li&gt;More empty space&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Create a valuable product
    &lt;ul&gt;
      &lt;li&gt;Less ideas&lt;/li&gt;
      &lt;li&gt;More problem solving&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;</content><author><name>Jason Charnes</name></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jasoncharnes.com/images/sharing.png" /><media:content medium="image" url="https://jasoncharnes.com/images/sharing.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Disabling Rails Generators</title><link href="https://jasoncharnes.com/disabling-rails-generators/" rel="alternate" type="text/html" title="Disabling Rails Generators" /><published>2021-08-04T00:00:00+00:00</published><updated>2021-08-04T00:00:00+00:00</updated><id>repo://posts.collection/_posts/2021-08-04-disabling-rails-generators.md</id><content type="html" xml:base="https://jasoncharnes.com/disabling-rails-generators/">&lt;p&gt;I love spinning up a Rails controller using &lt;code&gt;rails g controller&lt;/code&gt;. I don’t love all the files it brings with it. I end up with a treasure trove of files I either have to manually delete or commit into my git history for all eternity.&lt;/p&gt;

&lt;p&gt;For example, I typically use Webpacker for all my assets. When I run &lt;code&gt;rails g controller&lt;/code&gt; I don’t want autogenerated stylesheets in &lt;code&gt;app/&lt;/code&gt;. I want to disable assert generation.&lt;/p&gt;

&lt;p&gt;If I’m going to use a helper I’d rather create it &lt;em&gt;when&lt;/em&gt; I need it. I want to disable helper generation.&lt;/p&gt;

&lt;p&gt;Whenever I spin up a new Rails app, I look at previous projects or search the web for how to disable certain generators. But no more, this will be my resource for it moving forward.&lt;/p&gt;

&lt;p&gt;Consider this my love letter to the Ruby on Rails config.&lt;/p&gt;

&lt;p&gt;This example is derived from the &lt;a href=&quot;https://guides.rubyonrails.org/configuring.html#configuring-generators&quot;&gt;Rails guides&lt;/a&gt;. (I updated some of the comments in the docs for brevity.)&lt;/p&gt;

&lt;p&gt;Inside &lt;code&gt;config/application.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;module YourAmazingRailsApp
  class Application &amp;lt; Rails::Application
    # ... some stuff!

    # The commented out values are using the defaults.
    # To disable a generator (that is a boolean) change it from true to false.
    # Some generators take a symbol as a value, refer to the guides for the other options.
    #
    # Feel free to copy and paste this entire block in!
    config.generators do |generate|
      # generate.assets true # create assets when generating a scaffold
      # generate.force_plural false # allow pluralized model names
      # generate.helper true # generate helpers
      # generate.integration_tool :test_unit # which tool generates integration tests (might be overwritten automatically if using rspec-rails)
      # generate.system_tests :test_unit # which tool generates system tests (might be overwritten automatically if using rspec-rails)
      # generate.orm false # which orm to use (false uses Active Record)
      # generate.resource_controller :controller # which generator generates a controller when using bin/rails generate resource
      # generate.resource_route true # generate a resource route definition
      # generate.scaffold_controller :scaffold_controller # which generator generates a controller when using bin/rails generate scaffold
      # generate.stylesheets true # generate stylesheets
      # generate.stylesheet_engine :css # configures the stylesheet engine (for e.g. sass) to be used when generating assets. Defaults to :css.
      # generate.scaffold_stylesheet true # creates scaffold.css when generating a scaffolded resource. Defaults to true.
      # generate.test_framework false # which test framework to use (false uses Minitest) (might be overwritten automatically if using rspec-rails)
      # generate.template_engine :erb # which template engine to use
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;My typical config looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;module YourAmazingRailsApp
  class Application &amp;lt; Rails::Application
    # ... some stuff!

    config.generators do |generate|
      generate.assets false # create assets when generating a scaffold
      generate.helper false # generate helpers
      generate.stylesheets false # generate stylesheets
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To learn more, visit the &lt;a href=&quot;https://guides.rubyonrails.org/configuring.html#configuring-generators&quot;&gt;Rails guides&lt;/a&gt;.&lt;/p&gt;</content><author><name>Jason Charnes</name></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jasoncharnes.com/images/sharing.png" /><media:content medium="image" url="https://jasoncharnes.com/images/sharing.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Installing React in Ruby on Rails with Webpacker</title><link href="https://jasoncharnes.com/installing-react-in-ruby-on-rails-with-webpacker/" rel="alternate" type="text/html" title="Installing React in Ruby on Rails with Webpacker" /><published>2019-12-23T00:00:00+00:00</published><updated>2019-12-23T00:00:00+00:00</updated><id>repo://posts.collection/_posts/2019-12-23-installing-react-in-ruby-on-rails.md</id><content type="html" xml:base="https://jasoncharnes.com/installing-react-in-ruby-on-rails-with-webpacker/">&lt;p&gt;So, you want to use React in a Ruby on Rails application. I’m glad you’re here! I think React is a great tool to use in your Ruby on Rails applications.&lt;/p&gt;

&lt;p&gt;I’ll help you get started. We’ll look at bootstrapping any Ruby on Rails application (that can use Webpacker) with React.&lt;/p&gt;

&lt;p&gt;Luckily, for us, Ruby on Rails makes it pretty easy to get started.&lt;/p&gt;

&lt;h3 id=&quot;installing-webpacker&quot;&gt;Installing Webpacker&lt;/h3&gt;

&lt;p&gt;If you’re using &lt;strong&gt;Rails 6&lt;/strong&gt;, no further action is required to install Webpacker. 🎉 Good job, I’m proud of you.&lt;/p&gt;

&lt;p&gt;If you’re starting a &lt;em&gt;fresh&lt;/em&gt; &lt;strong&gt;Rails 6&lt;/strong&gt; application, jump to the &lt;a href=&quot;#bonus&quot;&gt;bonus section&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you’re using &lt;strong&gt;Rails 5&lt;/strong&gt;, we’ll follow the &lt;a href=&quot;https://github.com/rails/webpacker#installation&quot;&gt;Webpacker instructions&lt;/a&gt;.&lt;/p&gt;

&lt;h5 id=&quot;a-fresh-rails-5-application&quot;&gt;A fresh Rails 5 application&lt;/h5&gt;

&lt;p&gt;If you’re starting fresh, you should consider using Rails 6. Out of the box, you’ll get Webpacker. But, If you need a new Rails 5 application, you can provide the &lt;code&gt;--webpack&lt;/code&gt; option when creating your app:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;rails new react-app --webpack
&lt;/code&gt;&lt;/pre&gt;

&lt;h5 id=&quot;an-existing-rails-5-application&quot;&gt;An existing Rails 5 application&lt;/h5&gt;

&lt;p&gt;If you’re adding Webpacker to a pre-existing Rails 5 application, add the following to your Gemfile:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;# In Gemfile
gem &quot;webpacker&quot;, &quot;~&amp;gt; 4.x&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Once you’ve run &lt;code&gt;bundle install&lt;/code&gt;, you can install Webpacker using the following command in your terminal:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;bundle exec rails webpacker:install
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;installing-react-in-ruby-on-rails&quot;&gt;Installing React in Ruby on Rails&lt;/h3&gt;

&lt;p&gt;Once again, thanks to Webpacker, this is a simple step. Rails &lt;a href=&quot;https://github.com/rails/webpacker#react&quot;&gt;gives us a command&lt;/a&gt; to run that allows us to bootstrap our application with React.&lt;/p&gt;

&lt;p&gt;Run the following command in your terminal:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;bundle exec rails webpacker:install:react
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Running this command adds React to your application, run &lt;code&gt;yarn install&lt;/code&gt;, and create a React component you can immediately use in your application.&lt;/p&gt;

&lt;h3 id=&quot;bonus&quot;&gt;Bonus&lt;/h3&gt;

&lt;p&gt;If you’re starting a brand new &lt;strong&gt;Rails 6&lt;/strong&gt; application, you can bootstrap your application with React when using &lt;code&gt;rails new&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;rails new react-app --webpack=react
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;thats-all-folks&quot;&gt;That’s all, folks&lt;/h3&gt;

&lt;p&gt;See, that wasn’t so bad. A sincere thank you to the team working on Webpacker. We couldn’t ask for a better install process for React in Ruby on Rails.&lt;/p&gt;

&lt;p&gt;If you want to dissect the component Rails just created in &lt;code&gt;app/javascript&lt;/code&gt;, &lt;a href=&quot;/dissecting-a-new-webpacker-react-component/&quot;&gt;you can join me here&lt;/a&gt;.&lt;/p&gt;</content><author><name>Jason Charnes</name></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jasoncharnes.com/images/sharing.png" /><media:content medium="image" url="https://jasoncharnes.com/images/sharing.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Dissecting a New Webpacker React Component</title><link href="https://jasoncharnes.com/dissecting-a-new-webpacker-react-component/" rel="alternate" type="text/html" title="Dissecting a New Webpacker React Component" /><published>2019-12-23T00:00:00+00:00</published><updated>2019-12-23T00:00:00+00:00</updated><id>repo://posts.collection/_posts/2019-12-23-dissecting-a-new-react-webpacker-install.md</id><content type="html" xml:base="https://jasoncharnes.com/dissecting-a-new-webpacker-react-component/">&lt;p&gt;If you’re new to React, and &lt;a href=&quot;/installing-react-in-ruby-on-rails-with-webpacker/&quot;&gt;just installed React through Webpacker in your Ruby on Rails application&lt;/a&gt;, you might have some questions.&lt;/p&gt;

&lt;p&gt;Let’s answer those questions by walking through the React component Rails and Webpacker auto-generated for us.&lt;/p&gt;

&lt;h3 id=&quot;hello-react&quot;&gt;Hello React&lt;/h3&gt;

&lt;p&gt;Rails auto generates a React component in &lt;code&gt;app/javascript/packs&lt;/code&gt; named &lt;code&gt;hello_react.jsx&lt;/code&gt;. Cute name, right?&lt;/p&gt;

&lt;p&gt;The file looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-jsx&quot;&gt;import React from &quot;react&quot;;
import ReactDOM from &quot;react-dom&quot;;
import PropTypes from &quot;prop-types&quot;;

const Hello = (props) =&amp;gt; &amp;lt;div&amp;gt;Hello {props.name}!&amp;lt;/div&amp;gt;;

Hello.defaultProps = {
  name: &quot;David&quot;,
};

Hello.propTypes = {
  name: PropTypes.string,
};

document.addEventListener(&quot;DOMContentLoaded&quot;, () =&amp;gt; {
  ReactDOM.render(
    &amp;lt;Hello name=&quot;React&quot; /&amp;gt;,
    document.body.appendChild(document.createElement(&quot;div&quot;))
  );
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Let’s break down the different pieces of this file.&lt;/p&gt;

&lt;h3 id=&quot;the-file-type&quot;&gt;The file type&lt;/h3&gt;

&lt;p&gt;If you haven’t worked with React, JSX may be an unknown file type to you. Don’t worry; we’re going to start there.&lt;/p&gt;

&lt;p&gt;JSX is a “&lt;a href=&quot;https://reactjs.org/docs/introducing-jsx.html&quot;&gt;syntax extension to JavaScript&lt;/a&gt;”. Essentially, this means JSX is a regular JavaScript file with the ability to do some templating. The React team recommends the JSX file type, and it’s the one I use when I write React code, even in Ruby on Rails.&lt;/p&gt;

&lt;p&gt;All you need to know, at this point, is that JSX files render React components. We’ll create these React components out of JavaScript and HTML.&lt;/p&gt;

&lt;p&gt;There’s an example further down, so let’s move on for now.&lt;/p&gt;

&lt;h3 id=&quot;imports&quot;&gt;Imports&lt;/h3&gt;

&lt;p&gt;The top of the file starts with “import” statements. What are these imports?&lt;/p&gt;

&lt;p&gt;ES6 brought the ability to import functionality from JavaScript modules easily. Using modules allows us to wrap JavaScript functionality inside a module and use it elsewhere throughout our application.&lt;/p&gt;

&lt;p&gt;In this file, we’re importing three libraries from our “node_modules” directory. These libraries are brought in by Yarn as declared in &lt;code&gt;package.json&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-jsx&quot;&gt;import React from &quot;react&quot;;
import ReactDOM from &quot;react-dom&quot;;
import PropTypes from &quot;prop-types&quot;;
&lt;/code&gt;&lt;/pre&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;React&lt;/strong&gt; is used for, well, React.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;ReactDOM&lt;/strong&gt; is used to render our React component(s) onto the DOM.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;PropTypes&lt;/strong&gt; is used to declare “props” in our components. We’ll talk more about this below.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you’d like to know more, I go further in-depth on ES6 modules in my free course on &lt;a href=&quot;https://jasoncharnes.podia.com/es6-essentials-for-react&quot;&gt;ES6 Essentials&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;constants-and-arrow-functions-oh-my&quot;&gt;Constants and arrow functions oh my!&lt;/h3&gt;

&lt;p&gt;If you’ve not worked with ES6 or JSX, this line of JavaScript is going to look funny.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-jsx&quot;&gt;const Hello = (props) =&amp;gt; &amp;lt;div&amp;gt;Hello {props.name}!&amp;lt;/div&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This small line of code is a potent line of JavaScript. Let’s break it down by keyword.&lt;/p&gt;

&lt;h5 id=&quot;constants&quot;&gt;Constants&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;const&lt;/code&gt; is a keyword short for constant. Once’s a constant is declared, it cannot be re-declared or re-assigned- it becomes a read-only property.&lt;/p&gt;

&lt;h5 id=&quot;hello&quot;&gt;Hello&lt;/h5&gt;

&lt;p&gt;It should come as no shock that &lt;code&gt;Hello&lt;/code&gt; is the constant’s name. However, it might be odd to you that it’s capitalized. React components are camel-cased and start with capital letters. And that’s what we’re declaring, a React component.&lt;/p&gt;

&lt;h5 id=&quot;arrow-functions&quot;&gt;Arrow functions&lt;/h5&gt;

&lt;p&gt;Okay, so let’s dissect &lt;code&gt;props =&amp;gt; ...&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We’re assigning an arrow function to the &lt;code&gt;Hello&lt;/code&gt; constant. The first keyword, &lt;code&gt;props&lt;/code&gt;, is the argument to the arrow function.&lt;/p&gt;

&lt;p&gt;The code after the arrow is the code we want to execute when we invoke this constant (or render this component).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But, this code has no brackets or &lt;code&gt;return&lt;/code&gt; keyword!&lt;/strong&gt; Because this is a single expression, we can inline the code and get an implicit return.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But, this code is just HTML!&lt;/strong&gt; Aha, welcome to JSX, which I said we talk about more. This line begins the power of JSX. We’ve defined our component to render an HTML div. JSX knows how to convert that to a div for the DOM.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But, there are curly brackets inside the div!&lt;/strong&gt; How about that? So this further shows the power of JSX. If we want to execute a JavaScript expression in HTML, we can wrap it in curly brackets. In this case, &lt;code&gt;props.name&lt;/code&gt; is a value, so the value &lt;code&gt;name&lt;/code&gt; is rendered inside this HTML. Neat, huh?&lt;/p&gt;

&lt;p&gt;So, let’s recap what we learned about this line of code.&lt;/p&gt;

&lt;!-- prettier-ignore-start --&gt;
&lt;pre&gt;&lt;code class=&quot;language-jsx&quot;&gt;const
// 👆A constant

Hello =
// 👆The constant&apos;s name

props =&amp;gt;
// 👆The function&apos;s argument and declaration

&amp;lt;div&amp;gt;Hello {props.name}!&amp;lt;/div&amp;gt;;
// 👆The HTML implicitly returned by the function, with evaluated (and rendered) JavaScript
&lt;/code&gt;&lt;/pre&gt;
&lt;!-- prettier-ignore-end --&gt;

&lt;p&gt;I swear this article isn’t a promotion for my mini-course, but it is relevant again. (And at least it’s free!) If you’d like to know more about constants and arrow functions, I cover those in my free course on &lt;a href=&quot;https://jasoncharnes.podia.com/es6-essentials-for-react&quot;&gt;ES6 Essentials&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;props&quot;&gt;Props&lt;/h3&gt;

&lt;p&gt;Now is an appropriate time to talk about “props.” Props are simple to understand, very powerful, and require more explanation than this article can provide. We’ll cover at a high-level what props are and how they fit into this component.&lt;/p&gt;

&lt;p&gt;Props are arguments to React components. Skipping ahead (just a little bit) to the bottom of the file, you’ll find the following line of code:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-jsx&quot;&gt;&amp;lt;Hello name=&quot;React&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This line is rendering our React component. There is an argument awkwardly named &lt;code&gt;name&lt;/code&gt;. The argument, here, is taking the value “React”. This prop is then available in the component.&lt;/p&gt;

&lt;p&gt;Remember The line of code returned by our Component &lt;code&gt;&amp;lt;div&amp;gt;Hello {props.name}!&amp;lt;/div&amp;gt;&lt;/code&gt;? This snippet is how we access props passed into our component. &lt;code&gt;props&lt;/code&gt; is an argument into our function (given to us by React), and then the name is accessed via &lt;code&gt;props.name&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;See, that’s not so bad?&lt;/p&gt;

&lt;p&gt;One significant caveat also outside the scope of this article: Props are read-only. You can’t mutate props. For simplicity’s sake, think of props as constants.&lt;/p&gt;

&lt;h3 id=&quot;prop-types&quot;&gt;Prop types&lt;/h3&gt;

&lt;p&gt;With your abounding knowledge of props, we can continue down the file.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-jsx&quot;&gt;Hello.defaultProps = {
  name: &quot;David&quot;,
};

Hello.propTypes = {
  name: PropTypes.string,
};
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Our component can have two properties assigned to it:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Default props&lt;/li&gt;
  &lt;li&gt;Prop types&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These are just as they sound.&lt;/p&gt;

&lt;h5 id=&quot;default-props&quot;&gt;Default props&lt;/h5&gt;

&lt;p&gt;Default props are default arguments. If someone renders the component without passing the prop, it falls back to the default value.&lt;/p&gt;

&lt;h5 id=&quot;prop-types-1&quot;&gt;Prop types&lt;/h5&gt;

&lt;p&gt;You can set the expected type of the prop using the &lt;code&gt;PropTypes&lt;/code&gt; library we imported earlier. If I give this component an integer for the name prop instead of a string, the application won’t blow up. (Unless you try to do some string-specific logic to the integer.) It will, though, log an error in the console telling you it expected a string, and you gave it an integer.&lt;/p&gt;

&lt;p&gt;This functionality is handy as your components grow in size and complexity. However, both of these prop properties are &lt;strong&gt;&lt;em&gt;optional&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h3 id=&quot;the-grand-finale&quot;&gt;The grand finale&lt;/h3&gt;

&lt;p&gt;It’s time to get our React component onto the DOM.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-jsx&quot;&gt;document.addEventListener(&quot;DOMContentLoaded&quot;, () =&amp;gt; {
  ReactDOM.render(
    &amp;lt;Hello name=&quot;React&quot; /&amp;gt;,
    document.body.appendChild(document.createElement(&quot;div&quot;))
  );
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We start by adding an everyday event listener to the DOM. Once the content is loaded, the anonymous arrow function is invoked.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ReactDom&lt;/code&gt; (the library we imported earlier) has a render method we call with two arguments:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The rendered React component (with our props)&lt;/li&gt;
  &lt;li&gt;The DOM element the component is rendered inside&lt;/li&gt;
&lt;/ol&gt;

&lt;h5 id=&quot;rendered-react-components&quot;&gt;Rendered React components&lt;/h5&gt;

&lt;p&gt;To render a React component, we wrap it in self-closing brackets, just as we would any other HTML element.&lt;/p&gt;

&lt;h5 id=&quot;the-dom-element&quot;&gt;The DOM element&lt;/h5&gt;

&lt;p&gt;In this example, we’re creating a &lt;code&gt;div&lt;/code&gt; and appending it to the body. The React component is rendered inside the &lt;code&gt;div&lt;/code&gt; and displayed in the DOM.&lt;/p&gt;

&lt;p&gt;The second argument (the DOM element) can be any DOM node JavaScript knows about. For example, we could re-write the code to use an existing DOM node:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-jsx&quot;&gt;document.addEventListener(&quot;DOMContentLoaded&quot;, () =&amp;gt; {
  ReactDOM.render(
    &amp;lt;Hello name=&quot;React&quot; /&amp;gt;,
    document.getElementById(&quot;#fancy-react-element&quot;)
  );
});
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;look-at-you-react-expert&quot;&gt;Look at you, React expert&lt;/h3&gt;

&lt;p&gt;We covered much ground, but I hope this helps you understand the random React component that Webpacker generated for you in your Ruby on Rails application.&lt;/p&gt;

&lt;p&gt;So, what did we learn today?&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ES6 imports&lt;/li&gt;
  &lt;li&gt;Constants&lt;/li&gt;
  &lt;li&gt;Arrow functions&lt;/li&gt;
  &lt;li&gt;Basic React components&lt;/li&gt;
  &lt;li&gt;Props&lt;/li&gt;
  &lt;li&gt;PropTypes&lt;/li&gt;
  &lt;li&gt;ReactDOM rendering&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope this piques your interest just enough to keep learning React. I think it makes a great addition to Ruby on Rails applications, and I’m excited to see what you build with it.&lt;/p&gt;</content><author><name>Jason Charnes</name></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jasoncharnes.com/images/sharing.png" /><media:content medium="image" url="https://jasoncharnes.com/images/sharing.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Run.rb</title><link href="https://jasoncharnes.com/run-rb/" rel="alternate" type="text/html" title="Run.rb" /><published>2019-01-21T00:00:00+00:00</published><updated>2019-01-21T00:00:00+00:00</updated><id>repo://posts.collection/_posts/2019-01-21-run-rb.md</id><content type="html" xml:base="https://jasoncharnes.com/run-rb/">&lt;p&gt;I’m proud to be involved in the Ruby community.&lt;/p&gt;

&lt;p&gt;I want to do what I can to help other developers discover Ruby. Whether that’s seasoned non-Ruby developers or people like me who &lt;a href=&quot;https://jasoncharnes.com/getting-your-first-programming-job/&quot;&gt;stumble into programming&lt;/a&gt;, I want to help.&lt;/p&gt;

&lt;p&gt;As part of that, I’ve recently started on a project to help people learn Ruby. The final form will be a &lt;strong&gt;&lt;em&gt;free&lt;/em&gt;&lt;/strong&gt; set of guides (and maybe videos) to help people get started with the Ruby language. &lt;em&gt;(More on that another time)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;While working on this project, I spent some time thinking about how I could help get people writing Ruby quickly.&lt;/p&gt;

&lt;p&gt;It’s not difficult to install Ruby on your computer. However, I remember as a beginner it was more involved than I anticipated, being a “non-programmer” at the time.&lt;/p&gt;

&lt;p&gt;One of my first experiences with Ruby was using Try Ruby. Try Ruby was a quick Ruby tutorial with the ability to run the Ruby code and get immediate feedback.&lt;/p&gt;

&lt;p&gt;Inspired by that project, I want to bring a way to write Ruby code in the browser, and get immediate output.&lt;/p&gt;

&lt;p&gt;I think this is especially valuable when teaching Ruby. The ability to hop in a browser, run some Ruby code and get immediate feedback is a win while learning Ruby.&lt;/p&gt;

&lt;p&gt;Heck, even as a more “seasoned” Ruby developer I see value in this.&lt;/p&gt;

&lt;h4 id=&quot;introducing-runrb&quot;&gt;Introducing run.rb&lt;/h4&gt;

&lt;p&gt;Wanting to bring this project to life lead me to collaborate with the most intelligent person I know, Will Glynn.&lt;/p&gt;

&lt;p&gt;Today, I want to share &lt;a href=&quot;https://runrb.io&quot;&gt;run.rb&lt;/a&gt; with you. &lt;em&gt;Naming is hard, so I pronounce this “runner bee.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When you visit &lt;a href=&quot;https://runrb.io&quot;&gt;run.rb&lt;/a&gt; and run Ruby code, &lt;strong&gt;your code never leaves the browser&lt;/strong&gt;. Will, once again- a freaking genius, helped me compile Ruby 2.6.0 into WebAssembly.&lt;/p&gt;

&lt;p&gt;Your Ruby code executes in the browser.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This project is still very much an early prototype.&lt;/strong&gt;But I wanted to get it into the hands of others.&lt;/p&gt;

&lt;p&gt;For example, our next step is to add Ruby’s Standard Library (which is currently not there) into run.rb. I’d also like to allow you to share your code snippets as a link back to run.rb.&lt;/p&gt;

&lt;p&gt;So, please give it a spin. Let us know what we can do to make this better.&lt;/p&gt;

&lt;p&gt;❤️&lt;/p&gt;</content><author><name>Jason Charnes</name></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jasoncharnes.com/images/sharing.png" /><media:content medium="image" url="https://jasoncharnes.com/images/sharing.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Using Ruby in 2019</title><link href="https://jasoncharnes.com/using-ruby-in-2019/" rel="alternate" type="text/html" title="Using Ruby in 2019" /><published>2019-01-02T00:00:00+00:00</published><updated>2019-01-02T00:00:00+00:00</updated><id>repo://posts.collection/_posts/2019-01-02-using-ruby-in-2019.md</id><content type="html" xml:base="https://jasoncharnes.com/using-ruby-in-2019/">&lt;p&gt;Stop me if you’ve heard this one…&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Ruby is dead!&lt;/p&gt;

  &lt;p&gt;&lt;cite&gt;Hacker News&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As someone actively writing (and heavily invested in) Ruby, it’s hard not to question if I’m “missing the boat” when I hear such things.&lt;/p&gt;

&lt;p&gt;In an attempt to “stay relevant,” if you will, I spent the better part of last year exploring other programming languages and paradigms. I built many, many Hello, World applications. Although I didn’t master anything, I learned a lot.&lt;/p&gt;

&lt;p&gt;I spent some time trying to wrap my head around Elixir and functional programming. Alongside Elixir, I began to embrace modern JavaScript using things like ES6, React, and Stimulus. I built a mobile application using React Native with a Firebase backend. I read a little bit about Rust, drooled over Crystal, and read (part of) a book on Scheme.&lt;/p&gt;

&lt;p&gt;There’s a lot to learn from other programming languages and approaches. As I learn about these different techniques, I feel that I’m becoming a more well-rounded developer.&lt;/p&gt;

&lt;p&gt;However, I ended 2018 with one overwhelming theme: &lt;strong&gt;Ruby still fits me&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Exploring a world outside Ruby reminded me that Ruby isn’t the ”one true way,” but &lt;em&gt;it’s still an excellent tool in my toolbelt&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;99.99% of the work I do is on the web. For me, Ruby is an excellent tool for that job. The language is flexible, &lt;strong&gt;stable&lt;/strong&gt;, and fun to use.&lt;/p&gt;

&lt;p&gt;Before I go any further, I want to point out that I understand that Ruby isn’t the right tool for all jobs. There is a reason new languages are evolving and seeing adoption.&lt;/p&gt;

&lt;p&gt;I’d also like to point out that this isn’t a definitive “you should use Ruby and here are the reasons why!” type of article. &lt;strong&gt;This article is a summary of why I’m confident using ruby in 2019.&lt;/strong&gt;&lt;/p&gt;

&lt;h4 id=&quot;the-road-to-ruby-3&quot;&gt;The Road to Ruby 3&lt;/h4&gt;

&lt;p&gt;I stood in the back of the room for Matz’s 2015 RubyConf keynote counting down the time until I had to catch my flight home. I’ll never forget when he laid out his idea for &lt;a href=&quot;https://engineering.appfolio.com/appfolio-engineering/2015/11/18/ruby-3x3&quot;&gt;Ruby 3x3&lt;/a&gt;. The premise is that Ruby 3 will be three times faster than Ruby 2.&lt;/p&gt;

&lt;p&gt;We’re fresh off the Christmas release of Ruby 2.6. I asked &lt;a href=&quot;https://twitter.com/codefolio&quot;&gt;Noah Gibbs&lt;/a&gt; about the progress made from Ruby 2.0 to Ruby 2.6.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;A lot of the early 2.0-series improvements (2.1, 2.2, 2.3) were in the garbage collector - the 2.3-and-later GC is much faster than 2.0.&lt;/p&gt;

  &lt;p&gt;For RRB, 2.4.1 runs at 150%-155% of the speed of 2.0, and 2.6 (no JIT) runs at about 10%-15% faster than that. So you can quote me at &lt;strong&gt;165%&lt;/strong&gt; the speed of 2.0. That’s 65% faster, or just north of time-and-a-half speed.&lt;/p&gt;

  &lt;p&gt;&lt;a href=&quot;http://engineering.appfolio.com/appfolio-engineering/2018/12/13/a-short-update-how-fast-is-ruby-260rc1&quot;&gt;2.6 has been a bit of a speed disappointment for RRB and large Rails apps&lt;/a&gt;, but overall the 2.0 series has been pretty good. I tend to say that, as a rule, each minor version of Ruby averages 10% faster for Rails apps. So while 2.6 gave us nothing over 2.5, some earlier 2-series Rubies had us a bit ahead of that schedule and it all works out.&lt;/p&gt;

  &lt;p&gt;With that said, we are &lt;em&gt;not&lt;/em&gt; on schedule to get a 3x speedup just out of these small speedups - that would be a &lt;em&gt;lot&lt;/em&gt; of 10% speedups from minor versions. Instead, the big hope there is &lt;strong&gt;JIT&lt;/strong&gt; and possibly concurrency (&lt;strong&gt;Guilds&lt;/strong&gt;.) But we’ll probably count 3x as achieved even if a big Rails app doesn’t get it, because so much of what Rails Ruby Bench does &lt;em&gt;isnt&lt;/em&gt; Ruby – database calls, I/O, Redis, HTTP server, etc. I’m working on a smaller benchmark to show more of that now, and more Ruby-heavy benchmarks like OptCarrot already do, in various ways.&lt;/p&gt;

  &lt;p&gt;Measuring speed is a genuinely interesting problem, and there’s almost never just one answer. There’s &lt;a href=&quot;http://rubykaigi.org/2016/presentations/MattStudies.html&quot;&gt;a great talk by Matt Gaudet&lt;/a&gt; from just before I started on this problem, if you want the deep dive version.&lt;a href=&quot;http://rubykaigi.org/2016/presentations/MattStudies.html&quot;&gt;&lt;/a&gt;&lt;/p&gt;

  &lt;p&gt;&lt;cite&gt;Noah Gibbs | Appfolio&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4 id=&quot;rails-6&quot;&gt;Rails 6+&lt;/h4&gt;

&lt;p&gt;We’re on the cusp of a new major Ruby on Rails version. DHH recently released a &lt;a href=&quot;https://weblog.rubyonrails.org/2018/12/20/timeline-for-the-release-of-Rails-6-0/&quot;&gt;blog post&lt;/a&gt; highlighting the tentative timeline of Rails 6.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;April 30: Final release&lt;/strong&gt;. Ship and celebrate the release of Rails 6.0 at RailsConf 2019!&lt;/p&gt;

  &lt;p&gt;&lt;cite&gt;DHH | Timeline for the release of Rails 6.0&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Three things to highlight in Ruby on Rails 6:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://weblog.rubyonrails.org/2018/12/13/introducing-action-mailbox-for-rails-6/&quot;&gt;Action Mailbox&lt;/a&gt; &lt;/strong&gt;- Handle incoming emails to your Rails application&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://weblog.rubyonrails.org/2018/10/3/introducing-action-text-for-rails-6/&quot;&gt;Action Text&lt;/a&gt;&lt;/strong&gt; - Built-in rich text capability using Trix and Active Storage&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://rdeck.com/eileencodes/railsconf-2018-the-future-of-rails-6-scalable-by-default?slide=14&quot;&gt;Parallel Testing&lt;/a&gt;&lt;/strong&gt; - The ability to split/divide your tests to run in parallel&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m most excited about parallel testing, as I currently use a gem to do that for me.&lt;/p&gt;

&lt;p&gt;It’s nice to see DHH, Basecamp, and the countless contributors ❤️ still committed to Ruby and Ruby on Rails. I’m under the impression that for the foreseeable future David will continue to stay involved in Ruby and Ruby on Rails. (Guessing, here, but he loves Ruby.)&lt;/p&gt;

&lt;p&gt;Generating a fully-fledged Rails application has never been easier. One thing I’ve grown to appreciate about Ruby on Rails is “&lt;a href=&quot;https://rubyonrails.org/doctrine/#no-one-paradigm&quot;&gt;no one paradigm&lt;/a&gt;.”&lt;/p&gt;

&lt;p&gt;For example, there are times when I feel that I’m butting heads with the “Rails way.” When I find myself here, Ruby on Rails doesn’t prevent me from implementing new patterns or even doing wild things like replacing ActiveRecord.&lt;/p&gt;

&lt;p&gt;One thing I often envy is the &lt;a href=&quot;https://www.laravel.com&quot;&gt;Laravel&lt;/a&gt; framework in PHP. Chris and I have talked about this on our &lt;a href=&quot;https://remoteruby.transistor.fm&quot;&gt;Ruby podcast&lt;/a&gt;. Laravel has many tools &lt;em&gt;most&lt;/em&gt; web apps need baked into the framework. Things such as authentication, authorization, events, queues, etc. Outside of that, Laravel offers official packages that handle things such as recurring payments with Stripe/Braintree, a GUI for debugging your application in development, an OAuth server, OAuth providers, and more.&lt;/p&gt;

&lt;p&gt;I think adding these things into Rails might violate “no one paradigm.” Maybe it’s possible it’s as simple as Rails core believing Rails shouldn’t take those defaults.&lt;/p&gt;

&lt;p&gt;I still enjoy Rails without having those libraries baked in. However, I’d be remiss if I didn’t mention I wish we had more first-party functionality like that.&lt;/p&gt;

&lt;p&gt;I’m excited for &lt;a href=&quot;https://railsconf.com&quot;&gt;RailsConf 2019&lt;/a&gt;. I hope to see you there!&lt;/p&gt;

&lt;h4 id=&quot;outside-of-rails&quot;&gt;Outside of Rails&lt;/h4&gt;

&lt;p&gt;Though the majority of my work is in Ruby on Rails, I’m very excited about the work outside of Rails.&lt;/p&gt;

&lt;p&gt;For instance, the &lt;a href=&quot;https://dry-rb.org&quot;&gt;dry-rb&lt;/a&gt; project profoundly resonates with me after spending time exploring the functional programming world.&lt;/p&gt;

&lt;p&gt;I have the utmost respect for &lt;a href=&quot;https://twitter.com/_solnic_&quot;&gt;Piotr&lt;/a&gt; and &lt;a href=&quot;https://twitter.com/timriley&quot;&gt;Tim.&lt;/a&gt; (and the other people on the dry-rb team I’ve yet to meet!) Their approach to writing Ruby code is unique, and I have a lot to learn from them.&lt;/p&gt;

&lt;p&gt;Alongside dry-rb, Piotr has a database toolkit named &lt;a href=&quot;https://rom-rb.org&quot;&gt;ROM&lt;/a&gt;. Once again, this is an approach that is different to what I usually use, ActiveRecord. However, the approach resonates with me. I’m excited to explore this more in 2019.&lt;/p&gt;

&lt;p&gt;The other project I keep my eye on is &lt;a href=&quot;http://hanamirb.org&quot;&gt;Hanami&lt;/a&gt;. The core team is currently working on version 2.0, which embraces more of the dry-rb and ROM libraries. I’m excited to see the result. I hope to build a project using Hanami 2.0 in 2019.&lt;/p&gt;

&lt;p&gt;These are just a few of the exciting things happening in Ruby outside of Rails. I’m sure there are more I don’t even know. &lt;strong&gt;What are some of your favorite things?&lt;/strong&gt;&lt;/p&gt;

&lt;h4 id=&quot;gems&quot;&gt;Gems&lt;/h4&gt;

&lt;p&gt;The Ruby language has a plethora of gems. It’s one of the things I loved about Ruby when I came into the language in 2012.&lt;/p&gt;

&lt;p&gt;However, some gems are starting to get a little stale. While it’s a bummer to see abandoned gems, it’s also an opportunity for Ruby developers to get involved in the community.&lt;/p&gt;

&lt;p&gt;If a gem you like using is abandoned, you can fork it or build a new gem and share it with the community. I’d certainly love to see some fresh gem ideas in 2019.&lt;/p&gt;

&lt;p&gt;An aside, I would love to see more open source models like Mike Perham’s Sidekiq. Mike gives you a fantastic open source project, with the ability to pay for more “pro” features. I imagine this helps Mike stay interested in the project.&lt;/p&gt;

&lt;h4 id=&quot;flexibility&quot;&gt;Flexibility&lt;/h4&gt;

&lt;p&gt;One of the things I most love about Ruby (and at times have been frustrated with) is its flexibility.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Ruby includes a lot of sharp knives in its drawer of features.&lt;/p&gt;

  &lt;p&gt;&lt;cite&gt;DHH | &lt;a href=&quot;https://m.signalvnoise.com/provide-sharp-knives-cc0a22bf7934&quot;&gt;Provide Sharp Knives&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I’ve made many messes with Ruby code. You could argue this is the language’s fault, but I would disagree. I think in my cases, it was a lack of discipline and knowledge.&lt;/p&gt;

&lt;p&gt;At times I’ve wanted to move to a statically typed language. I dream of the things the computer can do for me. However, in my experience so far it comes at the expense of the flexibility of using Ruby.&lt;/p&gt;

&lt;p&gt;Several projects come to mind when I think of Ruby’s flexibility:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;RSpec - A DSL for writing tests&lt;/li&gt;
  &lt;li&gt;Ruby on Rails - That magical feeling when you first learn how to use Rails (AKA “Look at all the things I’m not doing”)&lt;/li&gt;
  &lt;li&gt;dry-rb - The ability to express functional concepts and blend FP with OOP &lt;em&gt;in&lt;/em&gt; Ruby&lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;stability&quot;&gt;Stability&lt;/h4&gt;

&lt;p&gt;I can count on one hand the number of times my Ruby projects broke due to a Ruby version upgrade. Matz has often talked about how stability is an important part of the Ruby language. In his keynotes, he’s looked at other languages with not so great upgrade stories.&lt;/p&gt;

&lt;p&gt;Granted, I wasn’t around for the Ruby 1.8 =&amp;gt; 1.9 transition. I heard it was a little bumpy. However, in my experience, it’s been solid. I very much appreciate writing Ruby code with confidence.&lt;/p&gt;

&lt;h4 id=&quot;ruby-conferences-in-2019&quot;&gt;Ruby Conferences in 2019&lt;/h4&gt;

&lt;p&gt;At the time of this writing, there are &lt;strong&gt;16&lt;/strong&gt; scheduled Ruby-related conferences in 2019. This count is according to the &lt;a href=&quot;https://rubyconferences.org&quot;&gt;Ruby Conferences website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cough cough, special shoutout &lt;a href=&quot;https://southeastruby.com&quot;&gt;Southeast Ruby&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h4 id=&quot;ruby-jobs-in-2019&quot;&gt;Ruby Jobs in 2019&lt;/h4&gt;

&lt;p&gt;One of metrics, if you will, I use to keep an eye on Ruby’s “demise” is the number of available Ruby jobs.&lt;/p&gt;

&lt;p&gt;One website I like to use is &lt;a href=&quot;https://stackoverflow.com/jobs&quot;&gt;Stack Overflow Jobs&lt;/a&gt;. A quick search for Ruby returns &lt;strong&gt;499 jobs&lt;/strong&gt; in Ruby out of ~6000 total job postings.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2019/01/Screen-Shot-2019-01-02-at-10.01.17-AM.png?fit=640%2C386&amp;amp;ssl=1&quot; alt=&quot;Stack Overflow Ruby Jobs&quot; /&gt;&lt;/p&gt;

&lt;p&gt;A search for PHP on the same website returns &lt;strong&gt;404&lt;/strong&gt; (job not found lolz) jobs. I consider PHP to be one of the more widely used (and not dead) langauges on the internet.&lt;/p&gt;

&lt;p&gt;Searching for Java returns 2,500 jobs. JavaScript returns 1,950 jobs. However, I expect that. Those languages (as far as I know) have always seen wider adoption.&lt;/p&gt;

&lt;p&gt;Stack Overflow Jobs isn’t a full representation of the job market. But, the jobs listed on Stack Overflow are legitimate companies hiring developers.&lt;/p&gt;

&lt;p&gt;If I were to look for a new job, this would be one of the websites I checked first. I might also check We Work Remotely and the physical job boards at RubyConf and RailsConf, which have no more room by the time we leave.&lt;/p&gt;

&lt;p&gt;All to say, I would feel comfortable finding a Ruby job in 2019.&lt;/p&gt;

&lt;h4 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h4&gt;

&lt;p&gt;I’m happy with my decision to &lt;a href=&quot;https://jasoncharnes.com/2018/&quot;&gt;dig even deeper into Ruby&lt;/a&gt; in 2019. Ruby isn’t perfect, but it still fits the way I view the world quite well.&lt;/p&gt;

&lt;p&gt;I’d be lying if I said I wasn’t envious for features from other languages. But, at the end of the day, I’m solving problems for people. Currently, I’m best equipped to do that using Ruby. The cool part? &lt;strong&gt;I’m happy while I do it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Is Ruby the right tool for every job? &lt;strong&gt;No.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Are there valid reasons to look at other languages? &lt;strong&gt;Yes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Are things still happening in Ruby? &lt;strong&gt;Hell yes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Jason, you didn’t reference &lt;a href=&quot;https://www.tiobe.com/tiobe-index/&quot;&gt;The TIOBE Index&lt;/a&gt;! &lt;strong&gt;Whoops.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Can Ruby and (Insert Language Here) coexist? &lt;strong&gt;Absolutely. I think too often we approach programming language wars as you have to choose one or the other. I don’t think that is the case.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Jason, are you going to keep using Ruby in 2019? &lt;strong&gt;Yes. But, that doesn’t mean I won’t try and learn from other languages and ecosystems.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Is Ruby dead? &lt;strong&gt;Nah.&lt;/strong&gt; (&lt;a href=&quot;https://isrubydead.com&quot;&gt;isrubydead&lt;/a&gt;&lt;a href=&quot;https://isrubydead.com&quot;&gt;.com&lt;/a&gt;)&lt;/p&gt;</content><author><name>Jason Charnes</name></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jasoncharnes.com/images/sharing.png" /><media:content medium="image" url="https://jasoncharnes.com/images/sharing.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Goodbye, 2018</title><link href="https://jasoncharnes.com/2018/" rel="alternate" type="text/html" title="Goodbye, 2018" /><published>2018-12-31T00:00:00+00:00</published><updated>2018-12-31T00:00:00+00:00</updated><id>repo://posts.collection/_posts/2018-12-31-2018.md</id><content type="html" xml:base="https://jasoncharnes.com/2018/">&lt;p&gt;It’s the last day of 2018. Like most things in 2018, I waited until the last possible minute to write this.&lt;/p&gt;

&lt;p&gt;Some great things happened, which I’m excited to share. Some less stellar things happened and some things didn’t happen. Either way, I want to take time to put my thoughts on paper this site. I have several ideas of what went wrong in 2018 and what can be different in 2019.&lt;/p&gt;

&lt;h3 id=&quot;the-good&quot;&gt;The Good&lt;/h3&gt;

&lt;h4 id=&quot;hello-baby-jaden-&quot;&gt;Hello, Baby Jaden! 🎉👶&lt;/h4&gt;

&lt;p&gt;Shannon (my partner) and I welcomed another baby boy into the world on October 10. Jaden Isaac Charnes is our second-born child.&lt;/p&gt;

&lt;p&gt;Shannon and I spent the majority of our year together preparing for his birth while keeping our first born (turned 2 December, 29) entertained. 😅&lt;/p&gt;

&lt;p&gt;It’s fantastic to have two healthy children. I hope I never take that for granted.&lt;/p&gt;

&lt;h4 id=&quot;remote-ruby-️&quot;&gt;Remote Ruby 🎙️&lt;/h4&gt;

&lt;p&gt;I had an idea in January to start an online meetup for Ruby developers. Like any new idea, it was exciting.&lt;/p&gt;

&lt;p&gt;I purchased a domain, threw together a website, and set a date for the first meetup.&lt;/p&gt;

&lt;p&gt;My buddy &lt;a href=&quot;https://twitter.com/excid3&quot;&gt;Chris&lt;/a&gt; agreed to be the first guest. As it would turn out, Chris would be the only guest. I ended up presenting at one or two more meetups. That wasn’t the original goal. The idea was for &lt;em&gt;others&lt;/em&gt; to give presentations.&lt;/p&gt;

&lt;p&gt;Around June, I asked Chris if he wanted to do a podcast. He suggested we do it under the Remote Ruby brand, which was kind of him.&lt;/p&gt;

&lt;p&gt;The podcast has done very well, by my standards. I was expecting to record an episode every week for 10-20 people. We’ve seen consistent growth in downloads. We recorded 21 times in 2018 for a total of 7,162 downloads.&lt;/p&gt;

&lt;p&gt;I owe part of that to Chris having a substantial following with his GoRails community. &lt;em&gt;Thanks, friend&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Earlier this week, I shut down the Remote Ruby Slack (used for meetups) and set up the email list to send new episodes out by email.&lt;/p&gt;

&lt;p&gt;In hindsight, I should have been more diligent to find meetup speakers. However, it was also hard asking Shannon to let me have 1-2 hours at night on top of everything she allows me to do.&lt;/p&gt;

&lt;p&gt;In the end, it all worked out. I love doing the podcast.&lt;/p&gt;

&lt;h4 id=&quot;southeast-ruby-️&quot;&gt;Southeast Ruby 🏙️&lt;/h4&gt;

&lt;p&gt;I once again put on Southeast Ruby. If you’re unfamiliar with Southeast Ruby, it’s a Ruby conference that Shannon and I started last year.&lt;/p&gt;

&lt;p&gt;Instead of being an idiot and his smart wife putting on a conference alone, I somehow fooled &lt;a href=&quot;https://twitter.com/erniemiller&quot;&gt;Ernie Miller&lt;/a&gt; into helping co-organize the conference. Including Ernie was of the best decisions we made in 2018. Ernie is one of the most empathic, caring human beings I’ve ever met. I’m beyond thrilled he’s helping us again in 2019.&lt;/p&gt;

&lt;p&gt;Somehow, once again, we had a fantastic speaker lineup.&lt;/p&gt;

&lt;p&gt;Avdi Grimm, once again, agreed to be a keynote speaker. Alongside Avdi my friend Nickolas Means and Nashville native Erin Page keynoted. Those three fantastic keynotes, alongside many amazing session speakers, helped this year’s conference continue to be an incredible experience for everyone involved.&lt;/p&gt;

&lt;p&gt;We had roughly 20% more attendees this year and several more sponsors, including Ramsey Solutions who provided a delightful venue.&lt;/p&gt;

&lt;p&gt;Last year Shannon and I lost a tremendous amount of money putting on the conference. 😭💸&lt;/p&gt;

&lt;p&gt;This year, we finished the conference with about $1,000 in the bank. This surplus helps give us a running start for 2019’s conference. I hope to one day make enough to reimburse ourselves for 2017, but if not it’s okay.&lt;/p&gt;

&lt;p&gt;Add all this together, and I would consider 2018’s Southeast Ruby to be a success.&lt;/p&gt;

&lt;p&gt;We’ve already announced next year’s dates! I’m excited to see how the &lt;a href=&quot;https://southeastruby.com&quot;&gt;conference unfolds in 2019&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;good--bad&quot;&gt;Good + Bad&lt;/h3&gt;

&lt;h4 id=&quot;changing-jobs-&quot;&gt;Changing Jobs 💼&lt;/h4&gt;

&lt;p&gt;I changed jobs this year. I’d been with Lensrentals.com for almost four years. It was my first full-time Ruby job.&lt;/p&gt;

&lt;p&gt;I owe several people there for the knowledge they shared with me and how great they treated me. I made some genuine friendships there.&lt;/p&gt;

&lt;p&gt;I got to learn a lot about not only Ruby, but deeper understood testing, OOP, and even got to do some React in my last few months. I have the utmost respect for the developers at Lensrentals, as well as the senior management.&lt;/p&gt;

&lt;p&gt;Leaving Lensrentals was a difficult decision for me.&lt;/p&gt;

&lt;p&gt;The company I joined is &lt;a href=&quot;https://podia.com&quot;&gt;Podia&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Joining Podia has been a spectacular experience, so far. I was employee number eight, and we ended the year with eleven employees. I’ve been able to witness (what I consider to be) great growth at the company.&lt;/p&gt;

&lt;p&gt;Since May I’ve been a part of some great feature launches. I very much like working on a product for creators, because I one day aspire to be a creator.&lt;/p&gt;

&lt;p&gt;The “boss” is great, and my co-workers accepted me (and my stupidity) from day one. ❤️&lt;/p&gt;

&lt;p&gt;So, leaving Lensrentals was (b|s)ad, but Podia has been great.&lt;/p&gt;

&lt;h4 id=&quot;less-public-speaking-&quot;&gt;Less Public Speaking 📢&lt;/h4&gt;

&lt;p&gt;I didn’t make a significant effort to speak at conferences in 2018. I’m not sure why, to be honest. I spoke at two conferences, one of which I was asked to speak out.&lt;/p&gt;

&lt;p&gt;I didn’t even submit to any other 2018 conferences.&lt;/p&gt;

&lt;p&gt;It takes a lot of work to speak, as many of you know. You have to have some ideas on talks, work up a solid abstract, 🤞 hope it gets accepted, and if it does: create an excellent presentation.&lt;/p&gt;

&lt;p&gt;It’s possible subconciously I didn’t want to go through that in 2018, but honestly, I don’t know why I held back this year.&lt;/p&gt;

&lt;h4 id=&quot;built-an-app-&quot;&gt;Built an App 📱&lt;/h4&gt;

&lt;p&gt;I finished building this app that I’ve been working on (and rewritten what feels like hundreds of times) for the last few years. The app is React Native with a Rails API. I polished it up and submitted it to the app stores.&lt;/p&gt;

&lt;p&gt;Google accepted the app within 30 minutes, and I was in the Play Store. Apple, however, after several days rejected the app because “it promoted self-harm.”&lt;/p&gt;

&lt;p&gt;I understand Apple’s position; the app was like Untappd for cigar smokers. It “promoted” the use of cigars. Nonetheless, it was a frustrating experience because of all the time I wasted.&lt;/p&gt;

&lt;p&gt;I decided to build a Progressive Web App (PWA) using React and Firebase. By the time I finished it, I’d lost any interest in it. I was especially concerned about the adoption of the app considering you had to visit a website and then bookmark the app to your home screen. 🤷‍♂️&lt;/p&gt;

&lt;p&gt;I’m glad I finished it because I learned some things along the way. But yeah, not a happy ending.&lt;/p&gt;

&lt;h3 id=&quot;not-so-good&quot;&gt;Not So Good&lt;/h3&gt;

&lt;p&gt;It was important to me to start with the good. I have Obsessive Compulsive Disorder and tend to obsess on the “bad.”&lt;/p&gt;

&lt;p&gt;I talk with Chris Oliver regularly about what’s going on in my life. One of the first things he brought up when I was recently explaining how down I am, was all the positive things that happened in 2019. &lt;em&gt;A second thank you in this post, Chris.&lt;/em&gt;&lt;/p&gt;

&lt;h4 id=&quot;building-a-product-audience-etc-️&quot;&gt;Building a Product, Audience, Etc 🛠️&lt;/h4&gt;

&lt;p&gt;One of the most disheartening things to look back on is how much I squandered opportunity in 2018 (and 2017).&lt;/p&gt;

&lt;p&gt;My oldest son was born two years ago on December 29, 2016. I spent the time I was on paternity leave (that wasn’t changing diapers, catching up on sleep or weeping in the fetal position) thinking about my future.&lt;/p&gt;

&lt;p&gt;It became clear to me that I wanted to one day “work for myself.”&lt;/p&gt;

&lt;p&gt;It wasn’t a new revelation, I’ve wanted to do so since before I became a programmer. I dreamed in high school of owning a music retail store one day. There’s something about owning my own business that has always appealed to me.&lt;/p&gt;

&lt;p&gt;It wasn’t until my son was born I &lt;em&gt;somehow&lt;/em&gt; finally pieced together that I can combine the desire to start a business with my passion (and career) of coding.&lt;/p&gt;

&lt;p&gt;Little did I know the rabbit hole I would go down.&lt;/p&gt;

&lt;p&gt;During that time I purchased &lt;a href=&quot;https://join.megamaker.co/a/r40y9&quot;&gt;Marketing for Developers&lt;/a&gt; by &lt;a href=&quot;https://justinjackson.ca&quot;&gt;Justin Jackson&lt;/a&gt;. That course opened my eyes to the world of building products in the digital age. Justin is a gold mine. Everytime he says something I want to listen.&lt;/p&gt;

&lt;p&gt;That’s also when I began spinning my wheels, though.&lt;/p&gt;

&lt;p&gt;I wanted to build a SaaS (Software as a Service) app. After all, a lot of my heroes have done that. Hell, the web framework I use the most came as an abstraction from a SaaS application.&lt;/p&gt;

&lt;p&gt;Quickly I learned there is quite a bit of (good) advice in the product community to not start with a SaaS app, but rather by doing two things: building an audience (by helping people solve problems) and creating a product that helps people learn something (think eBook or a Online Course).&lt;/p&gt;

&lt;p&gt;Both of these things sound good to me!&lt;/p&gt;

&lt;p&gt;I was laser focused. I put my head down and got to work.&lt;/p&gt;

&lt;p&gt;I bought a ticket and flew out to Las Vegas for MicroConf where I got to meet some of my heroes in the product &lt;em&gt;and&lt;/em&gt; programming community.&lt;/p&gt;

&lt;p&gt;I bought consulting time with Justin to learn how to find and validate ideas.&lt;/p&gt;

&lt;p&gt;I spent ~$2000 and started on &lt;a href=&quot;https://30x500.com/academy/&quot;&gt;30x500&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I made sure people could join my email list and finally, I was ready to go.&lt;/p&gt;

&lt;p&gt;And then I did &lt;strong&gt;nothing&lt;/strong&gt;. I psyched myself out. I’ve continued to do that for the last two years.&lt;/p&gt;

&lt;p&gt;It’s not that I don’t want to build a product. No, I obsess about that and beat myself up for having nothing to show.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Decision Paralysis and Self Doubt&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I mentioned earlier that I have OCD. Not like, “haha I’m OCD about this thing,” but rather “oh shit &lt;a href=&quot;https://www.youtube.com/watch?v=jrh78wn5aQA&amp;amp;t=617s&quot;&gt;my doctor has diagnosed me with OCD&lt;/a&gt;.”&lt;/p&gt;

&lt;p&gt;There are several things I could teach. My dream is to help people with Ruby. (If you don’t know, I &lt;strong&gt;love&lt;/strong&gt; Ruby)&lt;/p&gt;

&lt;p&gt;This is where decision paralysis creeps in.&lt;/p&gt;

&lt;p&gt;“I could teach beginners Ruby!… Well, there’s already good content out there, how would I make any difference?” &lt;strong&gt;Boom: Self Doubt&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;“I could teach Ruby developers React!… Well, I’m not an expert in React, people will think I’m stupid… I shouldn’t try to teach that.” &lt;strong&gt;Boom: Self Doubt﻿&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The process continues and eventually, I don’t do anything, because I’ve become unable to decide on what to write about.&lt;/p&gt;

&lt;p&gt;One of the big reasons I’m unable to make a decision is because I’m too scared to put myself out there. I not only struggle with OCD but also Generalized Anxiety Disorder (GAD).&lt;/p&gt;

&lt;p&gt;I’m afraid (absolutely terrified) that people will think I’m a fraud, or that I won’t add any value to anyone. I’m so scared that I eventually retreat and do nothing.&lt;/p&gt;

&lt;p&gt;When I get to this point, I don’t want to write blog posts because I’m afraid. I don’t build an audience or help anyone, because I’m scared.&lt;/p&gt;

&lt;p&gt;In 2019 I only wrote three blog posts. 😢&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Riding the High&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Aside from being scared to make an effort, I’m also bad about getting excited about new things and then backing away as the excitement fades.&lt;/p&gt;

&lt;p&gt;When I get time to sit down and work, I’m exhausted from overthinking, or I get distracted by some other shiny thing.&lt;/p&gt;

&lt;p&gt;Sometimes, I just don’t want to do the work, because I’m lazy. 😞&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Unfocused&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I’ve become so entranced with the idea of building a product, at times I’ve forgotten the reason you make products: &lt;strong&gt;to help people&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you can earn income from that, that’s awesome! I don’t think there is anything wrong with that. However, when the focus becomes “success,” it gets muddy.&lt;/p&gt;

&lt;p&gt;No one has advised me to focus on the end result, in fact, the opposite. That doesn’t stop me from day-dreaming about the end result. That’s when I start to lose sight of what I’m doing.&lt;/p&gt;

&lt;p&gt;When I’m obsessed with making a living from products, I’m so scared to fail. If I don’t think something is going to be a huge success, I start to doubt and then eventually abandon. AKA, I get nowhere.&lt;/p&gt;

&lt;p&gt;This leaves me with a twisted vision that I can’t fail. Whatever I do has to be a success. 🤮 Saying this out loud is embarrassing because it’s not true.&lt;/p&gt;

&lt;p&gt;The most successful people I know (thinking about Justin Jackson, Adam Wathan, and Mike Perham, to name a few) spent time helping people. Their paid products are an extension of their time writing or building things to help others.&lt;/p&gt;

&lt;p&gt;I asked Adam at MicroConf 2017 about how he built his audience. He told me (something along the lines of):&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“Most people want to take a shortcut. They don’t want to put in the work to help people.”&lt;/p&gt;

  &lt;p&gt;&lt;cite&gt;Adam Wathan&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I’ve lost focus. What good is an audience or a product if I’m throwing shit at the wall hoping it makes money. 🤢&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I want to refocus and help people grow as developers by sharing quality information.&lt;/strong&gt; The opposite leaves me in a never-ending loop of frustration with nothing to show.&lt;/p&gt;

&lt;h4 id=&quot;products-with-co-founders&quot;&gt;Products with Co-founders&lt;/h4&gt;

&lt;p&gt;I also have three open projects I didn’t complete in 2018. For these, I’m not alone- I have a “co-founder” for each product. Also, these products we’re making have potential, but I back myself into a corner of self-doubt and laziness.&lt;/p&gt;

&lt;p&gt;My goal is to launch two of them in January and get head down working on the third in February.&lt;/p&gt;

&lt;h4 id=&quot;excuses&quot;&gt;Excuses&lt;/h4&gt;

&lt;p&gt;I’m getting ahead of myself, here, but if you’ve read this far, I want you to know: these are not excuses. Though I’ve let myself fall into bad habits and listen to my negative thoughts, I can do this. I’m making an effort to identify my weaknesses to do better.&lt;/p&gt;

&lt;p&gt;My plan for 2019 is to go deeper, not wider- an idea from David Cain. I have more to say on this at the end.&lt;/p&gt;

&lt;h4 id=&quot;finances-&quot;&gt;Finances 💰&lt;/h4&gt;

&lt;p&gt;As a software developer, I’m lucky to earn an excellent salary. It’s enough for Shannon to stay home and raise our children full-time, which is something she &lt;em&gt;wants&lt;/em&gt; to do.&lt;/p&gt;

&lt;p&gt;The problem is, I’m horrible with money. I’ve been known to make impulsive decisions financially with money we didn’t have. AKA, we did things with credit cards we shouldn’t have.&lt;/p&gt;

&lt;p&gt;We have a decent amount of debt. It’s one of the most significant stressors in my life. It’s no one’s fault but my own, but it’s still something that eats at me.&lt;/p&gt;

&lt;p&gt;Two thousand eighteen was a better year. We budgeted each month and made strides to get our money on track. We, at times, still overspent, but as the year comes to a close, I’m happy with how Shannon and I are approaching money.&lt;/p&gt;

&lt;p&gt;An example of a better step in the right direction: Shannon and I are taking a trip. This time, we’ve paid for the trip with money we’ve saved up. 🙌 Before, I would have thrown the trip on plastic and “worried about it later.” Except, later accumulates to where we are now.&lt;/p&gt;

&lt;p&gt;My goal for 2019 is to pay only with money we have and to have one of the best years for paying off the debt we’ve seen as a family.&lt;/p&gt;

&lt;h4 id=&quot;health-️&quot;&gt;Health 🍴🏃‍♂️😭&lt;/h4&gt;

&lt;p&gt;I’m the largest I’ve been to date. In 2011, I was at my (then) heaviest of 280lbs. I decided I was tired of it and lost ~65lbs. I felt the best I’d ever felt, was more active, impressed Shannon with my smoking bod 😉, and I was overall happier.&lt;/p&gt;

&lt;p&gt;Around the time I got married, I started to deal with my anxiety and depression issues. I didn’t want to bring that added stress into a new marriage.&lt;/p&gt;

&lt;p&gt;I started a new anxiety medicine with a side-effect of weight gain. “Meh,” I thought. I’ll be okay.&lt;/p&gt;

&lt;p&gt;That, alongside “eating my emotions,” has led me to today. I weight 350lbs. 😳&lt;/p&gt;

&lt;p&gt;I’m unhealthy, feel terrible, and worst of all: sometimes struggle to play with my kids. 😭&lt;/p&gt;

&lt;p&gt;I spent a lot 0f 2018 thinking about how I want to be around for my children. It’s one thing if something happens to me that I can’t control. My health, though? I own the responsibility. I want my children to know their dad fought for his health because he loves his family.&lt;/p&gt;

&lt;p&gt;The end of 2018 I’ve started taking baby steps. I’m more mindful of what I eat and how much of it I eat. I also started the process of changing medications to see if that helps me regain control of my eating habits. So far, I’m eating less and optimistic for the future.&lt;/p&gt;

&lt;h4 id=&quot;2019&quot;&gt;&lt;strong&gt;2019&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;I highly debated writing a “year in review,” because I a) don’t think people care about what I did and b) didn’t know how to think about the future.&lt;/p&gt;

&lt;p&gt;I’ve never kept a New Years Resolution. Why keep coming up with them?&lt;/p&gt;

&lt;p&gt;Today, I was reminded of a post I read by David Cain entitled “&lt;a href=&quot;https://www.raptitude.com/2017/12/go-deeper-not-wider/&quot;&gt;Go Deeper, Not Wider&lt;/a&gt;.” (aside: David is amazing and you should read whatever he writes)&lt;/p&gt;

&lt;p&gt;I realized that in 2019, I don’t want to add to my to-do list or try to “widen” an already uncompleted list. I want to deal with, and actually, make progress on (deepen) what I felt was lacking this year.&lt;/p&gt;

&lt;p&gt;So, with that said, here is my list of things I would like to accomplish in 2019.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Gain control of my health.&lt;/strong&gt; I want to lose weight, be more active, and find contentment with my appearance.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Pay down debt.&lt;/strong&gt; It’s not feasible to pay off &lt;em&gt;all&lt;/em&gt; our debt in 2019. However, it is possible to make great strides and sacrifices to pay down our debt and continue to work towards financial freedom.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Grow technically.&lt;/strong&gt; I’d like to invest more in technology. I’d like to grow deeper in what I currently know about Ruby and JavaScript, the two languages I use the most.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Help people.&lt;/strong&gt; I want to focus on writing blog posts, making videos, and helping developers. Instead of paralyzing my brain worried about what to write about, I want to share more of what I’ve learned since I became a programmer. I want to worry less about “building a product.” If a product comes out of helping people, that’s amazing. In 2019, though, I want to reset my focus on others more than myself.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Finish things.&lt;/strong&gt; Finally, I want to finish what I’ve started. The more I continue not to finish things and start something new, the more stress I add to my life and subsequently my family’s life.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Join a new church community.&lt;/strong&gt; The end of 2018 was also the end of seven years of membership at our church. There’s no big drama here, we just felt it was time to move on. Shannon and I are focused on finding a new church for our family, which isn’t an easy task.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you’re interested in growing as a developer, or getting started in web development: please reach out and let me know things you’re interested in learning. I want to know how to help.&lt;/p&gt;

&lt;p&gt;I wish you the best in 2019. Thank you for reading.&lt;/p&gt;</content><author><name>Jason Charnes</name></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jasoncharnes.com/images/sharing.png" /><media:content medium="image" url="https://jasoncharnes.com/images/sharing.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Remote Ruby #20: Trivia Questions and Answers</title><link href="https://jasoncharnes.com/remote-ruby-20-trivia-questions-and-answers/" rel="alternate" type="text/html" title="Remote Ruby #20: Trivia Questions and Answers" /><published>2018-12-20T00:00:00+00:00</published><updated>2018-12-20T00:00:00+00:00</updated><id>repo://posts.collection/_posts/2018-12-20-remote-ruby-20-trivia-questions-and-answers.md</id><content type="html" xml:base="https://jasoncharnes.com/remote-ruby-20-trivia-questions-and-answers/">&lt;p&gt;On episode 20 of the Remote Ruby podcast, Chris and I play a game of trivia. These questions are composed of information from &lt;a href=&quot;https://en.wikipedia.org/wiki/Ruby_(programming_language)&quot;&gt;Wikipedia&lt;/a&gt; and &lt;a href=&quot;https://github.com/beneggett/ruby-trivia&quot;&gt;beneggett/ruby-trivia&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I have no doubts that some of this information &lt;em&gt;could&lt;/em&gt; be wrong. I was a late bloomer to Ruby. 😎&lt;/p&gt;

&lt;p&gt;I hope you enjoy(ed) the episode.&lt;/p&gt;

&lt;iframe loading=&quot;lazy&quot; src=&quot;https://share.transistor.fm/e/0f50d36b&quot; width=&quot;100%&quot; height=&quot;180&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot; seamless=&quot;true&quot; style=&quot;width:100%; height:180px;&quot;&gt;&lt;/iframe&gt;

&lt;ol&gt;
  &lt;li&gt;According to Matz, what year was Ruby conceived? &lt;strong&gt;1993&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;What year did Ruby first appear? &lt;strong&gt;1995&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;There were two potential names for the language. In the end, Ruby was the name chosen. What was the other proposed name? &lt;strong&gt;Coral&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;What was the first book written in English about Ruby? &lt;strong&gt;Programming Ruby&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;What year did the popular Ruby web framework Ruby on Rails first appear? &lt;strong&gt;2005&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;On what day is a new version of Ruby typically released each year? &lt;strong&gt;December 25&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;What version of Ruby unified the Fixnum and Bignum classes into the Integer Class? &lt;strong&gt;Ruby 2.4&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;What version of Ruby introduced keyword arguments? &lt;strong&gt;Ruby 2.0&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;What version of Ruby introduced the safe navigation operator? &lt;strong&gt;Ruby 2.3&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;What version of Ruby introduced the ability to use colons for symbol keys alongside the hash syntax? &lt;strong&gt;Ruby 1.9&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;What version introduce method chaining using the yield_self method? &lt;strong&gt;Ruby 2.5&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;What is the estimated release date for Ruby 3.0? Hint: It’s a year. &lt;strong&gt;2020&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;When you define a method at the top level, what class is that method called on? &lt;strong&gt;Object Class&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;What is the standard Ruby interpreter often referred as? &lt;strong&gt;MRI&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;What Ruby implementation was designed for enterprise environments and optimized for large-scale Ruby on Rails apps? &lt;strong&gt;REE&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;What web framework did Ruby on Rails merge with for the release of Rails 3? &lt;strong&gt;Merb&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;What is the name of the popular graphic novel used to introduce Ruby to developers? &lt;strong&gt;Why’s (poignant) Guide to Ruby&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;What popular implementation of Ruby runs on the JVM? &lt;strong&gt;Jruby&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;What is the name of the upcoming implementation of Ruby on the GraalVM? &lt;strong&gt;TruffleRuby&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;What year did Matz recently announce as a potential year for him to retire? &lt;strong&gt;2025&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Can methods be added to a Struct? &lt;strong&gt;yes&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Which method is invoked when a method is not found? &lt;strong&gt;method_missing&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Which method is invoked when a constant is not found? &lt;strong&gt;const_missing&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;What error is raised if a method is passed the wrong number of arguments? &lt;strong&gt;ArgumentError&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;What is the default encoding of MRI? &lt;strong&gt;UTF-8&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Why must a module name begin with a capital letter? &lt;strong&gt;It’s a new constant&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Are constants public or private? &lt;strong&gt;public&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Is initialize public or private by default? &lt;strong&gt;private&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Does a method return a value if it does not contain an expression? &lt;strong&gt;it returns nil (which is a value)&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Name one immutable object in Ruby? &lt;strong&gt;symbols&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;</content><author><name>Jason Charnes</name></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jasoncharnes.com/images/sharing.png" /><media:content medium="image" url="https://jasoncharnes.com/images/sharing.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Eager Loading/Querying ActiveStorage Attachments</title><link href="https://jasoncharnes.com/eager-loading-querying-against-activestorage-attachments/" rel="alternate" type="text/html" title="Eager Loading/Querying ActiveStorage Attachments" /><published>2018-06-19T00:00:00+00:00</published><updated>2018-06-19T00:00:00+00:00</updated><id>repo://posts.collection/_posts/2018-06-19-eager-loading-querying-against-activestorage-attachments.md</id><content type="html" xml:base="https://jasoncharnes.com/eager-loading-querying-against-activestorage-attachments/">&lt;p&gt;&lt;a href=&quot;https://www.google.com/url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;source=web&amp;amp;cd=1&amp;amp;cad=rja&amp;amp;uact=8&amp;amp;ved=0ahUKEwih7JHCj-HbAhUHPa0KHRz5AxQQFggpMAA&amp;amp;url=http%3A%2F%2Fedgeguides.rubyonrails.org%2Factive_storage_overview.html&amp;amp;usg=AOvVaw1vWAZ_ZCS4JM3kjj-lxLEW&quot;&gt;ActiveStorage&lt;/a&gt;, the new kid on the block. It’s exciting for Ruby on Rails developers to have a built-in solution for file uploads/attachments. Let’s talk about interacting with the table ActiveStorage gives us. There are times that we’ll want to reach for eager loading and even query against our attachments. Without much effort, it’s easy to commit the N+1 sin.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;# app/models/thing.rb
class Thing &amp;lt; ApplicationRecord
  has_one_attached :image
end
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;# app/controllers/things_controller.rb
class ThingsController &amp;lt; ApplicationController
  def index
    @things = Thing.all
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code class=&quot;language-erb&quot;&gt;# app/views/things/index.html.erb
&amp;lt;% @things.each do |thing| %&amp;gt;
  &amp;lt;%= image_tag rails_blob_url(thing.image) %&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;👆 This view, my friends, is N+1 city. For every call to an image, ActiveStorage makes a call to a table where the image record resides.&lt;/p&gt;

&lt;h4 id=&quot;built-in-eager-loading&quot;&gt;Built-in Eager Loading&lt;/h4&gt;

&lt;p&gt;Rails, as you might come to expect, has a built-in solution to prevent this. Using the example above, you’ll note that we have a single attached image. Under the hood, this means that a &lt;code&gt;Thing&lt;/code&gt; is &lt;em&gt;&lt;strong&gt;implicitly&lt;/strong&gt;&lt;/em&gt; setup with the following relationship:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;class Thing &amp;lt; ApplicationRecord
  has_one :image_attachment, -&amp;gt; { where(name: &apos;image&apos;) }, class_name: &quot;ActiveStorage::Attachment&quot;, as: :record, inverse_of: :record, dependent: false
  has_one :image_blob, through: :image_attachment&quot;, class_name: &quot;ActiveStorage::Blob&quot;, source: :blob
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You get all this 👆 for free by adding &lt;code&gt;has_one_attached :image&lt;/code&gt; to your model. My attachment is named image, anytime you see a reference to image in my code, change it to your attachment name.&lt;/p&gt;

&lt;p&gt;A Rails scope exists to allow us to take advantage of this relationship. If we wanted to preload those images, we could change the controller to use the following scope:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;# app/controllers/things_controller.rb
class ThingsController &amp;lt; ApplicationController
  def index
    @things = Thing.with_attached_image.all
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This scope 👆 uses preloading under the hood 👇&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;includes(image_attachment: :blob)
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;querying-against-activestorage-attachments&quot;&gt;Querying Against ActiveStorage Attachments&lt;/h4&gt;

&lt;p&gt;Preloading is dandy, and all, but what happens when you want to query &lt;em&gt;against&lt;/em&gt; the attachment records? This question is similar to the use case that led me here.&lt;/p&gt;

&lt;p&gt;Specifically, I only wanted to show records that have an image attached. After digging through the ActiveStorage &lt;a href=&quot;https://github.com/rails/rails/blob/main/activestorage/lib/active_storage/attached/model.rb&quot;&gt;source code&lt;/a&gt;, I ended up finding not only the references to the code above but also the answer to this question.&lt;/p&gt;

&lt;p&gt;I’d like to return _only _the records without an image record. The following is the result 👇&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;Thing.where.missing(:image_attachment)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here, we piggybacked off the implementation of the earlier scope we saw, with_image_attachment.&lt;/p&gt;

&lt;p&gt;Throw this behind a scope and you’re cooking!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2018/12/stew-gif.gif&quot; alt=&quot;Carl Weathers stew goin!&quot; /&gt;&lt;/p&gt;</content><author><name>Jason Charnes</name></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jasoncharnes.com/images/sharing.png" /><media:content medium="image" url="https://jasoncharnes.com/images/sharing.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Adding Bootstrap Errors to Rails Fields with Errors</title><link href="https://jasoncharnes.com/bootstrap-4-rails-fields-with-errors/" rel="alternate" type="text/html" title="Adding Bootstrap Errors to Rails Fields with Errors" /><published>2018-02-13T00:00:00+00:00</published><updated>2018-02-13T00:00:00+00:00</updated><id>repo://posts.collection/_posts/2018-02-13-bootstrap-4-rails-fields-with-errors.md</id><content type="html" xml:base="https://jasoncharnes.com/bootstrap-4-rails-fields-with-errors/">&lt;p&gt;&lt;img src=&quot;/images/posts/2018/02/Screen-Shot-2018-02-11-at-4.46.04-PM-300x66.png&quot; alt=&quot;Field with errors&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The other day I was working on a new Rails application. Though I’m currently obsessed with &lt;a href=&quot;http://tailwindcss.com&quot;&gt;Tailwind CSS&lt;/a&gt;, this project was a better fit for Bootstrap. I needed some predefined styling, quick. Unfortunately, fields with errors got in my way. The app, like most web applications, required forms. Using Ruby on Rails’ (ActiveRecord) model validations, I was able to setup displaying error messages efficiently. I reached for a &lt;a href=&quot;http://getbootstrap.com/docs/4.0/components/alerts/&quot;&gt;Bootstrap alert&lt;/a&gt;, shoved in a loop of error messages, and done. Or, so I thought. 🤔 Isn’t it a better experience for the user if the fields that failed validation change border color? In fact, Bootstrap 4 &lt;a href=&quot;http://getbootstrap.com/docs/4.0/components/forms/#server-side&quot;&gt;has support for this&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id=&quot;the-problems-was-fields-with-errors&quot;&gt; The Problem(s) was Fields with Errors&lt;/h4&gt;

&lt;p&gt;Great! Except there’s one problem. If you’re familiar with Rails, you’ll know that when the page rerenders after a failed form validation, the field failing validation is wrapped inside &lt;code&gt;&amp;lt;div class=&quot;field-with-errors&quot; /&amp;gt;&lt;/code&gt;. In my case, I wanted to add the class name is-invalid to the failed input. In fact, “field with errors” doesn’t do much for me at all, since I’m not writing custom styling. Writing custom styling would allow me to write some CSS, like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;.field-with-errors input {
  border: 1px solid red;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This would have been extremely powerful, and a boost in development speed had I been writing my own CSS. In this case, though, we want to defer styling decisions to Bootstrap. As mentioned before, Bootstrap already has support for this. By writing this CSS above we’re hurting ourselves in one of two ways:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;We’re distancing ourselves from the styles provided by the CSS framework we’ve chosen to use. Or;&lt;/li&gt;
  &lt;li&gt;We’re creating more work for ourselves by trying to match the Bootstrap style with custom CSS.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;the-solution&quot;&gt;The Solution&lt;/h4&gt;

&lt;p&gt;If you’ve encountered this problem before, you might know that you can override this functionality. The solution I like best is a &lt;a href=&quot;https://stackoverflow.com/a/8380400/1930371&quot;&gt;Stack Overflow answer&lt;/a&gt;. Let’s start with the code in this solution, break down what it does, and then tweak it for Bootstrap 4.&lt;/p&gt;

&lt;h4 id=&quot;1-create-an-initializer&quot;&gt;1. Create an Initializer&lt;/h4&gt;

&lt;p&gt;Create an empty Ruby file: &lt;code&gt;config/initializers/customize_error.rb&lt;/code&gt;&lt;/p&gt;

&lt;h4 id=&quot;2-use-the-code&quot;&gt;2. Use the Code&lt;/h4&gt;

&lt;p&gt;Inside your newly created file, add the code.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
  class_attr_index = html_tag.index &apos;class=&quot;&apos;

  if class_attr_index
    html_tag.insert class_attr_index+7, &apos;error &apos;
  else
    html_tag.insert html_tag.index(&apos;&amp;gt;&apos;), &apos; class=&quot;error&quot;&apos;
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Let’s talk about what this chunk of code does. If your ActiveRecord backed form fails validation, ActionView calls this proc for each field that failed validation. The proc passes an html_tag (the form-field) and the instance into the block. If we didn’t overwrite it, it would wrap the field in a div that looks something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;div class=&quot;field-with-errors&quot;&amp;gt;... html_tag ...&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;However, we’re going to override that by modifying the field directly, versus wrapping it in a div.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;class_attr_index = html_tag.index &apos;class=&quot;&apos;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;👆🏻 This variable tells us if the field already has a class attribute, or if it doesn’t. If it does, we’ll get the index where class=” is in the raw HTML string. If it does not have class=” anywhere, we will set the variable to nil.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;if class_attr_index
  html_tag.insert class_attr_index+7, &apos;error &apos;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;👆🏻 If the variable is not nil, we can append the class name error to the beginning of the class name list. The extra space is essential. If “class” already exists as an attribute on the form field, we want to keep the existing class intact.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;else
  html_tag.insert html_tag.index(&apos;&amp;gt;&apos;), &apos; class=&quot;error&quot;&apos;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;👆🏻 If the variable is nil, right before we close the html_tag, we need to insert the entire class attribute assignment.&lt;/p&gt;

&lt;h4 id=&quot;3-modify-the-code-for-bootstrap-4&quot;&gt;3. Modify the Code for Bootstrap 4&lt;/h4&gt;

&lt;p&gt;There are only a few changes I’ll make here.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;ActionView::Base.field_error_proc = proc do |html_tag, _instance|
  class_attr_index = html_tag.index &apos;class=&quot;&apos;

  if class_attr_index
    html_tag.insert class_attr_index + 7, &apos;is-invalid &apos;
  else
    html_tag.insert html_tag.index(&apos;&amp;gt;&apos;), &apos; class=&quot;is-invalid&quot;&apos;
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The most important change is converting the class name from error to is-invalid. With this done, &lt;strong&gt;be sure to restart your Rails app&lt;/strong&gt; as initializers load on boot. In front of the argument “instance,” I added an underscore. This underscore may look silly to you, but it is a standard convention for block variables passed in and never used.&lt;/p&gt;

&lt;h4 id=&quot;do-what-feels-right&quot;&gt;Do What Feels “Right”&lt;/h4&gt;

&lt;p&gt;There were many ways I could have Made This Work™. However, they would have felt like a hack. For instance, I could have used JavaScript to apply the Bootstrap field is-invalid to the form field once the page re-rendered. Or, I could have tried to re-create the Bootstrap styling for errors. However, with a little patience and research, it turns out &lt;a href=&quot;https://jasoncharnes.com/learning-ruby/&quot;&gt;Rails had the tools&lt;/a&gt; at my disposal all along.&lt;/p&gt;</content><author><name>Jason Charnes</name></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jasoncharnes.com/images/sharing.png" /><media:content medium="image" url="https://jasoncharnes.com/images/sharing.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>