CINXE.COM
eileen.codes
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>eileen.codes</title> <meta name="google-site-verification" content="EYDL78pbIclS_cpFovjgs6kHqmKw3sw9xgo19_M42N4" /> <meta name="description" content="Eileen Codes is a blog by Eileen M. Uchitelle about developing with and learning Ruby on Rails, a programming framework." /> <meta name="keywords" content="Eileen Uchitelle, Uchitelle, Eileen M Uchitelle, Abe Uchitelle, Eileen Codes, Ruby on Rails, Eileen Builds with Rails, Builds with Rails, rails, ruby, new york, new york web developer, hudson valley rails, hudson valley web developer, Eileen Carpenter, Eileen M. Carpenter, web development, rails web development, rails websites, rails blogs, rails blogs new york, rails blog eileen, blog about rails, ruby blog, capistrano, unicorn, nginx" /> <link rel="stylesheet" href="/css/main.css"> <link rel="canonical" href="http://eileencodes.com/"> <link rel="alternate" type="application/rss+xml" title="eileen.codes" href="http://eileencodes.com/feed.xml" /> <link href='https://fonts.googleapis.com/css?family=Raleway:500,700' rel='stylesheet' type='text/css'> <link rel="author" href="https://plus.google.com/u/0/109313797607962965718/posts" /> <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" /> <!-- Google tag (gtag.js) --> <script async src="https://www.googletagmanager.com/gtag/js?id=G-VMFKFZJVRS"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-VMFKFZJVRS'); </script> </head> <body> <header class="site-header"> <div class="wrapper"> <div class="site-title-holder"> <a class="site-title" href="/">eileen.codes</a> </div> <nav class="site-nav"> <a href="#" class="menu-icon"> <svg viewBox="0 0 18 15"> <path fill="#424242" d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.031C17.335,0,18,0.665,18,1.484L18,1.484z"/> <path fill="#424242" d="M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0c0-0.82,0.665-1.484,1.484-1.484 h15.031C17.335,6.031,18,6.696,18,7.516L18,7.516z"/> <path fill="#424242" d="M18,13.516C18,14.335,17.335,15,16.516,15H1.484C0.665,15,0,14.335,0,13.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.031C17.335,12.031,18,12.696,18,13.516L18,13.516z"/> </svg> </a> <div class="trigger"> <a class="page-link" href="/">Blog</a> <a class="page-link" href="/speaking">Speaking</a> </div> </nav> </div> </header> <div class="page-content"> <div class="wrapper main"> <div class="content"> <div class="image header-image"> <img src="/assets/eileen-railsworld.jpg" alt="Eileen speaking at Rails World" /> The Myth of the Modular Monolith at Rails World. Photo by Aaron Patterson. </div> <div class="home"> <div class="post-list"> <div class="post"> <span class="post-meta">Feb 21, 2023</span> <h2> <a class="post-link" href="/posts/the-case-against-monkey-patching/">The Case Against Monkey Patching</a> </h2> <p>Monkey patching is considered one of the more powerful features of the Ruby programming language. However, by the end of this post I’m hoping to convince you that they should be used sparingly, if at all, because they are brittle, dangerous, and often unnecessary. I’ll also share tips on how to use them as safely as possible in the rare cases where you do need to monkey patch.</p> <p>Read more on the <a href="https://shopify.engineering/the-case-against-monkey-patching" target="_blank">Shopify Engineering Blog</a></p> </div> <div class="categories"> <strong>Categories:</strong> <a href="/categories/shopify">shopify</a> </div> <div class="post"> <span class="post-meta">Jul 12, 2021</span> <h2> <a class="post-link" href="/posts/adding-support-cross-cluster-associations-rails-7/">Adding support for cross-cluster associations to Rails 7</a> </h2> <p>At GitHub, we recently added a new feature to Rails that will be available in 7.0: support for handling associations across database clusters. Read about it on the <a href="https://github.blog/2021-07-12-adding-support-cross-cluster-associations-rails-7/">blog</a>.</p> </div> <div class="categories"> <strong>Categories:</strong> <a href="/categories/github">github</a> </div> <div class="post"> <span class="post-meta">Aug 25, 2020</span> <h2> <a class="post-link" href="/posts/upgrading-github-to-ruby-2-7/">Upgrading GitHub to Ruby 2.7</a> </h2> <p>Read about GitHub’s Ruby 2.7 upgrade at <a href="https://github.blog/2020-08-25-upgrading-github-to-ruby-2-7/">https://github.blog/2020-08-25-upgrading-github-to-ruby-2-7/</a>.</p> </div> <div class="categories"> <strong>Categories:</strong> <a href="/categories/github">github</a> </div> <div class="post"> <span class="post-meta">Sep 9, 2019</span> <h2> <a class="post-link" href="/posts/running-github-on-rails-6-0/">Running GitHub on Rails 6.0</a> </h2> <p>Read about GitHub’s Rails 6.0 upgrade at <a href="https://github.blog/2019-09-09-running-github-on-rails-6-0/">https://github.blog/2019-09-09-running-github-on-rails-6-0/</a>.</p> </div> <div class="categories"> <strong>Categories:</strong> <a href="/categories/github">github</a> </div> <div class="post"> <span class="post-meta">Sep 26, 2018</span> <h2> <a class="post-link" href="/posts/upgrading-github-from-3-2-to-5-2/">Upgrading GitHub from 3.2 to 5.2</a> </h2> <p>Read about GitHub’s Rails upgrade at <a href="https://github.blog/2018-09-28-upgrading-github-from-rails-3-2-to-5-2/">https://github.blog/2018-09-28-upgrading-github-from-rails-3-2-to-5-2/</a>.</p> </div> <div class="categories"> <strong>Categories:</strong> <a href="/categories/github">github</a> </div> <div class="post"> <span class="post-meta">Sep 29, 2017</span> <h2> <a class="post-link" href="/posts/http2-early-hints/">HTTP2 Early Hints</a> </h2> <p>Update: The PR’s discussed in this blog post have been merged. You can try out Early Hints by using Rails and Puma master. You’ll need to also use Arel master until Rails 5.2 is released.</p> <p>Recently I’ve been working with <a href="https://twitter.com/tenderlove" target="_blank">Aaron Patterson</a> on implementing the HTTP2 Early Hints.</p> <p>The spec for Early Hints is still in <a href="https://tools.ietf.org/html/draft-ietf-httpbis-early-hints-04" target="_blank">draft</a> but explains the requirements for implementation. In order to start preparing Rails and Rack for HTTP2 we’ve implemented Early Hints handling in Puma and Rails.</p> <p>As of today (September 29, 2017) the pull requests haven’t been merged but we’d love for you to try them out if you’re interested in implementing Early Hints. A lot of this work is somewhat experimental so try it on production at your own risk.</p> <p>In this post I’ll go over what early hints are, what the spec expects, and finally how to use the two pull requests to test it out on your own application.</p> <h3 id="early-hints-what-huh">Early Hints, what huh?</h3> <p>Early Hints is a new HTTP status code that allows your application to send links to assets that you would like to load early. For example if you have a stylesheet and javascript file included in your Rails application you may want to tell the client about them early so it can start downloading them.</p> <p>The Early Hints spec contains header Links with references to those resources that you need downloaded early. An example response from the server looks like this:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> HTTP/1.1 103 Early Hints Link: </style.css>; rel=preload; as=style Link: </script.js>; rel=preload; as=script HTTP/1.1 200 OK Date: Fri, 26 May 2017 10:02:11 GMT Content-Length: 1234 Content-Type: text/html; charset=utf-8 Link: </style.css>; rel=preload; as=style Link: </script.js>; rel=preload; as=script </code></pre></div></div> <p>There are 2 responses, one for Early Hints that sends the linked resources and one for the final request that should also include the same links.</p> <p>For the Link header, <code class="language-plaintext highlighter-rouge">Link: </style.css>; rel=preload; as=style</code> the <code class="language-plaintext highlighter-rouge">style.css</code> is the path to the css file, <code class="language-plaintext highlighter-rouge">rel</code> does not change and should be <code class="language-plaintext highlighter-rouge">preload</code>, and <code class="language-plaintext highlighter-rouge">as</code> is the type of resource you’re sending. The <code class="language-plaintext highlighter-rouge">as</code> is not required, but is useful for content-security policies.</p> <p>While HTTP/1.1 <em>can</em> accept a 103, a server might not actually send the hints unless it absolutely knows they will be accepted. HTTP/2 is less likely to have this problem as handling of response headers doesn’t affect how the response body is determined (as noted in the spec.</p> <h3 id="implementing-early-hints-with-puma-and-rails">Implementing Early Hints with Puma and Rails</h3> <p>The <a href="https://github.com/puma/puma/pull/1403" target="_blank">Puma PR</a> and <a href="https://github.com/rails/rails/pull/30744" target="_blank">Rails PR</a> are both a work in progress so they are likely to change before we merge them into their respective projects.</p> <p>Below I’ll describe how you can try these two out in your Rails app. First make sure you’re using the Rails and Puma gems set to the branch for these PRs’</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Gemfile gem 'rails', git: 'https://github.com/eileencodes/rails', branch: 'early-hints' gem 'puma', git: 'https://github.com/eileencodes/puma', branch: 'early-hints' gem 'arel', git: 'https://github.com/rails/arel' </code></pre></div></div> <p>Next you’ll need a proxy that can handle HTTP/2.</p> <p>Install <a href="https://github.com/h2o/h2o" target="_blank">h2o</a> via homebrew or the method you need for your computer. I used homebrew with <code class="language-plaintext highlighter-rouge">brew install h2o</code>.</p> <p>Find the h2o config file (mine is in <code class="language-plaintext highlighter-rouge">/usr/local/etc/h2o/h2o.conf</code> and update it with the following:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>hosts: "localhost": listen: port: 9090 ssl: certificate-file: /usr/local/etc/h2o/localhost.crt key-file: /usr/local/etc/h2o/localhost.key paths: "/": proxy.reverse.url: "http://127.0.0.1:3000/" access-log: /usr/local/var/h2o/access-log error-log: /usr/local/var/h2o/error-log </code></pre></div></div> <p>Next you’ll need a “fake” certificate so you can do HTTPS requests with localhost. Otherwise Early Hints won’t work. See <a href="http://kokizzu.blogspot.com/2015/02/how-to-install-h2o-http2-web-server.html" target="_blank">this post</a> for more information on the following.</p> <p>Run this command:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout localhost.key -out localhost.crt </code></pre></div></div> <p>And follow the prompts. I hit <code class="language-plaintext highlighter-rouge">enter</code> for everything. Then move your certificate and key into your h2o folder since that’s where the config is looking. If you want the cert to live somewhere else, update your h2o.conf with that new path.</p> <p>Now start the h2o server with the config: <code class="language-plaintext highlighter-rouge">h2o -c h2o/h2o.conf</code></p> <p>And start your Rails server (if it’s a Rails 5 app you will automatically be using Puma. This will not work if you’re not using the Puma branch I linked above): <code class="language-plaintext highlighter-rouge">bin/rails s --early-hints</code></p> <p>Open Chrome and go to <code class="language-plaintext highlighter-rouge">https://localhost:9090/someurl</code> replacing <code class="language-plaintext highlighter-rouge">someurl</code> with a URL you know uses a <code class="language-plaintext highlighter-rouge">javascript_include_tag</code> or a <code class="language-plaintext highlighter-rouge">stylesheet_link_tag</code> because that’s the way Early Hints is currently implemented in Rails.</p> <p>Open the Chrome dev tools and go to the network tab. From there you should see <code class="language-plaintext highlighter-rouge">Push / posts</code> where <code class="language-plaintext highlighter-rouge">posts</code> is the URL you entered under the “Initiator” column. Below is a screenshot of my Chrome dev tools showing the Early Hints loading. If you click the image to load the full side it is easier to view.</p> <p><a href="/assets/early_hints.png" target="_blank"><img src="/assets/early_hints.png" alt="Early Hints Chrome Browser with Rails and Puma" /></a></p> </div> <div class="categories"> <strong>Categories:</strong> <a href="/categories/new-features">new-features</a> <a href="/categories/open-source">open-source</a> </div> <div class="post"> <span class="post-meta">Feb 27, 2016</span> <h2> <a class="post-link" href="/posts/my-process-for-writing-a-talk/">My Process for Writing a Talk</a> </h2> <p>There’s a ton of blog posts out there with advice on how to write talks. They all discuss the “right way”, but in reality I don’t think anyone follows a process prescribed by someone else.</p> <p>I’m a very visual person and in a way I write talks backwards. “The right way” would be to write copy and then build the slides around it. I shouldn’t even be opening Keynote until I have solid, well-articulated copy. But that’s not how I’ve been writing talks.</p> <p>I’m definitely not recommending you follow my way of doing things, but I thought it would be fun to share my process. I’ve developed approximately 6 talks between meetups and conferences. I put a lot of time and effort into each one. My <a href="http://eileencodes.com/speaking/#how-to-performance">How to Performance</a> talk was probably 100-120+ hours depending on if you count revisions and practice I did before each conference.</p> <p>Here’s my process:</p> <ol> <li> <p>Talk to anyone who will listen about something I’m passionate about or working on recently. The talk I’m currently writing is about Security. I’ve ranted and explained all sort of things I believe about security and patching applications to anyone who will listen; my dog, my husband, my friends and coworkers. If I keep talking about it enough, I know I care about it enough to turn it into a talk.</p> </li> <li> <p>Collect ideas in a Google doc so I can access the file anywhere.</p> </li> <li> <p>Come up with a title (see I told you this was backwards because this is “supposed to” be after an abstract)</p> </li> <li> <p>Write an abstract.</p> <ul> <li> <p>Write something, anything down that resembles a beginning, middle and end of an abstract</p> </li> <li> <p>Show it to my husband who tells me how to write a better one</p> </li> <li> <p>State that I can’t do this, I don’t know how to do this <img src="/assets/table_flip.jpg" alt="Table flip" /></p> </li> <li> <p>Go to the gym and work out my frustration</p> </li> <li> <p>Come back and bang out a kick-ass abstract</p> </li> </ul> </li> <li> <p>Write an outline. This is where it starts to get weird.</p> </li> <li> <p>Open Keynote and pick colors. Colors are very important to me. I was a photography major and have a design and art background. If the colors don’t feel right I can’t write the talk.</p> </li> <li> <p>Collect memes and gifs to help express myself.</p> </li> <li> <p>Build out the middle slides; the meat. This is generally where I start adding all the gifs I’ve saved over the past couple months that I think would go great with sentiments I have in the talk.</p> </li> <li> <p>Freak out that this talk isn’t going well and it will never be good. I’ve given 3 well liked talks at 8 conferences and I still believe they were a one-hit wonder and no one will like any future talks. This is something I deal with every time, and it’s hard. It’s difficult to tell yourself you’re going to be fine. That’s why it’s good to have a great support system of family and friends who will help pull your head out of your ass so you can keep working. <img src="/assets/crying.gif" alt="Crying" style="margin:20px;" /></p> </li> <li> <p>Start writing copy for the beginning slides I never added. Add slides to fill in the opening of the talk as I write them.</p> </li> <li> <p>Write the copy for the ending slides I never added. Add slides to fill in the end of the talk as I write them.</p> </li> <li> <p>Go back to the middle slides and write the copy for those adding, removing, and reordering slides as necessary. Once I’m satisfied the talk is “written” I go back and edit copy. Written to me just means I could go give this talk as is and it would be complete, but confusing. It’s not perfect but all my main points are in there.</p> </li> <li> <p>Give talk at a local meetup.</p> </li> <li> <p>Make changes based on the meetup feedback.</p> </li> <li> <p>Practice. Edit. Practice. Every night for 2-3 weeks leading up to the conference.</p> </li> <li> <p>Give talk at a conference.</p> </li> <li> <p>Make changes based on things I felt were confusing and based on questions/feedback I get.</p> </li> <li> <p>Repeat 15-17 until I retire the talk.</p> </li> </ol> <p><img src="/assets/rabbit.jpg" alt="Rinse and repeat" /></p> <p>This process, while convoluted at points, is my process. This works for me. Don’t let anyone tell you you’re doing it wrong. It’s your talk. If you a) get up and actually do it or b) people find your talk interesting, then you were successful. Find what works for you and what gets you up there on that stage. That’s all the matters.</p> <p>I’m giving talks at 4 conferences so far this year. Mountain West Ruby Conference in March, Twilio’s SignalConf in May, Brighton Ruby Conference in July, and AbstractionsConf in August. You can always find what conferences I’ll be at on my <a href="http://eileencodes.com/speaking">speaking</a> page.</p> </div> <div class="categories"> <strong>Categories:</strong> <a href="/categories/conferences">conferences</a> <a href="/categories/opinion">opinion</a> <a href="/categories/tips">tips</a> </div> <div class="post"> <span class="post-meta">Nov 11, 2015</span> <h2> <a class="post-link" href="/posts/the-sprockets-4-manifest/">Rails 5: The Sprockets 4 Manifest</a> </h2> <aside>As we work towards the release of Rails 5 there are a lot of changes will affect your application when you choose to upgrade. To help you keep up with the rapid development and changes I'm starting a series of blog posts to help you be ready to upgrade when that time comes.</aside> <p>When Rails 5 is released it will require that you upgrade to Sprockets 4. Sprockets 4 has some big changes in how it knows what assets to compile so you will definitely have some updates to make if you rely on Sprockets within Rails. Since there are a lot of changes in Sprockets 4 I’ll just be talking about the new <code class="language-plaintext highlighter-rouge">manifest.js</code> in this post.</p> <p>With Sprockets you used to tell your <code class="language-plaintext highlighter-rouge">config/initializers/assets.rb</code> what assets were supposed to be precompiled. In Sprockets 4 you will use a <code class="language-plaintext highlighter-rouge">manifest.js</code> inside your <code class="language-plaintext highlighter-rouge">app/assets/</code> directory to tell Sprockets what assets to precompile. This behavior is actually available to use in Sprockets 3 but <a href="https://github.com/rails/sprockets-rails/blob/93a45b1c463a063ec7cf4d160107b67aa3db7a1a/lib/sprockets/railtie.rb#L77-L81" target="_blank">sprockets-rails</a> has a conditional that only activates this in Sprockets 4.</p> <figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="c1"># sprockets-rails/lib/sprockets/railtie.rb</span> <span class="k">if</span> <span class="n">using_sprockets4?</span> <span class="n">config</span><span class="p">.</span><span class="nf">assets</span><span class="p">.</span><span class="nf">precompile</span> <span class="o">=</span> <span class="sx">%w( manifest.js )</span> <span class="k">else</span> <span class="n">config</span><span class="p">.</span><span class="nf">assets</span><span class="p">.</span><span class="nf">precompile</span> <span class="o">=</span> <span class="p">[</span><span class="no">LOOSE_APP_ASSETS</span><span class="p">,</span> <span class="sr">/(?:\/|\\|\A)application\.(css|js)$/</span><span class="p">]</span> <span class="k">end</span></code></pre></figure> <p><i>Note: the file type that <code class="language-plaintext highlighter-rouge">manifest.js</code> is stored as may change. There is disucssion around moving the <code class="language-plaintext highlighter-rouge">manifest.js</code> to <code class="language-plaintext highlighter-rouge">manifest.yml</code> because it doesn’t make sense that the manifest has a file type that is unrelated to it’s usage.</i></p> <p>So, how do you use a the new manifest file? In your <code class="language-plaintext highlighter-rouge">app/assets/</code> directory add a new directory named <code class="language-plaintext highlighter-rouge">config/</code>. Inside that folder add a file called <code class="language-plaintext highlighter-rouge">manifest.js</code>.</p> <p>In the <code class="language-plaintext highlighter-rouge">manifest.js</code> you’ll want to link your JS and CSS directories as well as any other directories you rely on like images, fonts, sounds etc.</p> <p>Here is an example of a <code class="language-plaintext highlighter-rouge">manifest.js</code> that links JS, CSS, fonts, and images.</p> <figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="c1">// JS and CSS bundles</span> <span class="c1">//</span> <span class="c1">//= link_directory ../javascripts .js</span> <span class="c1">//= link_directory ../stylesheets .css</span> <span class="c1">// Images and fonts so that views can link to them</span> <span class="c1">//</span> <span class="c1">//= link_tree ../fonts</span> <span class="c1">//= link_tree ../images</span></code></pre></figure> <p>Previously you didn’t need to include fonts and images in your precompiled assets list and Sprockets Rails would use the <code class="language-plaintext highlighter-rouge">LOOSE_APP_ASSETS</code> constant to figure out those items, but now you have to explicitly include them in your config.</p> <p>You’ll notice that we use <code class="language-plaintext highlighter-rouge">link_directory</code> for CSS and JS, then the path from the config manifest file to the javascript “file”. We compile <code class="language-plaintext highlighter-rouge">.coffee</code> and <code class="language-plaintext highlighter-rouge">.scss</code> down to <code class="language-plaintext highlighter-rouge">.js</code> and <code class="language-plaintext highlighter-rouge">.css</code>, respectively, so we denote that after the path to the JS and CSS files to tell Sprockets what to compile them into. Images and fonts don’t change file type when compiled.</p> <p>Once you’ve done that you’ll need to remove <code class="language-plaintext highlighter-rouge">config.assets.precompile</code> from your <code class="language-plaintext highlighter-rouge">config/initializers/assets.rb</code>.</p> <figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="n">config</span><span class="p">.</span><span class="nf">assets</span><span class="p">.</span><span class="nf">precompile</span> <span class="o">+=</span> <span class="sx">%w( all.css all.js )</span></code></pre></figure> <p>Smaller apps may only have the <code class="language-plaintext highlighter-rouge">precompile</code> directive in their applications so in that case you can delete the <code class="language-plaintext highlighter-rouge">config/initializers/assets.rb</code> file. For larger apps, like Basecamp we have some extra settings regarding assets and didn’t want to delete the config file.</p> </div> <div class="categories"> <strong>Categories:</strong> <a href="/categories/rails-5">rails-5</a> </div> <div class="post"> <span class="post-meta">Sep 20, 2015</span> <h2> <a class="post-link" href="/posts/actioncontroller-parameters-now-returns-an-object-instead-of-a-hash/">Rails 5: ActionController::Parameters Now Returns an Object Instead of a Hash</a> </h2> <aside>As we work towards the release of Rails 5 there are a lot of changes will affect your application when you choose to upgrade. To help you keep up with the rapid development and changes I'm starting a series of blog posts to help you be ready to upgrade when that time comes.</aside> <p>A big change coming is how <code class="language-plaintext highlighter-rouge">ActionController::Parameters</code> works. <code class="language-plaintext highlighter-rouge">ActionController::Parameters</code> is where all of your <code class="language-plaintext highlighter-rouge">params</code> come from for your controllers. Calling <code class="language-plaintext highlighter-rouge">params</code> used to return a hash, but now will return an object.</p> <p>Note: this doesn’t affect accessing the keys in the params hash like <code class="language-plaintext highlighter-rouge">params[:id]</code>. You can view the PR that implemented this change here: <a href="https://github.com/rails/rails/pull/20868" target="_blank">https://github.com/rails/rails/pull/20868</a></p> <p>To access the parameters in the object you can add <code class="language-plaintext highlighter-rouge">#to_h</code> to the parameters:</p> <figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="n">params</span><span class="p">.</span><span class="nf">to_h</span></code></pre></figure> <p>If those params aren’t explictly permitted you will be returned a hash with only the permitted parameters. If none are permitted you’ll get an empy hash (<code class="language-plaintext highlighter-rouge">{}</code>). This comes in where you may be running <code class="language-plaintext highlighter-rouge">#symbolize_keys</code> or <code class="language-plaintext highlighter-rouge">#slice</code> on unpermitted <code class="language-plaintext highlighter-rouge">params</code>. If you’re accessing <code class="language-plaintext highlighter-rouge">params</code> that aren’t being saved to a model/db then you probably aren’t explictly permitting those parameters.</p> <p>If we look at the <code class="language-plaintext highlighter-rouge">#to_h</code> method in <code class="language-plaintext highlighter-rouge">ActionController::Parameters</code> we can see it checks if the parameters are permitted before converting them to a hash.</p> <figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="c1"># actionpack/lib/action_controller/metal/strong_parameters.rb</span> <span class="k">def</span> <span class="nf">to_h</span> <span class="k">if</span> <span class="n">permitted?</span> <span class="vi">@parameters</span><span class="p">.</span><span class="nf">to_h</span> <span class="k">else</span> <span class="n">slice</span><span class="p">(</span><span class="o">*</span><span class="nb">self</span><span class="p">.</span><span class="nf">class</span><span class="p">.</span><span class="nf">always_permitted_parameters</span><span class="p">).</span><span class="nf">permit!</span><span class="p">.</span><span class="nf">to_h</span> <span class="k">end</span> <span class="k">end</span></code></pre></figure> <p>Let’s take an example where we are slicing params to use later. If we have this method that slices params we used to be able to write:</p> <figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">def</span> <span class="nf">do_something_with_params</span> <span class="n">params</span><span class="p">.</span><span class="nf">slice</span><span class="p">(</span><span class="ss">:param_1</span><span class="p">,</span> <span class="ss">:param_2</span><span class="p">)</span> <span class="k">end</span></code></pre></figure> <p>Which would return:</p> <figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"> <span class="p">{</span> <span class="ss">:param_1</span> <span class="o">=></span> <span class="s2">"a"</span><span class="p">,</span> <span class="ss">:param_2</span> <span class="o">=></span> <span class="s2">"2"</span> <span class="p">}</span></code></pre></figure> <p>But now that will return an <code class="language-plaintext highlighter-rouge">ActionController::Parameters</code> object.</p> <p>Calling <code class="language-plaintext highlighter-rouge">#to_h</code> on this would return an empty hash because <code class="language-plaintext highlighter-rouge">param_1</code> and <code class="language-plaintext highlighter-rouge">param_2</code> aren’t permitted.</p> <p>To get access to the params from <code class="language-plaintext highlighter-rouge">ActionController::Parameters</code> you need to first permit the params and then call <code class="language-plaintext highlighter-rouge">#to_h</code> on the object. The following returns the same thing as slice did previously.</p> <figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">def</span> <span class="nf">do_something_with_params</span> <span class="n">params</span><span class="p">.</span><span class="nf">permit</span><span class="p">([</span><span class="ss">:param_1</span><span class="p">,</span> <span class="ss">:param_2</span><span class="p">]).</span><span class="nf">to_h</span> <span class="k">end</span></code></pre></figure> <p>Another way to do this would be to use <code class="language-plaintext highlighter-rouge">#to_unsafe_hash</code> if you know the params are not user supplied and are safe:</p> <figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">def</span> <span class="nf">do_something_with_params</span> <span class="n">params</span><span class="p">.</span><span class="nf">to_unsafe_h</span><span class="p">.</span><span class="nf">slice</span><span class="p">(</span><span class="ss">:param_1</span><span class="p">,</span> <span class="ss">:param_2</span><span class="p">)</span> <span class="k">end</span></code></pre></figure> <p>By default <code class="language-plaintext highlighter-rouge">controller</code> and <code class="language-plaintext highlighter-rouge">action</code> parameters are allowed. To explicitly always allow other parameters you can set a configuration option in your <code class="language-plaintext highlighter-rouge">application.rb</code> that allows those parameters. Note: this will return the hash with string keys, not symbol keys.</p> <p>Config option:</p> <figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"> <span class="n">config</span><span class="p">.</span><span class="nf">always_permitted_parameters</span> <span class="o">=</span> <span class="sx">%w( controller action param_1 param_2 )</span></code></pre></figure> <p>Calling slice on the parameters:</p> <figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">def</span> <span class="nf">do_something_with_params</span> <span class="n">params</span><span class="p">.</span><span class="nf">slice</span><span class="p">(</span><span class="s2">"param_1"</span><span class="p">,</span> <span class="s2">"param_2"</span><span class="p">).</span><span class="nf">to_h</span> <span class="k">end</span></code></pre></figure> <p>If you’re not sure when you’ll have time to upgrade it would be a good idea to write some tests for your controllers that access the <code class="language-plaintext highlighter-rouge">params</code>. That way when you do upgrade you’ll know to fix the params because your tests will be failing.</p> </div> <div class="categories"> <strong>Categories:</strong> <a href="/categories/rails-5">rails-5</a> </div> <div class="post"> <span class="post-meta">Aug 28, 2015</span> <h2> <a class="post-link" href="/posts/website-redesign-with-jekyll-and-github-pages/">Website Redesign with Jekyll and Github Pages</a> </h2> <p>Back in 2012 I built my first Rails app from scratch. It was a little blog that was meant as a learning tool and a way to contribute back to a community that gives so much to beginngers (gems, mentoring, etc).</p> <p>I learned a lot from that blog, it helped me get jobs, and kept me accountable for the things I learned. It served as both a place to try new features and to record things I learned. It was where I built my first admin system, wrote about learning to build a forgot password form, everything.</p> <p>But I realized I was neglecting it. I dreaded Rails security vulnerabilities, server vulnerabilities, and the chore that upgrading it to the next verison of Rails was going to be. It was also in desperate need of a design overhaul and didn’t look great on mobile browsers.</p> <p>A few weeks ago I decided that I was tired of all of the above, and that my little blog had served it’s purpose well more than I had expected too. It helped me grow my career and myself.</p> <p>Earlier today I swapped my blog to Github pages. I have to say I am very impressed with <a href="http://jekyllrb.com/" target="_blank">Jekyll</a> even though I’ll miss my little Rails blog that I built from scratch. Jekyll is very powerful with great documentation. I was able to basically recreate my blog with the same URLs, RSS feed, and all. I have a front-end background so I was able to make my own theme quickly and easily.</p> <p>The one caveat is that Github pages runs on a different version of Jekyll so some of the things in the documentation aren’t correct for that version. Once I figure that out though it was smooth sailing.</p> <p>For posterity, here’s a picture of the old blog. I’m going to miss it.</p> <p><img src="/assets/blog.png" alt="Previous Site Screenshot" /></p> </div> <div class="categories"> <strong>Categories:</strong> <a href="/categories/updates">updates</a> </div> </div> <div class="pagination"> <span>« Prev</span> <em>1</em> <a href="/posts/2">2</a> <a href="/posts/3">3</a> <a href="/posts/4">4</a> <a href="/posts/5">5</a> <a href="/posts/2">Next »</a> </div> </div> </div> <div class="sidebar"> <h3>About</h3> <p>Hi, I'm Eileen! I work at Shopify as a Senior Staff Software Engineer on the Ruby and Rails Infrastructure team. I love contributing to open source and speaking at conferences. I've been a member of the Rails Core team since 2017 and the Ruby Core Committers team since 2024. I'm passionate about making the open source world more welcoming and accessible, as well as improving performance, security, and scalability as applications grow.</p> <h4>Where to find me</h4> <ul> <li> <a href="https://twitter.com/eileencodes" class="twitter-follow-button" data-show-count="false" data-size="large" data-dnt="true">Follow @eileencodes</a> <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> </li> <li> <a href="https://github.com/eileencodes"> <span class="icon icon--github"> <svg viewBox="0 0 16 16"> <path fill="#828282" d="M7.999,0.431c-4.285,0-7.76,3.474-7.76,7.761 c0,3.428,2.223,6.337,5.307,7.363c0.388,0.071,0.53-0.168,0.53-0.374c0-0.184-0.007-0.672-0.01-1.32 c-2.159,0.469-2.614-1.04-2.614-1.04c-0.353-0.896-0.862-1.135-0.862-1.135c-0.705-0.481,0.053-0.472,0.053-0.472 c0.779,0.055,1.189,0.8,1.189,0.8c0.692,1.186,1.816,0.843,2.258,0.645c0.071-0.502,0.271-0.843,0.493-1.037 C4.86,11.425,3.049,10.76,3.049,7.786c0-0.847,0.302-1.54,0.799-2.082C3.768,5.507,3.501,4.718,3.924,3.65 c0,0,0.652-0.209,2.134,0.796C6.677,4.273,7.34,4.187,8,4.184c0.659,0.003,1.323,0.089,1.943,0.261 c1.482-1.004,2.132-0.796,2.132-0.796c0.423,1.068,0.157,1.857,0.077,2.054c0.497,0.542,0.798,1.235,0.798,2.082 c0,2.981-1.814,3.637-3.543,3.829c0.279,0.24,0.527,0.713,0.527,1.437c0,1.037-0.01,1.874-0.01,2.129 c0,0.208,0.14,0.449,0.534,0.373c3.081-1.028,5.302-3.935,5.302-7.362C15.76,3.906,12.285,0.431,7.999,0.431z"/> </svg> </span> <span class="username">eileencodes</span> </a> </li> <li> <a href="https://linkedin.com/in/eileencodes"> <span class="icon icon--linkedin"> <svg viewBox="0 0 1792 1792"> <path d="M365 1414h231v-694h-231v694zm246-908q-1-52-36-86t-93-34-94.5 34-36.5 86q0 51 35.5 85.5t92.5 34.5h1q59 0 95-34.5t36-85.5zm585 908h231v-398q0-154-73-233t-193-79q-136 0-209 117h2v-101h-231q3 66 0 694h231v-388q0-38 7-56 15-35 45-59.5t74-24.5q116 0 116 157v371zm468-998v960q0 119-84.5 203.5t-203.5 84.5h-960q-119 0-203.5-84.5t-84.5-203.5v-960q0-119 84.5-203.5t203.5-84.5h960q119 0 203.5 84.5t84.5 203.5z"/> </svg> </span> <span class="username">eileencodes</span> </a> </li> <li> <a href="/feed.xml"> <span class="icon icon--rss"> <svg viewBox="0 0 1792 1792"> <path d="M640 1280q0-53-37.5-90.5t-90.5-37.5-90.5 37.5-37.5 90.5 37.5 90.5 90.5 37.5 90.5-37.5 37.5-90.5zm351 94q-13-232-177-396t-396-177q-14-1-24 9t-10 23v128q0 13 8.5 22t21.5 10q154 11 264 121t121 264q1 13 10 21.5t22 8.5h128q13 0 23-10t9-24zm384 1q-5-154-56-297.5t-139.5-260-205-205-260-139.5-297.5-56q-14-1-23 9-10 10-10 23v128q0 13 9 22t22 10q204 7 378 111.5t278.5 278.5 111.5 378q1 13 10 22t22 9h128q13 0 23-10 11-9 9-23zm289-959v960q0 119-84.5 203.5t-203.5 84.5h-960q-119 0-203.5-84.5t-84.5-203.5v-960q0-119 84.5-203.5t203.5-84.5h960q119 0 203.5 84.5t84.5 203.5z"/> </svg> </span> <span class="username">RSS</span> </a> </li> </ul> <br /> <h4>Categories</h4> <ul> <li><a href="/categories/activerecord">activerecord</a></li> <li><a href="/categories/administration">administration</a></li> <li><a href="/categories/cms-functionality">cms-functionality</a></li> <li><a href="/categories/conferences">conferences</a></li> <li><a href="/categories/deployment">deployment</a></li> <li><a href="/categories/errors">errors</a></li> <li><a href="/categories/gems">gems</a></li> <li><a href="/categories/github">github</a></li> <li><a href="/categories/learning-rails">learning-rails</a></li> <li><a href="/categories/mysql">mysql</a></li> <li><a href="/categories/new-features">new-features</a></li> <li><a href="/categories/nginx">nginx</a></li> <li><a href="/categories/nifty-methods">nifty-methods</a></li> <li><a href="/categories/open-source">open-source</a></li> <li><a href="/categories/opinion">opinion</a></li> <li><a href="/categories/rails-5">rails-5</a></li> <li><a href="/categories/shopify">shopify</a></li> <li><a href="/categories/shoutouts">shoutouts</a></li> <li><a href="/categories/tips">tips</a></li> <li><a href="/categories/updates">updates</a></li> <li><a href="/categories/user-experience">user-experience</a></li> </ul> </div> </div> </div> <footer class="site-footer"> <div class="wrapper"> ©2017 Eileen M. Uchitelle </div> </footer> </body> </html>