https://www.justinweiss.com/Justin Weiss2019-05-01T04:40:15ZJustin Weisshttps://www.justinweiss.comtag:www.justinweiss.com,2019-05-01:/articles/how-do-you-catch-back-up/When you've taken a learning break, how do you catch back up?2019-05-01T04:40:15Z2019-05-01T04:40:15Z
<p>When you’ve been deeply focused on a big project or a new job, you might poke your head up and feel lost. Like the tech world has moved beyond you. <strong>Did that time you didn’t spend learning new things finally catch up with you?</strong> And how can you close that gap?</p>
<h2 id="study-at-home-or-learn-at-work">Study at home? Or learn at work?</h2>
<p>If you haven’t been making time for learning, that time has to come from somewhere.</p>
<p>But where will that time come from? Should you study on your own time? Or study on the job?</p>
<p>It’s a trick question. <strong>The answer is both.</strong></p>
<p>Finding time outside of work can be a struggle. It definitely has been for me, as I’ve gone from 0 to 1 to 2 kids. <strong>But learning something in my own time makes that thing feel more like mine.</strong> It feels more exciting, and you can pick up a topic that’s more interesting than practical.</p>
<p>If you feel like the time just isn’t there, plan ahead. Set aside a specific time of day, or make up a trigger. For example, “I’ll read a few pages right after I wake up”, or “I’ll read from 5:30–6 PM.” <strong>Have the book sitting right there, and it can be its own reminder.</strong></p>
<p>I’ve also had some great times reading programming books after the family has gone to sleep. It works, but you have to be careful not to sacrifice much sleep of your own.</p>
<h2 id="what-about-on-the-job">What about on the job?</h2>
<p>When it comes to studying as part of the job, it’s the same thing: <strong>plan time for yourself</strong>. I’ll even block it out on my work calendar.</p>
<p><strong>At most jobs, nobody will specifically give you that time.</strong> Count yourself lucky if they do! (<a href="https://www.aha.io/company/culture">Aha!, my current employer</a>, is one of those rare ones).</p>
<p>For the rest, the first step is to build trust. Can you have a conversation that starts, “I’m going to spend time learning this so I can become more effective at the work we do every day?” If so, you’re on the right track.</p>
<p>You might be limited to learning something directly related to the job. For example, reading up on React if you’re going to be doing more front-end JavaScript work.</p>
<p>But that’s not as limited as it seems.</p>
<p><strong>Work time is a great time to read fundamental books, like <a href="http://martinfowler.com/books/refactoring.html">Refactoring</a>, or <a href="https://www.oreilly.com/library/view/working-effectively-with/0131177052/">Working Effectively with Legacy Code</a>, or <a href="http://dddcommunity.org/book/evans_2003/">Domain Driven Design</a></strong>. Those are all books I’ve read at various jobs, and some of the most valuable of my career.</p>
<p>What if they say no? You’ll have to make a decision. Learning is important enough that I would take the time anyway. There’s usually enough downtime to fit it in somewhere, as long as you have the material on hand. And if you put in the effort and focus on the right things, you’ll become more efficient, and the time will create itself.</p>
<h2 id="one-final-warning">One final warning</h2>
<p>If you feel like you’re trying to catch up, you’ll be tempted to take on too much at once. That’s a mistake.</p>
<p><strong>Learning one new language and one or two major frameworks a year is a good low bar, and probably also a good high bar.</strong> You might be able to stretch a little, but much more than that and you’ll forget it when you need it.</p>
<p>That seems low, but it adds up over time. And even if you’re not totally caught up, you’ll still feel like you’re making real progress toward the developer you want to be.</p>
tag:www.justinweiss.com,2017-08-22:/articles/how-do-you-do-a-rails-deep-dive/How do you do a Rails deep dive?2017-08-22T04:40:15Z2017-08-22T04:40:15Z
<p>Maybe fixing a bug just spawned a dozen new ones. Or your code breaks in such a weird way that you wonder if you really understand it at all. You think <a href="/articles/take-a-rails-deep-dive/">it’s time for a deep dive</a>.</p>
<p>But <em>knowing</em> you need to dive deeply into a topic? That’s only step 1. <strong>How do you actually learn a topic down to its fundamentals?</strong> How do you learn enough that it comes naturally to you?</p>
<h2 id="where-do-you-start">Where do you start?</h2>
<p>There are a lot of places you could start your learning. <strong>But when I need to learn a lot about a topic quickly, books are my favorite place to start.</strong> For example, if you’re doing a deep dive into git, a book called <em>Pro Git</em> is probably exactly what you’re looking for.</p>
<p>Books are great for deep dives because they’re comprehensive: Most medium-sized topics are pretty well covered by a 200–400 page book. At the end, you might not be an expert, but you’ll have a pretty good understanding and solid fundamentals to grow from. That’ll help if you decide to move on to reading source code or specs.</p>
<p>But maybe you don’t want to buy a book. Or a book on your topic doesn’t even exist. When that happens, where else can you look?</p>
<p><strong>Official documentation is a good alternative.</strong> If you’re doing a deep dive into a single part of a framework like Rails, or a web technology like OAuth, official docs are an especially good match.</p>
<p>For projects and frameworks, something named “The X Guide(s)” is your best bet for starting. For example, I often recommend the <a href="http://guides.rubyonrails.org">Rails Guides</a> for new Rails developers, and the <a href="https://elixir-lang.org/getting-started/introduction.html">Elixir Guides</a> are a great place to learn how to write Elixir code.</p>
<p>But while guides are more comprehensive than, say, a blog post, they aren’t totally comprehensive. <strong>Instead, you can use the guide as a jumping-off point to the reference documentation, like RDoc.</strong></p>
<p>Reference material is hard to understand if you don’t have a way to put all those methods and classes into context. It’s just a mess of details with no real structure. So I find that references work best when you pair them with guides or books.</p>
<p>For example, almost nothing will teach you ActiveModel more than digging through the <a href="http://api.rubyonrails.org/classes/ActiveModel/Model.html">ActiveModel API docs</a>. But the <a href="http://guides.rubyonrails.org/active_model_basics.html">ActiveModel guide</a> will help you put it all together.</p>
<p>I say “almost nothing”, because <strong>there is one thing more comprehensive than reading official docs: Reading the source code.</strong> But reading source code isn’t like reading a book: it takes experience, practice, and guidance. So even though it will give you the most detail, it’s not where you should go first.</p>
<p>After deep diving through all this written material, you’ll have some open questions. So, ask them! <strong>The author of a library will usually have a better mental model of it than anyone else, and can walk through their thought process to help you out.</strong> Many authors of open source projects and frameworks make themselves available through Slack or IRC. You can usually find details on project pages.</p>
<p>If you don’t have access to those people? You can still ask. <strong>Ask your colleagues, or more senior devs.</strong> I’m surprised at how often asking a single unanswered question to a friend will make everything else click into place.</p>
<hr>
<p>Once you know you have to do a deep dive, there are a few places you can start. <strong>Here’s the order I’ll usually follow:</strong></p>
<ol>
<li>A book, or an official guide</li>
<li>The official reference documentation (like RDoc) or a spec / <a href="https://en.wikipedia.org/wiki/Request_for_Comments">RFC</a>
</li>
<li>The source code</li>
</ol>
<p>And I’ll fill the gaps by asking questions. It’s not the fastest process, but it’s the best combination of breadth and depth that I’ve found so far.</p>
<p>Do you regularly do deep dives? If so, I’d love to know what resources you’ve found most helpful. Leave a comment and let me know!</p>
tag:www.justinweiss.com,2017-08-15:/articles/take-a-rails-deep-dive/When to take a Rails deep dive2017-08-15T04:40:15Z2017-08-15T04:40:15Z
<p>Have you ever found a Rails topic that didn’t make any sense to you?</p>
<p>Like, you thought you knew it, so you wrote some code, and something completely different happened?</p>
<p>Or you <em>know</em> you don’t understand, but you kind of know enough to get by, except you spend so much time fighting edge cases that you could have been an expert in it by the time you were done?</p>
<p>Well, what if it didn’t have to be that way? Wouldn’t it better to just <em>know</em> how things worked? To have a solid mental model of the problem in front of you? <strong>So you could just make the right decisions, and write the right code?</strong></p>
<hr>
<p>When I was first learning web development, sessions were That Thing: I thought I kind of knew them, but I didn’t. And my misunderstanding of sessions caused so many bugs that I was criticized, a lot, for the problems I created.</p>
<p><strong>Soon, I realized I had to take time to <em>actually</em> understand how sessions worked.</strong> To demystify them, to make them not scary or weird. And eventually, to be able to guess how they’d behave – and to be right.</p>
<p>“Sessions” isn’t the only topic I’ve done a deep dive into. Data modeling, caching, metaprogramming, they’re all confusing things that are really easy to get to <em>kind of</em> work. But you’ll run into eternally hard debugging problems if you don’t understand them.</p>
<p>In <em><a href="https://www.justinweiss.com/practicing-rails/">Practicing Rails</a></em>, I wrote about <em>T-Shaped learning</em>: When you have good baseline knowledge, but push much further into specific topics as you need to. <strong>Those pushes are deep dives, and they’ll help you solve huge problems over the course of your programming career.</strong></p>
<h2 id="when-should-you-do-a-deep-dive">When should you do a deep dive?</h2>
<p>So how do you know when it’s time for a deep dive?</p>
<p>First, to do a deep dive, you have to know what you’re diving into.</p>
<p><strong>Deep dives are most helpful when you’re dealing with a single topic.</strong> A specific thing you can describe in a word or a short phrase. <em>SQL query performance</em>. <em>Sessions</em>. <em>HTTP Caching</em>. Too specific, and you miss the interactions that make a topic so complicated. Too general, and you’re doing a deep dive into “Programming.” Which, I guess you kind of are, but that’s a deep dive you’ll spend your whole career on.</p>
<p>Next, you should do a deep dive in one of two situations:</p>
<ol>
<li>
<p><strong>You <em>think</em> you know what you’re doing, but something totally unexpected happens.</strong> You <em>know in your heart</em> that pushing that green button turns the hallway light on, but you push it, and the room collapses instead.</p>
</li>
<li>
<p><strong>You <em>know</em> you don’t really understand something, and that’s been OK…</strong> But now, you’re fixing a bug, and everything you try causes more problems than you’re solving, creating new bugs as quickly as you’re fixing old ones.</p>
</li>
</ol>
<p>These situations have something in common: You’ve just started to notice that you’re going in the wrong direction. And even though you <em>hope</em> you’ll turn things around, you’re starting to realize you’ll waste a lot of time struggling.</p>
<p>They’re both ways to help you sense, early on, that the way you’re doing things isn’t working.</p>
<p>So, the next time you run around in circles, battling edge cases to fix a bug, or the next time you’re floored by code you wrote doing something completely different than what you expected, remember the feeling you have. Get sensitive to it. That’s the feeling that’ll tell you it’s time to pause. To collect yourself. <strong>And to learn, deeply, that thing you now know you don’t understand.</strong></p>
<p><a href="/articles/how-do-you-do-a-rails-deep-dive/">But now that you’ve decided you need a deep dive, how do you go about doing it?</a></p>
tag:www.justinweiss.com,2017-05-09:/articles/a-decorator-vs-a-subclass/A decorator vs. a subclass2017-05-09T04:40:15Z2017-05-09T04:40:15Z
<p>In my <a href="/articles/the-lesser-known-features-in-rails-5-dot-1/">most recent article</a>, I mentioned a great new feature in Rails 5.1, <code>delegate_missing_to</code>. <strong>With <code>delegate_missing_to</code>, any method that you can’t find on one object is called on another object, instead</strong>:</p>
<figure class="code"><pre class="highlight"><code class="language-ruby"><span class="k">class</span> <span class="nc">Player</span>
<span class="n">delegate_missing_to</span> <span class="ss">:@user</span>
<span class="k">def</span> <span class="nf">initalize</span><span class="p">(</span><span class="n">user</span><span class="p">)</span>
<span class="vi">@user</span> <span class="o">=</span> <span class="n">user</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">points</span>
<span class="no">Game</span><span class="p">.</span><span class="nf">points_for_user</span><span class="p">(</span><span class="n">user</span><span class="p">.</span><span class="nf">id</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="no">Player</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">user</span><span class="p">).</span><span class="nf">name</span> <span class="c1"># calls user.name</span></code>
</pre></figure>
<p>But, like <a href="/articles/the-lesser-known-features-in-rails-5-dot-1/#comment-3285972786">Gavin mentioned in the comments</a>, this seems like an odd way to avoid inheritance. Why not just use a subclass? You’d get the same effect, and you don’t have to add a whole new feature. It seems like a weird thing to add.</p>
<p>There must be a reason <code>delegate_missing_to</code> was added, though. And for Rails features, pull requests are a great way to find those reasons. <strong>In <a href="https://github.com/rails/rails/issues/23824">this pull request</a>, DHH mentioned why he suggested the feature:</strong></p>
<blockquote>
<p>Here’s a common pattern if you want to build a decorator:</p>
</blockquote>
<p>That seems like a pretty good place to start digging.</p>
<h2 id="why-decorators">Why decorators?</h2>
<p><strong>When you build a <a href="http://wiki.c2.com/?DecoratorPattern">decorator</a>, you’re changing the way an object acts, without creating a new subclass.</strong> For example, in the code from earlier:</p>
<figure class="code"><pre class="highlight"><code class="language-ruby"><span class="k">class</span> <span class="nc">Player</span>
<span class="n">delegate_missing_to</span> <span class="ss">:@user</span>
<span class="k">def</span> <span class="nf">initalize</span><span class="p">(</span><span class="n">user</span><span class="p">)</span>
<span class="vi">@user</span> <span class="o">=</span> <span class="n">user</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">points</span>
<span class="no">Game</span><span class="p">.</span><span class="nf">points_for_user</span><span class="p">(</span><span class="n">user</span><span class="p">.</span><span class="nf">id</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span></code>
</pre></figure>
<p>You’d say that “Player <em>decorates</em> user,” because a Player <em>almost</em> acts like a User, but has an extra method, <code>points</code>. And it does this without inheritance.</p>
<p>Why would you need something like this? That’s a tough question to answer, because like many design patterns, it’s not always clear where you’d want to use it instead of something else.</p>
<h2 id="when-would-you-use-a-decorator">When would you use a decorator?</h2>
<p>Decorators could just be a more complicated way to do inheritance. I mean, which of these two lines of code is better?</p>
<figure class="code"><pre class="highlight"><code class="language-ruby"><span class="n">player</span> <span class="o">=</span> <span class="no">Player</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="no">User</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="ss">name: </span><span class="s2">"Justin"</span><span class="p">))</span> <span class="c1"># Player decorates User</span>
<span class="n">player</span> <span class="o">=</span> <span class="no">Player</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="ss">name: </span><span class="s2">"Justin"</span><span class="p">)</span> <span class="c1"># Player subclasses User</span></code>
</pre></figure>
<p>Clearly the second one, right? Here, creating Player as a decorator instead of a subclass is just a waste of code.</p>
<p><strong>But sometimes, you want to add functionality to an object later on, far away from where you created the object.</strong> For example, what if you had code like this?</p>
<figure class="code"><pre class="highlight"><code class="language-ruby"><span class="n">user</span> <span class="o">=</span> <span class="no">User</span><span class="p">.</span><span class="nf">find</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="o">...</span> <span class="n">some</span> <span class="n">time</span> <span class="n">later</span> <span class="o">...</span>
<span class="n">player</span> <span class="o">=</span> <span class="no">Player</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">user</span><span class="p">)</span></code>
</pre></figure>
<p>Now, you can create the user however you want, in whatever method you want. The code that creates the User object doesn’t know or care that a Player class even exists. And you can still use the original User object if you don’t want those extra methods anymore.</p>
<p><strong>This helps you separate behavior into different classes.</strong> Each class can focus on how the User object would be used in a specific situation – a Player, an Employee, a Developer. With inheritance, it’s easy for all this stuff to get jumbled together.</p>
<p><a href="http://www.justinweiss.com/articles/the-lesser-known-features-in-rails-5-dot-1/#comment-3286300468">MrChris mentioned another benefit to decorators in the comments</a>:</p>
<p>When you decorate an object, you can only call the public methods on that object. When you subclass, you can call any method, even private ones. <strong>That can make subclasses break more frequently, because they can accidentally rely on their parents’ implementation details.</strong> Those details will usually change more often than the public methods.</p>
<p>Decorators can be especially useful when you’re breaking apart large classes. With decorators, it’s easier to follow the <a href="http://wiki.c2.com/?SingleResponsibilityPrinciple">Single-Responsibility Principle</a> – <strong>each decorator can do one thing and do it well, and you can combine decorators to get more complex behavior.</strong></p>
<hr>
<p>There are a lot of ways to share behavior in Ruby. You can subclass, you can combine modules, you can even <a href="http://www.justinweiss.com/articles/fun-with-the-method-method/">grab methods off one class and attach them to another if you want to</a>. The decorator pattern, though, gives you something a little different. <strong>You’re just using instance variables and method calls, the building blocks of any object-oriented language.</strong> From those fundamentals, you can have flexible behavior while your app is running – all without overcomplicating your code.</p>
tag:www.justinweiss.com,2017-05-02:/articles/the-lesser-known-features-in-rails-5-dot-1/The lesser-known features in Rails 5.12017-05-02T05:49:00Z2017-05-02T05:49:00Z<p>Last week, during RailsConf 2017, <a href="http://weblog.rubyonrails.org/2017/4/27/Rails-5-1-final/">Rails 5.1 shipped</a>.</p>
<p>If you followed the announcements, you’ve seen the big features: better integration with modern JavaScript, encrypted secrets, and system tests. And there’s my personal favorite: <em>finally</em> getting rid of the weird combo of <code>form_for</code> and <code>form_tag</code>, and <a href="https://github.com/rails/rails/issues/25197">replacing it with <code>form_with</code></a>. I can’t wait to try it.</p>
<p><strong>But the reason I love Rails isn’t the big new features. It’s the little, constant improvements.</strong> It’s those quality-of-life changes that make me happier when I’m writing Rails apps. And Rails 5.1 is full of them.</p>
<h2 id="more-consistent-tag-helpers">More consistent tag helpers</h2>
<p>Have you used Rails’ tag helpers, like <code>tag</code> and <code>content_tag</code>?</p>
<figure class="code"><pre class="highlight"><code class="language-erb"><span class="cp"><%=</span> <span class="n">content_tag</span> <span class="ss">:p</span><span class="p">,</span> <span class="vi">@user</span><span class="p">.</span><span class="nf">name</span><span class="p">,</span> <span class="ss">class: </span><span class="s2">"name"</span> <span class="cp">%></span></code>
</pre></figure>
<p><a href="https://github.com/rails/rails/pull/25289">Rails 5.1 adds a new tag helper syntax</a>.</p>
<p><strong>Use calls like <code>tag.div</code> or <code>tag.br</code>, and you can stop worrying about parameter order and juggling two different methods:</strong></p>
<figure class="code"><pre class="highlight"><code class="language-erb"><span class="cp"><%=</span> <span class="n">tag</span><span class="p">.</span><span class="nf">p</span> <span class="vi">@user</span><span class="p">.</span><span class="nf">name</span><span class="p">,</span> <span class="ss">class: </span><span class="s2">"name"</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">tag</span><span class="p">.</span><span class="nf">br</span> <span class="cp">%></span></code>
</pre></figure>
<p>These new tag helpers support HTML5 by default, and even let you create your own elements:</p>
<figure class="code"><pre class="highlight"><code class="language-erb"><span class="cp"><%=</span> <span class="n">tag</span><span class="p">.</span><span class="nf">pea</span> <span class="vi">@user</span><span class="p">.</span><span class="nf">name</span><span class="p">,</span> <span class="ss">class: </span><span class="s2">"name"</span> <span class="cp">%></span>
<span class="c"><!-- turns into <pea class="name">Justin Weiss</pea> --></span></code>
</pre></figure>
<h2 id="assert-more-than-just-differences">Assert more than just differences</h2>
<p>I love <code>assert_difference</code>. <strong>Before <code>assert_difference</code>, I spent way too much time juggling local variables in tests:</strong></p>
<figure class="code"><pre class="highlight"><code class="language-ruby"><span class="n">old_score</span> <span class="o">=</span> <span class="vi">@user</span><span class="p">.</span><span class="nf">score</span>
<span class="vi">@user</span><span class="p">.</span><span class="nf">answer_question!</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
<span class="n">assert_equal</span> <span class="n">old_score</span> <span class="o">+</span> <span class="mi">10</span><span class="p">,</span> <span class="vi">@user</span><span class="p">.</span><span class="nf">score</span></code>
</pre></figure>
<p>With <code>assert_difference</code>, it’s much clearer what you’re trying to do:</p>
<figure class="code"><pre class="highlight"><code class="language-ruby"><span class="n">assert_difference</span> <span class="s2">"@user.score"</span><span class="p">,</span> <span class="mi">10</span> <span class="k">do</span>
<span class="vi">@user</span><span class="p">.</span><span class="nf">answer_question!</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
<span class="k">end</span></code>
</pre></figure>
<p><a href="https://github.com/rails/rails/pull/25393">In Rails 5.1, <code>assert_changes</code> takes this one step further</a>.</p>
<p><code>assert_difference</code> only checks changes in count. <strong>But <code>assert_changes</code> can check non-numerical changes, like changes between two strings, or between nil and something else:</strong></p>
<figure class="code"><pre class="highlight"><code class="language-ruby"><span class="n">assert_changes</span> <span class="s2">"users(:justin).name"</span><span class="p">,</span> <span class="ss">from: </span><span class="s2">"Justin"</span><span class="p">,</span> <span class="ss">to: </span><span class="s2">"Bob"</span> <span class="k">do</span>
<span class="vi">@user</span><span class="p">.</span><span class="nf">update_attributes</span><span class="p">(</span><span class="ss">name: </span><span class="s2">"Bob"</span><span class="p">)</span>
<span class="k">end</span></code>
</pre></figure>
<p>Instead of a string, you can give it a lambda:</p>
<figure class="code"><pre class="highlight"><code class="language-ruby"><span class="n">assert_changes</span> <span class="o">-></span> <span class="p">{</span> <span class="n">users</span><span class="p">(</span><span class="ss">:justin</span><span class="p">).</span><span class="nf">name</span> <span class="p">},</span> <span class="ss">from: </span><span class="s2">"Justin"</span><span class="p">,</span> <span class="ss">to: </span><span class="s2">"Bob"</span> <span class="k">do</span>
<span class="vi">@user</span><span class="p">.</span><span class="nf">update_attributes</span><span class="p">(</span><span class="ss">name: </span><span class="s2">"Bob"</span><span class="p">)</span>
<span class="k">end</span></code>
</pre></figure>
<p><code>to:</code> can be anything that compares with ===. <strong>That’s nice when you know <em>something</em> about the value, but don’t know what it is, specifically:</strong></p>
<figure class="code"><pre class="highlight"><code class="language-ruby"><span class="n">assert_changes</span> <span class="o">-></span> <span class="p">{</span> <span class="n">users</span><span class="p">(</span><span class="ss">:justin</span><span class="p">).</span><span class="nf">updated_at</span> <span class="p">},</span> <span class="ss">to: </span><span class="no">ActiveSupport</span><span class="o">::</span><span class="no">TimeWithZone</span> <span class="k">do</span>
<span class="vi">@user</span><span class="p">.</span><span class="nf">update_attributes</span><span class="p">(</span><span class="ss">name: </span><span class="s2">"Bob"</span><span class="p">)</span>
<span class="k">end</span></code>
</pre></figure>
<h2 id="delegate-everything">Delegate everything</h2>
<p>In some Rails code, you’ll see the <code>delegate</code> method used. <strong>Delegation is helpful when you want to add behavior on top of another class, without inheriting from it:</strong></p>
<figure class="code"><pre class="highlight"><code class="language-ruby"><span class="k">class</span> <span class="nc">Player</span>
<span class="n">delegate</span> <span class="ss">:id</span><span class="p">,</span> <span class="ss">:name</span><span class="p">,</span> <span class="ss">to: :@user</span>
<span class="k">def</span> <span class="nf">initalize</span><span class="p">(</span><span class="n">user</span><span class="p">)</span>
<span class="vi">@user</span> <span class="o">=</span> <span class="n">user</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">points</span>
<span class="no">Game</span><span class="p">.</span><span class="nf">points_for_user</span><span class="p">(</span><span class="n">user</span><span class="p">.</span><span class="nf">id</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span></code>
</pre></figure>
<p>But sometimes you want to forward <em>everything</em> to the class you’re wrapping.</p>
<p>There are a few ways to do this with Ruby, using <code>method_missing</code> or <code>SimpleDelegator</code>. <strong>But to better match the <code>delegate</code> method, <a href="https://github.com/rails/rails/issues/23824"><code>delegate_missing_to</code> was added to Rails 5.1</a>.</strong> It does exactly what it says:</p>
<figure class="code"><pre class="highlight"><code class="language-ruby"><span class="k">class</span> <span class="nc">Player</span>
<span class="n">delegate_missing_to</span> <span class="ss">:@user</span>
<span class="k">def</span> <span class="nf">initalize</span><span class="p">(</span><span class="n">user</span><span class="p">)</span>
<span class="vi">@user</span> <span class="o">=</span> <span class="n">user</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">points</span>
<span class="no">Game</span><span class="p">.</span><span class="nf">points_for_user</span><span class="p">(</span><span class="n">user</span><span class="p">.</span><span class="nf">id</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span></code>
</pre></figure>
<p>Now, any call to a method that’s not in the Player class will search on <code>@user</code> instead.</p>
<h2 id="bonus-aliasmethodchain-is-gone">Bonus: <code>alias_method_chain</code> is gone!</h2>
<p>One of my favorite features in Ruby 2 is <a href="https://bugs.ruby-lang.org/issues/1102">Module#prepend</a>. I liked it so much, <a href="http://www.justinweiss.com/articles/rails-5-module-number-prepend-and-the-end-of-alias-method-chain/#comment-3078737465">I wrote a post about it</a>. Specifically, about how I hoped Module#prepend would eventually replace <code>alias_method_chain</code>.</p>
<p><strong>And as of Rails 5.1, <a href="https://github.com/rails/rails/pull/27035/commits/7c848e6dd493ff236d33a0410a92f4c3e5cc3c7f"><code>alias_method_chain</code> is now officially gone</a> – replaced with prepend.</strong></p>
<hr>
<p>New versions of Rails are always exciting. <strong>But it’s the details that give Rails its beauty.</strong> The small changes that make you happier with the code you write every day.</p>
<p>How do you find those changes? Dive into the changelogs. Take a look at interesting pull requests. See which of the new, small, 5.1 features will make your life that little bit easier.</p>
<p><strong>And when you find some cool stuff, don’t keep it to yourself. Share it here, so we can all learn something new!</strong></p>
tag:www.justinweiss.com,2017-03-01:/articles/write-that-first-complicated-test/Write that first complicated test2017-03-01T05:05:56Z2017-03-01T05:05:56Z
<p>What code of yours isn’t tested? Is it code that deals with complicated situations that you don’t control? Threads, running commands, git, networking, or UI?</p>
<p>Our apps are most interesting when they’re complicated. They’re also most dangerous. <strong>And that’s why code that’s hard to test is exactly the kind of code that needs to be tested well.</strong> That doesn’t always happen.</p>
<p>Instead, every time you touch that code, you touch lightly. You tread carefully. Maybe you do some manual testing. And when you send the pull request, you hope your teammates don’t realize those tests don’t exist.</p>
<p><strong>But that won’t make things better.</strong> You’ll run into the same problems, the same bugs, the same stress next time – and every time after that. How can you finally make those challenging tests something you can rely on?</p>
<h2 id="shift-your-mindset">Shift your mindset</h2>
<p>The most frustrating thing about these tests? <strong>It’s going to take ten times as long to write it as it feels like it should.</strong> If you estimate the time the test saves you against the time you spend writing the test, it just doesn’t seem worth it.</p>
<p>But it’s not just about this test. It’s about <em>all your future tests</em>.</p>
<p><strong>Most of the best-tested code I’ve seen has a lot of support.</strong> It’s not just the code in <code>test/models</code>. Extremely well-tested code has <a href="http://www.justinweiss.com/articles/testing-network-services-in-ruby/">fakes</a>, it has mocks, it has a good set of test fixtures, it has configuration options specifically for the tests.</p>
<p>All that takes time to write and put together.</p>
<p>But once you have it, it feels <em>so good.</em> You can come up with test after test, feeling comfortable about your code, and confident in quickly you can move after the investment you’ve made.</p>
<p>You can <em>rely</em> on the work you’ve already done.</p>
<p>So it’s not just about preventing bugs in complicated code. <strong>It’s also about making future code easier to test, piece by piece.</strong></p>
<h2 id="make-it-an-integration-test-for-now">Make it an integration test (for now)</h2>
<p>Sometimes, though, it’s not about understanding the value – I get it. <strong>Instead, I just get stuck because I can’t figure out how to write a small, fast, unit test.</strong></p>
<p>How do you know you’re running the right git commands in your deployment tool, without actually running <code>git</code>? How do you make sure you’re sending a remote server the right headers?</p>
<p>With enough time, you can build a quality fake for your tests to rely on.</p>
<p>But when that seems like too much to think about, there’s something else you can try. <strong>Break testing apart into two separate steps: “test the code” and “write the mock.”</strong></p>
<p>Just call that server. Just run that command. Why?</p>
<ul>
<li>
<strong>It’s much easier to get started.</strong> You’re probably testing those commands manually, right? Running it in a console, or trying it in a browser? Just copy it into a test.</li>
<li>
<strong>When you eventually write your mock or fake, you can use these tests to make sure your mock works.</strong> If you see the same behavior in the real world as you see from your fake, your fake is probably good!</li>
</ul>
<p>You probably don’t want to keep these tests around forever, though:</p>
<ul>
<li>
<strong>They have all the problems integration tests have.</strong> They can be slow. They might need a live internet connection. They might be brittle, because they’re depending on behavior that your app doesn’t actually care about.</li>
<li>
<strong>You might not be able to test some things in the real world.</strong> For example, how do you force specific error codes when you don’t control the server on the other end?</li>
<li>
<strong>You might get blocked by a server you depend on, and that can break your tests (and your app!).</strong> This actually happened to me, and it was a big problem.</li>
</ul>
<p>So, writing your test as a real-world integration test isn’t a permanent solution, or even a long-term one. But even with all those drawbacks, it’s still helpful. And after you replace it, you can still keep the integration test around, in a separate suite. That way, you can always check my code against reality, not just your assumptions.</p>
<hr>
<p>Some code is just hard to test. It takes a while to build up the infrastructure you need to write reliable tests quickly. And a lot of the time, it doesn’t seem worth it.</p>
<p><strong>But when you stop thinking about that single test, and think about the value of making all your future tests easier, testing complicated code becomes a lot more motivating.</strong> And once the first test goes down, the rest of them seem to magically become so much easier to write.</p>
<p>Sometimes, though, that’s not enough. What if you know how to make sure your code works in the real world, but just can’t figure out how to test it?</p>
<p>When that happens, stop looking at the test as something you need to keep pure and isolated. <strong>Instead, see it as a way to automatically do what you’re already doing manually.</strong></p>
<p>It’s not perfect, and you should replace it as soon as you can. But those tests can give you the confidence you need to write and change complicated code quickly.</p>
tag:www.justinweiss.com,2017-02-14:/articles/writing-a-one-time-script-in-rails/Writing a one-time script in Rails2017-02-14T06:08:51Z2017-02-14T06:08:51Z<p>Have you ever wanted to import a bunch of data into your app from a CSV file? Or maybe you need to fix <a href="/articles/how-to-get-from-theyre-to-theyre/">badly encoded characters</a> in some of your customer reviews. Or you changed your mind about how you wanted to store data in Redis, and had to move everything from the old format to the new one.</p>
<p>At <a href="https://www.avvo.com">Avvo</a>, we called these “ad-hoc tasks.” As in, you probably only need to run them once. <strong>So what’s the best way to handle an ad-hoc task in Rails?</strong></p>
<h2 id="write-a-database-migration">Write a database migration</h2>
<p>A migration works well if you need to change the structure of the data in your database. It tracks whether the task was run, it carries over changes to other environments – it’s what migrations were <em>built</em> for. It’s also what you’re probably already using them for.</p>
<p><strong>If you’re changing data at the same time, a migration <em>might</em> work well. But there are some things to watch out for.</strong></p>
<p>Calling something like <code>Permissions.create(...)</code> in your migration can cause you trouble. If the model has changed, your migration <a href="http://railsguides.net/change-data-in-migrations-like-a-boss/">might break</a>, because your model might not be available when the migration runs. Or your model might have changed between the time you wrote the migration and when it ran. There are ways to get around this, but they’re error-prone and can fail in weird ways.</p>
<p>Migrations are also less useful if your task doesn’t involve ActiveRecord.</p>
<p>These aren’t deal-breakers. <strong>But I tend not to import or change much data in migrations. There are better options.</strong></p>
<h2 id="write-a-rake-task">Write a rake task</h2>
<p>You have a task. You probably only want to run it once. And you want to be able to test it on your machine and run it in production.</p>
<p><strong>Rake tasks work really well for this.</strong> Rails can even generate rake tasks for you:</p>
<figure class="code"><pre class="highlight"><code class="language-ruby"><span class="err">$</span> <span class="n">be</span> <span class="n">rails</span> <span class="n">g</span> <span class="n">task</span> <span class="n">locations</span> <span class="n">import</span>
<span class="n">create</span> <span class="n">lib</span><span class="o">/</span><span class="n">tasks</span><span class="o">/</span><span class="n">locations</span><span class="p">.</span><span class="nf">rake</span></code>
</pre></figure>
<p>This creates a file for you to stash your code into:</p>
<figure class="code"><figcaption><span>lib/tasks/locations.rake</span></figcaption><pre class="highlight"><code class="language-ruby"><span class="n">namespace</span> <span class="ss">:locations</span> <span class="k">do</span>
<span class="n">desc</span> <span class="s2">"TODO"</span>
<span class="n">task</span> <span class="ss">import: :environment</span> <span class="k">do</span>
<span class="k">end</span>
<span class="k">end</span></code>
</pre></figure>
<p>Inside that <code>task</code> block, you can use all your models and the rest of the code in your Rails app. <strong>It’s easy to import and change data, because you can write your code just like you were sitting at a Rails console.</strong></p>
<p>Once you’ve written your task, you can run it with <code>rake locations:import</code>. If you’re using Heroku, you can run it with <code>heroku run rake locations:import</code>. If you’re using Capistrano, you can use the <a href="https://github.com/sheharyarn/capistrano-rake">capistrano-rake</a> gem to run your task. You might have an even better option, though.</p>
<h2 id="write-a-scheduled-job-using-sidekiq-schedulerhttpsgithubcommoove-itsidekiq-scheduler">Write a scheduled job, using <a href="https://github.com/Moove-it/sidekiq-scheduler">sidekiq-scheduler</a>
</h2>
<p>If your app is big enough, you’re <em>probably</em> already using <a href="http://sidekiq.org">Sidekiq</a>, <a href="https://github.com/resque/resque">Resque</a>, or something like that.</p>
<p>Most of these background job processors can schedule jobs to run later. In Sidekiq, for example, there’s the <a href="https://github.com/Moove-it/sidekiq-scheduler">sidekiq-scheduler gem</a>. And with sidekiq-scheduler, there’s a trick you can do.</p>
<p><strong>What if you had a job that never <em>automatically</em> scheduled itself, but let you <em>manually</em> schedule it whenever you wanted?</strong> That would work great for “one-off” jobs that you might want to run again later, or that you’d rather run using a UI.</p>
<p><strong>In sidekiq-scheduler, you can schedule the job far in the future, and set the job to disabled:</strong></p>
<figure class="code"><figcaption><span>sidekiq.yml</span></figcaption><pre class="highlight"><code class="language-ruby"><span class="ss">:schedule</span><span class="p">:</span>
<span class="ss">location_importer:
class: </span><span class="no">LocationImporterWorker</span>
<span class="ss">at: </span><span class="s1">'3001/01/01'</span>
<span class="ss">enabled: </span><span class="kp">false</span></code>
</pre></figure>
<p>Then, when you visit sidekiq-web, you’ll see a button to manually enqueue the job:</p>
<p><img src="/images/posts/schedule-adhoc-task.png" width="819" height="144"></p>
<p>With this, you can run your job whenever you’re ready, in both development and production. And if you ever need to run it again, it’s right there in the UI.</p>
<p>This isn’t the best option if your job is dangerous. It’s too easy to accidentally click that button. And it’s also not great if the job takes a while to complete, because Sidekiq works best if jobs finish quickly. Your job will take over a worker, and you won’t be able to safely restart Sidekiq until your job finishes. <strong>But if your job is fast, and can run safely more than once, this works well.</strong> If it’s a cleanup kind of task, you might decide you <em>want</em> to run it regularly.</p>
<p>If you only want to focus on scheduling and triggering, or need more flexibility to set params in your one-time scripts, a reader, Dmitry, pointed me at <a href="https://github.com/richfisher/sidekiq-enqueuer">sidekiq-enqueuer</a>. <strong>With sidekiq-enqueuer, you can schedule jobs and set params, all through the Sidekiq web interface.</strong></p>
<h2 id="ssh-into-production-and-paste-code-into-the-rails-console">SSH into production and paste code into the Rails console</h2>
<p>Just kidding.</p>
<h2 id="which-should-you-choose">Which should you choose?</h2>
<p>I’ve used all of these ways to run one-off tasks. <strong>But I’ll usually go for a rake task first.</strong> It works, it’s hard to run accidentally, and it’s easy to get rid of when you’re done with it. I don’t choose rake tasks every time, though.</p>
<p><strong>I might choose a migration if:</strong></p>
<ul>
<li>The job fixes up data using SQL as part of a database schema change.</li>
<li>The job is very simple data work, like changing data in a column or adding a few records.</li>
<li>I want to easily track whether the job has been run, and not run it again.</li>
</ul>
<p><strong>I might choose a Sidekiq job if:</strong></p>
<ul>
<li>I think I might want to run the job again later.</li>
<li>Someone who’s not me has to run it. All they’ll have to do is click a button.</li>
<li>It’s a short data import or data cleanup job. I’ll probably have to run those regularly, even if I don’t expect to at first.</li>
</ul>
<p>How about you? Do you have any other options, or make different choices? <strong>Leave a comment and let me know!</strong></p>
tag:www.justinweiss.com,2015-09-22:/articles/how-to-get-from-theyre-to-theyre/How to get from they’re to they’re2015-09-22T06:35:48Z2015-09-22T06:35:48Z
<p><a href="/blog/2015/09/15/3-steps-to-fix-encoding-problems-in-ruby/">In last week’s article</a>, you learned a short process that solves most encoding problems. <strong>But there’s one encoding problem that’s much harder to solve.</strong></p>
<p>I know you’ve seen it. (Or maybe you’ve seen it?) It’s when a curly quote turns into ’, or an em-dash turns into —. It’ll make you think you’ve gone crazy. It should just work!</p>
<p>You could create a giant table, so you could find bad characters and replace them with good ones:</p>
<figure class="code"><pre class="highlight"><code class="language-ruby"><span class="p">[{</span><span class="ss">broken: </span><span class="s1">'–'</span><span class="p">,</span> <span class="ss">fixed: </span><span class="s2">"—"</span><span class="p">}</span>
<span class="p">{</span><span class="ss">broken: </span><span class="s2">"—"</span><span class="p">,</span> <span class="ss">fixed: </span><span class="s2">"–"</span><span class="p">}</span>
<span class="p">{</span><span class="ss">broken: </span><span class="s2">"‘"</span><span class="p">,</span> <span class="ss">fixed: </span><span class="s2">"‘"</span><span class="p">}</span>
<span class="p">{</span><span class="ss">broken: </span><span class="s2">"’"</span><span class="p">,</span> <span class="ss">fixed: </span><span class="s2">"’"</span><span class="p">}</span>
<span class="p">{</span><span class="ss">broken: </span><span class="s2">"“"</span><span class="p">,</span> <span class="ss">fixed: </span><span class="s2">"“"</span><span class="p">}</span>
<span class="p">{</span><span class="ss">broken: </span><span class="s2">"â€"</span><span class="p">,</span> <span class="ss">fixed: </span><span class="s2">"”"</span><span class="p">},</span> <span class="o">...</span><span class="p">]</span></code>
</pre></figure>
<p><strong>But there’s an easier, more reliable way to fix those broken characters.</strong></p>
<h2 id="why-does-good-typography-always-break">Why does good typography always break?</h2>
<p><strong><a href="http://www.justinweiss.com/blog/2015/09/15/3-steps-to-fix-encoding-problems-in-ruby/">Last week</a>, you learned that an encoding is just a way to turn groups of meaningless bytes into displayable characters.</strong> Not every character can be represented in a single byte, because there are more than 256 possible characters. So some characters, like the curly quote <code>’</code>, are represented with more than one byte:</p>
<figure class="code"><pre class="highlight"><code class="language-irb"><span class="gp">irb(main):001:0></span><span class="w"> </span><span class="s2">"they’re"</span><span class="p">.</span><span class="nf">bytes</span>
<span class="p">=></span> <span class="p">[</span><span class="mi">116</span><span class="p">,</span> <span class="mi">104</span><span class="p">,</span> <span class="mi">101</span><span class="p">,</span> <span class="mi">121</span><span class="p">,</span> <span class="mi">226</span><span class="p">,</span> <span class="mi">128</span><span class="p">,</span> <span class="mi">153</span><span class="p">,</span> <span class="mi">114</span><span class="p">,</span> <span class="mi">101</span><span class="p">]</span></code>
</pre></figure>
<p><strong>Even though the string only has 7 characters, they’re represented by 9 bytes!</strong></p>
<p>When you focus on just the curly quote:</p>
<figure class="code"><pre class="highlight"><code class="language-irb"><span class="gp">irb(main):002:0></span><span class="w"> </span><span class="s2">"’"</span><span class="p">.</span><span class="nf">bytes</span>
<span class="p">=></span> <span class="p">[</span><span class="mi">226</span><span class="p">,</span> <span class="mi">128</span><span class="p">,</span> <span class="mi">153</span><span class="p">]</span></code>
</pre></figure>
<p>You’ll see it uses 3 bytes. And our messed up string, they’re, has three characters where it should just have one. That seems like more than a coincidence, right?</p>
<p><strong>It seems like those three bytes should be read as UTF-8, where they’d represent a curly quote. Instead, <em>each byte</em> is showing up as a different character.</strong> So, which encoding would represent <code>[226, 128, 153]</code> as <code>’</code>? If you look at a few tables of popular encodings, you’ll see it’s <a href="https://en.wikipedia.org/wiki/Windows-1252">Windows-1252</a>.</p>
<p>You can check this in <code>irb</code>:</p>
<figure class="code"><pre class="highlight"><code class="language-irb"><span class="gp">irb(main):003:0></span><span class="w"> </span><span class="s2">"they’re"</span><span class="p">.</span><span class="nf">force_encoding</span><span class="p">(</span><span class="s2">"Windows-1252"</span><span class="p">).</span><span class="nf">encode</span><span class="p">(</span><span class="s2">"UTF-8"</span><span class="p">)</span>
<span class="p">=></span> <span class="s2">"they’re"</span></code>
</pre></figure>
<p><em>(We need that last <code>.encode("UTF-8")</code> to display the string in the console.)</em></p>
<p><strong>Yep! That’s the problem.</strong> But it gets worse.</p>
<p>The data is supposed to be UTF-8, but is being misread as Windows-1252. But you’ll probably save that data to a database, or a file, as UTF-8. <strong>Ruby will helpfully convert it to UTF-8 for you, so you’ll end up with:</strong></p>
<figure class="code"><pre class="highlight"><code class="language-irb"><span class="gp">irb(main):004:0></span><span class="w"> </span><span class="s2">"they’re"</span><span class="p">.</span><span class="nf">force_encoding</span><span class="p">(</span><span class="s2">"Windows-1252"</span><span class="p">).</span><span class="nf">encode</span><span class="p">(</span><span class="s2">"UTF-8"</span><span class="p">)</span>
<span class="p">=></span> <span class="s2">"they’re"</span>
<span class="gp">irb(main):005:0></span><span class="w"> </span><span class="s2">"they’re"</span><span class="p">.</span><span class="nf">force_encoding</span><span class="p">(</span><span class="s2">"Windows-1252"</span><span class="p">).</span><span class="nf">encode</span><span class="p">(</span><span class="s2">"UTF-8"</span><span class="p">).</span><span class="nf">bytes</span>
<span class="p">=></span> <span class="p">[</span><span class="mi">116</span><span class="p">,</span> <span class="mi">104</span><span class="p">,</span> <span class="mi">101</span><span class="p">,</span> <span class="mi">121</span><span class="p">,</span> <span class="mi">195</span><span class="p">,</span> <span class="mi">162</span><span class="p">,</span> <span class="mi">226</span><span class="p">,</span> <span class="mi">130</span><span class="p">,</span> <span class="mi">172</span><span class="p">,</span> <span class="mi">226</span><span class="p">,</span> <span class="mi">132</span><span class="p">,</span> <span class="mi">162</span><span class="p">,</span> <span class="mi">114</span><span class="p">,</span> <span class="mi">101</span><span class="p">]</span></code>
</pre></figure>
<p>Your string has been badly-encoded <em>twice</em>. Those broken characters now look like they’re supposed to be there. And if you didn’t know how it happened, it’d be almost impossible to untangle it.</p>
<h2 id="how-do-you-fix-it">How do you fix it?</h2>
<p>How do you get things back to normal? Let’s think about the problem backwards:</p>
<ul>
<li>
<p>You have a UTF-8 string, (they’re)</p>
</li>
<li>
<p>converted from a Windows-1252 string, (they’re)</p>
</li>
<li>
<p>whose bytes <em>should have been</em> read as UTF-8 (they’re)</p>
</li>
</ul>
<p><strong>To fix it, you just have to follow those backwards steps.</strong> Use <code>encode</code> to convert the UTF-8 string back into a Windows-1252 string. Then, use <code>force_encoding</code> to force that mis-encoded Windows-1252 string to be read as UTF-8:</p>
<figure class="code"><pre class="highlight"><code class="language-irb"><span class="gp">irb(main):006:0></span><span class="w"> </span><span class="s2">"they’re"</span><span class="p">.</span><span class="nf">encode</span><span class="p">(</span><span class="s2">"Windows-1252"</span><span class="p">).</span><span class="nf">force_encoding</span><span class="p">(</span><span class="s2">"UTF-8"</span><span class="p">)</span>
<span class="p">=></span> <span class="s2">"they’re"</span></code>
</pre></figure>
<p>Fixed!</p>
<h2 id="theres-one-small-problem">There’s one small problem…</h2>
<p>Unfortunately, you probably found this problem because a bunch of files or database records had badly encoded data in it. And not every file or record is necessarily badly encoded – you might have a mix of good and bad data. <em>Especially</em> if that data came from the people visiting your site.</p>
<p><strong>If that’s the case, you can’t blindly run that code on every string:</strong></p>
<figure class="code"><pre class="highlight"><code class="language-irb"><span class="gp">irb(main):007:0></span><span class="w"> </span><span class="s2">"they’re"</span><span class="p">.</span><span class="nf">encode</span><span class="p">(</span><span class="s2">"Windows-1252"</span><span class="p">).</span><span class="nf">force_encoding</span><span class="p">(</span><span class="s2">"UTF-8"</span><span class="p">)</span>
<span class="p">=></span> <span class="s2">"they’re"</span>
<span class="gp">irb(main):008:0></span><span class="w"> </span><span class="s2">"they’re"</span><span class="p">.</span><span class="nf">encode</span><span class="p">(</span><span class="s2">"Windows-1252"</span><span class="p">).</span><span class="nf">force_encoding</span><span class="p">(</span><span class="s2">"UTF-8"</span><span class="p">)</span>
<span class="p">=></span> <span class="s2">"they</span><span class="se">\x92</span><span class="s2">re"</span></code>
</pre></figure>
<p>If you run it on good data, you’ll just turn it into bad data. So what can you do?</p>
<p><strong>You can use a heuristic: only change strings that have one of the bad characters in them, like <code>â</code>.</strong> This works well if a character like <code>â</code> won’t ever appear in a valid string.</p>
<p>The last time I fixed this kind of bug, though, I wanted to play it safe. I used another useful tool to help: my eyes.</p>
<p><strong>Whenever I found a badly encoded string, I printed it out, along with its replacement:</strong></p>
<figure class="code"><pre class="highlight"><code class="language-text">Changing title with ID 6 from "They’re over there!" to "They’re over there!"</code>
</pre></figure>
<p>That way, I could spot-check the small number of strings that changed, and make sure they didn’t break any further.</p>
<h2 id="i-think-i-have-a-headache">I think I have a headache</h2>
<p>Like I said last week, keeping different interpretations of the same data straight in your head is hard! But if you’re confused, exploring in an <code>irb</code> console will help. So try it out! Open one up, and see if you can go back and forth between <code>—</code> and <code>—</code>, or <code>“</code> and <code>“</code>.</p>
<p><strong>Practicing complicated ideas like these is the fastest way to feel confident when you need them.</strong> And in the <a href="/practicing-rails">free sample chapter of <em>Practicing Rails</em></a>, you’ll learn the best techniques and processes to do just that.</p>
tag:www.justinweiss.com,2015-09-16:/articles/3-steps-to-fix-encoding-problems-in-ruby/3 steps to fix encoding problems in Ruby2015-09-16T06:59:11Z2015-09-16T06:59:11Z
<p><strong>You only really think about a string’s encoding when it breaks.</strong> When you check your exception tracker and see</p>
<figure class="code"><pre class="highlight"><code class="language-text">Encoding::InvalidByteSequenceError: "\xFE" on UTF-8</code>
</pre></figure>
<p>staring you in the face. Or maybe “they’re” starts showing up as “they’re”.</p>
<p>So, when you have a bad encoding, how do you figure out what broke? And how can you fix it?</p>
<h2 id="what-is-an-encoding">What is an encoding?</h2>
<p>If you can imagine what encoding does to a string, these bugs are easier to fix.</p>
<p>You can think of a string as an array of bytes, or small numbers:</p>
<figure class="code"><pre class="highlight"><code class="language-irb"><span class="gp">irb(main):001:0></span><span class="w"> </span><span class="s2">"hello!"</span><span class="p">.</span><span class="nf">bytes</span>
<span class="p">=></span> <span class="p">[</span><span class="mi">104</span><span class="p">,</span> <span class="mi">101</span><span class="p">,</span> <span class="mi">108</span><span class="p">,</span> <span class="mi">108</span><span class="p">,</span> <span class="mi">111</span><span class="p">,</span> <span class="mi">33</span><span class="p">]</span></code>
</pre></figure>
<p>In this encoding, <code>104</code> means <code>h</code>, <code>33</code> means <code>!</code>, and so on.</p>
<p>It gets trickier when you use characters that are less common in English:</p>
<figure class="code"><pre class="highlight"><code class="language-irb"><span class="gp">irb(main):002:0></span><span class="w"> </span><span class="s2">"hellṏ!"</span><span class="p">.</span><span class="nf">bytes</span>
<span class="p">=></span> <span class="p">[</span><span class="mi">104</span><span class="p">,</span> <span class="mi">101</span><span class="p">,</span> <span class="mi">108</span><span class="p">,</span> <span class="mi">108</span><span class="p">,</span> <span class="mi">225</span><span class="p">,</span> <span class="mi">185</span><span class="p">,</span> <span class="mi">143</span><span class="p">,</span> <span class="mi">33</span><span class="p">]</span></code>
</pre></figure>
<p>Now it’s harder to tell which number represents which character. Instead of one byte, <code>ṏ</code> is represented by the group of bytes <code>[225, 185, 143]</code>. But there’s still a relationship between bytes and characters. <strong>And a string’s encoding defines that relationship.</strong></p>
<p>Take a look at what a single set of bytes looks like when you try different encodings:</p>
<figure class="code"><pre class="highlight"><code class="language-irb"><span class="c"># Try an ISO-8859-1 string with a special character!
</span><span class="gp">irb(main):003:0></span><span class="w"> </span><span class="n">str</span> <span class="o">=</span> <span class="s2">"hellÔ!"</span><span class="p">.</span><span class="nf">encode</span><span class="p">(</span><span class="s2">"ISO-8859-1"</span><span class="p">);</span> <span class="n">str</span><span class="p">.</span><span class="nf">encode</span><span class="p">(</span><span class="s2">"UTF-8"</span><span class="p">)</span>
<span class="p">=></span> <span class="s2">"hellÔ!"</span>
<span class="gp">irb(main):004:0></span><span class="w"> </span><span class="n">str</span><span class="p">.</span><span class="nf">bytes</span>
<span class="p">=></span> <span class="p">[</span><span class="mi">104</span><span class="p">,</span> <span class="mi">101</span><span class="p">,</span> <span class="mi">108</span><span class="p">,</span> <span class="mi">108</span><span class="p">,</span> <span class="mi">212</span><span class="p">,</span> <span class="mi">33</span><span class="p">]</span>
<span class="c"># What would that string look like interpreted as ISO-8859-5 instead?
</span><span class="gp">irb(main):005:0></span><span class="w"> </span><span class="n">str</span><span class="p">.</span><span class="nf">force_encoding</span><span class="p">(</span><span class="s2">"ISO-8859-5"</span><span class="p">);</span> <span class="n">str</span><span class="p">.</span><span class="nf">encode</span><span class="p">(</span><span class="s2">"UTF-8"</span><span class="p">)</span>
<span class="p">=></span> <span class="s2">"hellд!"</span>
<span class="gp">irb(main):006:0></span><span class="w"> </span><span class="n">str</span><span class="p">.</span><span class="nf">bytes</span>
<span class="p">=></span> <span class="p">[</span><span class="mi">104</span><span class="p">,</span> <span class="mi">101</span><span class="p">,</span> <span class="mi">108</span><span class="p">,</span> <span class="mi">108</span><span class="p">,</span> <span class="mi">212</span><span class="p">,</span> <span class="mi">33</span><span class="p">]</span></code>
</pre></figure>
<p>The bytes didn’t change. But that doesn’t look right at all. Changing the encoding changed how the string printed, without changing the bytes.</p>
<p><strong>And not all strings can be represented in all encodings</strong>:</p>
<figure class="code"><pre class="highlight"><code class="language-irb"><span class="gp">irb(main):006:0></span><span class="w"> </span><span class="s2">"hi∑"</span><span class="p">.</span><span class="nf">encode</span><span class="p">(</span><span class="s2">"Windows-1252"</span><span class="p">)</span>
<span class="go">Encoding::UndefinedConversionError: U+2211 to WINDOWS-1252 in conversion from UTF-8 to WINDOWS-1252
from (irb):61:in `encode'
from (irb):61
</span><span class="gp"> from /usr/local/bin/irb:11:in `<main></span><span class="err">'</span></code>
</pre></figure>
<p>Most encodings are small, and can’t handle every possible character. You’ll see that error when a character in one encoding doesn’t exist in another, or when Ruby can’t figure out how to translate a character between two encodings.</p>
<p><strong>You can work around this error if you pass extra options into <a href="http://ruby-doc.org/core-2.2.3/String.html#method-i-encode"><code>encode</code></a>:</strong></p>
<figure class="code"><pre class="highlight"><code class="language-irb"><span class="gp">irb(main):064:0></span><span class="w"> </span><span class="s2">"hi∑"</span><span class="p">.</span><span class="nf">encode</span><span class="p">(</span><span class="s2">"Windows-1252"</span><span class="p">,</span> <span class="ss">invalid: :replace</span><span class="p">,</span> <span class="ss">undef: :replace</span><span class="p">)</span>
<span class="p">=></span> <span class="s2">"hi?"</span></code>
</pre></figure>
<p>The <code>invalid</code> and <code>undef</code> options replace characters that can’t be translated with a different character. By default, that replacement character is <code>?</code>. (When you convert to Unicode, it’s �).</p>
<p><strong>Unfortunately, when you replace characters with <code>encode</code>, you might lose information.</strong> You have no idea which bytes were replaced by <code>?</code>. But if you need your data to be in that new encoding, losing data can be better than things being broken.</p>
<hr>
<p>So far, you’ve seen three key string methods to help you understand encodings:</p>
<ul>
<li>
<p><a href="http://ruby-doc.org/core-2.2.3/String.html#method-i-encode"><code>encode</code></a>, which translates a string to another encoding (converting characters to their equivalent in the new encoding)</p>
</li>
<li>
<p><a href="http://ruby-doc.org/core-2.2.3/String.html#method-i-bytes"><code>bytes</code></a>, which will show you the bytes that make up a string</p>
</li>
<li>
<p><a href="http://ruby-doc.org/core-2.2.3/String.html#method-i-force_encoding"><code>force_encoding</code></a>, which will show you what those bytes would look like interpreted by a different encoding</p>
</li>
</ul>
<p>The major difference between <code>encode</code> and <code>force_encoding</code> is that <code>encode</code> might change <code>bytes</code>, and <code>force_encoding</code> won’t.</p>
<h2 id="a-three-step-process-for-fixing-encoding-bugs">A three-step process for fixing encoding bugs</h2>
<p>You can fix most encoding issues with three steps:</p>
<h3 id="discover-which-encoding-your-string-is-actually-in">1. Discover which encoding your string is <em>actually</em> in.</h3>
<p>This sounds easy. <strong>But just because a string <em>says</em> it’s some encoding, doesn’t mean it actually is:</strong></p>
<figure class="code"><pre class="highlight"><code class="language-irb"><span class="gp">irb(main):078:0></span><span class="w"> </span><span class="s2">"hi</span><span class="se">\x99</span><span class="s2">!"</span><span class="p">.</span><span class="nf">encoding</span>
<span class="p">=></span> <span class="kt">#<</span><span class="no">Encoding</span><span class="ss">:UTF</span><span class="o">-</span><span class="mi">8</span><span class="kt">></span></code>
</pre></figure>
<p>That’s not right – if it was <em>really</em> UTF-8, it wouldn’t have that weird backslashed number in it. So how do you figure out the right encoding for your string?</p>
<p>A lot of older software will stick to a single default encoding, so you can research where the input came from. Did someone paste it in from Word? It could be <a href="https://en.wikipedia.org/wiki/Windows-1252">Windows-1252</a>. Did it come from a file or did you pull it from an older website? It might be <a href="https://en.wikipedia.org/wiki/ISO/IEC_8859-1">ISO-8859-1</a>.</p>
<p><strong>I’ve also found it helpful to search for encoding tables, like the ones on those linked Wikipedia pages.</strong> On those tables, you can look up the characters referenced by the unknown numbers, and see if they make sense in context.</p>
<p>In this example, the Windows-1252 chart shows that the byte <code>99</code> represents the “™” character. Byte <code>99</code> doesn’t exist under ISO-8859-1. If ™ makes sense here, you could assume the input was in Windows-1252 and move on. Otherwise, you could keep researching until you found a character that seems more reasonable.</p>
<h3 id="decide-which-encoding-you-want-the-string-to-be">2. Decide which encoding you <em>want</em> the string to be.</h3>
<p>This one’s easy. Unless you have a really good reason, <a href="http://utf8everywhere.org">you want your strings to be UTF-8 encoded</a>.</p>
<p>There’s one other common encoding you might use in Ruby: ASCII-8BIT. In ASCII-8BIT, every character is represented by a single byte. That is, <code>str.chars.length == str.bytes.length</code>. So, if you want a lot of control over the specific bytes in your string, ASCII-8BIT might be a good option.</p>
<h3 id="re-encode-your-string-from-the-encoding-in-step-1-to-the-encoding-in-step-2">3. Re-encode your string from the encoding in step 1 to the encoding in step 2.</h3>
<p>You can do this with the <code>encode</code> method. In this example, our string <em>was</em> in the Windows-1252 encoding, and we <em>want</em> it to become UTF-8. Pretty straightforward:</p>
<figure class="code"><pre class="highlight"><code class="language-irb"><span class="gp">irb(main):088:0></span><span class="w"> </span><span class="s2">"hi</span><span class="se">\x99</span><span class="s2">!"</span><span class="p">.</span><span class="nf">encode</span><span class="p">(</span><span class="s2">"UTF-8"</span><span class="p">,</span> <span class="s2">"Windows-1252"</span><span class="p">)</span>
<span class="p">=></span> <span class="s2">"hi™!"</span></code>
</pre></figure>
<p>Much better. (Even though the order of the encodings in that call always seemed backwards to me).</p>
<hr>
<p>It can be brain-bending to imagine different interpretations of the same array of bytes. <em>Especially</em> when one of those interpretations is broken. <strong>But there’s a great way to become a lot more comfortable with encodings: Play with them.</strong></p>
<p>Open an <code>irb</code> console, and mess around with <code>encode</code>, <code>bytes</code>, and <code>force_encoding</code>. Watch how <code>encode</code> changes the bytes making up the string. Build intuition about what different encodings look like. When you’ve grown more comfortable with encodings and use these steps, you’ll fix in minutes what would have taken you hours before.</p>
<p><strong>Finally, if you want to learn how to make a habit out of learning these kinds of things by doing, <a href="/practicing-rails">grab the free sample chapter of my book</a>.</strong> Breaking things in the console is a <em>really</em> fun way to study ideas like this.</p>
tag:www.justinweiss.com,2015-09-08:/articles/keeping-your-logs-from-becoming-an-unreadable-mess/Keeping your logs from becoming an unreadable mess2015-09-08T07:23:49Z2015-09-08T07:23:49Z<p>When you run into a strange, seemingly unsolvable bug, improving your logging can be the best step you can take. <strong>Great logging is the easiest way to detect and fix entire classes of bugs.</strong> When you log enough information, you can see how your data changes during a request. You can track the calls you make to other services, and investigate the response. In fact, when debuggers failed, logging helped me fix the toughest bug I’ve ever run into.</p>
<p><strong>But log too much, and your log files will quickly turn into a jumble of unreadable, unhelpful messages.</strong> How can you slice just the information you care about out of that pile of data? Can you print messages in a way that’s easy to filter later?</p>
<h2 id="marking-your-log-messages">Marking your log messages</h2>
<p><strong>Rails includes <a href="http://api.rubyonrails.org/classes/ActiveSupport/TaggedLogging.html">TaggedLogging</a>, which can help you quickly categorize related log messages.</strong> When you tag a logger, you’ll get a marker at the beginning of your message. So instead of:</p>
<figure class="code"><pre class="highlight"><code class="language-sh">Finding people...
Person Load <span class="o">(</span>0.3ms<span class="o">)</span> SELECT <span class="s2">"people"</span>.<span class="k">*</span> FROM <span class="s2">"people"</span>
Found 0 people!</code>
</pre></figure>
<p>You could tag the Rails logger:</p>
<figure class="code"><pre class="highlight"><code class="language-ruby"><span class="n">logger</span><span class="p">.</span><span class="nf">tagged</span><span class="p">(</span><span class="s2">"People"</span><span class="p">)</span> <span class="k">do</span>
<span class="n">logger</span><span class="p">.</span><span class="nf">debug</span> <span class="s2">"Finding people..."</span>
<span class="vi">@people</span> <span class="o">=</span> <span class="no">Person</span><span class="p">.</span><span class="nf">all</span>
<span class="n">logger</span><span class="p">.</span><span class="nf">debug</span> <span class="s2">"Found </span><span class="si">#{</span><span class="vi">@people</span><span class="p">.</span><span class="nf">length</span><span class="si">}</span><span class="s2"> people!"</span>
<span class="k">end</span></code>
</pre></figure>
<p>And you’d see something like this:</p>
<figure class="code"><pre class="highlight"><code class="language-sh"><span class="o">[</span>People] Finding people...
<span class="o">[</span>People] Person Load <span class="o">(</span>0.3ms<span class="o">)</span> SELECT <span class="s2">"people"</span>.<span class="k">*</span> FROM <span class="s2">"people"</span>
<span class="o">[</span>People] Found 0 people!</code>
</pre></figure>
<p><strong>Now, log messages that care about different things can <em>look</em> different.</strong></p>
<h2 id="some-tagged-logger-examples">Some tagged logger examples</h2>
<p>As you log more often, and log more complicated things, you’ll naturally notice areas where those tags will make your messages clearer. <strong>But there are a few places I’ve found tagged logging particularly helpful.</strong> I’ll usually tag those right away.</p>
<p><strong>You can log requests you make to other APIs:</strong></p>
<figure class="code"><pre class="highlight"><code class="language-ruby"><span class="n">logger</span><span class="p">.</span><span class="nf">tagged</span><span class="p">(</span><span class="s2">"GitHub API"</span><span class="p">)</span> <span class="k">do</span>
<span class="n">uri</span> <span class="o">=</span> <span class="no">URI</span><span class="p">(</span><span class="s2">"https://api.github.com/repos/rails/rails/tags"</span><span class="p">)</span>
<span class="n">logger</span><span class="p">.</span><span class="nf">info</span> <span class="p">{</span> <span class="s2">"Fetching </span><span class="si">#{</span><span class="n">uri</span><span class="si">}</span><span class="s2">"</span> <span class="p">}</span>
<span class="n">tags</span> <span class="o">=</span> <span class="no">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="no">Net</span><span class="o">::</span><span class="no">HTTP</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="n">uri</span><span class="p">))</span>
<span class="n">logger</span><span class="p">.</span><span class="nf">info</span> <span class="p">{</span> <span class="s2">"First tag: </span><span class="si">#{</span><span class="n">tags</span><span class="p">.</span><span class="nf">first</span><span class="p">[</span><span class="s2">"name"</span><span class="p">]</span><span class="si">}</span><span class="s2">"</span> <span class="p">}</span>
<span class="k">end</span></code>
</pre></figure>
<figure class="code"><pre class="highlight"><code class="language-sh"><span class="o">[</span>GitHub API] Fetching https://api.github.com/repos/rails/rails/tags
<span class="o">[</span>GitHub API] First tag: v4.2.4.rc1</code>
</pre></figure>
<p>That way, you can easily see how and when your app is talking to that API.</p>
<p>(This works particularly well with <a href="https://github.com/lostisland/faraday">Faraday</a> middleware, or if you only communicate with a server through a <a href="http://martinfowler.com/eaaCatalog/gateway.html">Gateway</a>).</p>
<p><strong>Background jobs also work well with tagged logging:</strong></p>
<figure class="code"><pre class="highlight"><code class="language-ruby"><span class="nb">require</span> <span class="s2">"active_support/tagged_logging"</span>
<span class="no">Resque</span><span class="p">.</span><span class="nf">logger</span> <span class="o">=</span> <span class="no">ActiveSupport</span><span class="o">::</span><span class="no">TaggedLogging</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="no">Resque</span><span class="p">.</span><span class="nf">logger</span><span class="p">)</span>
<span class="k">module</span> <span class="nn">LoggedJob</span>
<span class="k">def</span> <span class="nf">around_perform_log_job</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
<span class="n">logger</span><span class="p">.</span><span class="nf">tagged</span><span class="p">(</span><span class="nb">name</span><span class="p">)</span> <span class="k">do</span>
<span class="n">logger</span><span class="p">.</span><span class="nf">info</span> <span class="p">{</span> <span class="s2">"Performing </span><span class="si">#{</span><span class="nb">name</span><span class="si">}</span><span class="s2"> with </span><span class="si">#{</span><span class="n">args</span><span class="p">.</span><span class="nf">inspect</span><span class="si">}</span><span class="s2">"</span> <span class="p">}</span>
<span class="k">yield</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">MyJob</span>
<span class="kp">extend</span> <span class="no">LoggedJob</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">perform</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
<span class="o">...</span>
<span class="k">end</span>
<span class="k">end</span></code>
</pre></figure>
<p>Now, any job that extends LoggedJob will have all of its log messages tagged with the class name of the job.</p>
<p><strong>And if you have a logged-in user, you could tag messages with their user ID:</strong></p>
<figure class="code"><pre class="highlight"><code class="language-ruby"><span class="n">logger</span><span class="p">.</span><span class="nf">tagged</span><span class="p">(</span><span class="n">current_user_id</span> <span class="p">?</span> <span class="s2">"user-</span><span class="si">#{</span><span class="n">current_user_id</span><span class="si">}</span><span class="s2">"</span> <span class="p">:</span> <span class="s2">"user-anonymous"</span><span class="p">)</span> <span class="k">do</span>
<span class="n">logger</span><span class="p">.</span><span class="nf">debug</span> <span class="s2">"Finding people..."</span>
<span class="vi">@people</span> <span class="o">=</span> <span class="no">Person</span><span class="p">.</span><span class="nf">all</span>
<span class="n">logger</span><span class="p">.</span><span class="nf">debug</span> <span class="s2">"Found </span><span class="si">#{</span><span class="vi">@people</span><span class="p">.</span><span class="nf">length</span><span class="si">}</span><span class="s2"> people!"</span>
<span class="k">end</span></code>
</pre></figure>
<figure class="code"><pre class="highlight"><code class="language-sh"><span class="o">[</span>user-123] Finding people...
<span class="o">[</span>user-123] Person Load <span class="o">(</span>0.3ms<span class="o">)</span> SELECT <span class="s2">"people"</span>.<span class="k">*</span> FROM <span class="s2">"people"</span>
<span class="o">[</span>user-123] Found 0 people!</code>
</pre></figure>
<p><strong>Finally, if you add a line to your <code>config/environments/production.rb</code> (or <code>development.rb</code>), you can have Rails automatically tag your messages:</strong></p>
<figure class="code"><pre class="highlight"><code class="language-ruby"><span class="n">config</span><span class="p">.</span><span class="nf">log_tags</span> <span class="o">=</span> <span class="p">[</span> <span class="ss">:subdomain</span><span class="p">,</span> <span class="ss">:uuid</span> <span class="p">]</span></code>
</pre></figure>
<p><code>log_tags</code> lists the tags you want to appear at the beginning of every Rails log entry. Each symbol refers to a method on <a href="http://api.rubyonrails.org/classes/ActionDispatch/Request.html">ActionDispatch::Request</a>, so <code>:uuid</code> means <code>request.uuid</code>.</p>
<p>You can also pass a Proc that takes a <code>request</code> object:</p>
<figure class="code"><pre class="highlight"><code class="language-ruby"><span class="n">config</span><span class="p">.</span><span class="nf">log_tags</span> <span class="o">=</span> <span class="p">[</span> <span class="ss">:subdomain</span><span class="p">,</span> <span class="ss">:uuid</span><span class="p">,</span> <span class="nb">lambda</span> <span class="p">{</span> <span class="o">|</span><span class="n">request</span><span class="o">|</span> <span class="n">request</span><span class="p">.</span><span class="nf">headers</span><span class="p">[</span><span class="s2">"User-Agent"</span><span class="p">]</span> <span class="p">}</span> <span class="p">]</span></code>
</pre></figure>
<p>But I don’t see that very often.</p>
<p>These default tags are nice: <code>uuid</code> can tie together all the log entries that happen in one request, and if you’re keeping sessions on the server, the session ID is also helpful. <strong>With those tags, and enough messages, you can trace some really complicated paths through your app.</strong> And usually, that’s what it takes to figure out how a nasty bug happened.</p>
<p>How much do you use the Rails logger in your apps? Have you tried tagged logging? If you haven’t, try finding a place for it. <strong>Tagging actions taken by your users is a good start.</strong> It’ll help you out the next time you have to debug a crazy multi-step bug.</p>
<p>If you want to learn more about logging and other debugging techniques, I’ve dedicated an entire chapter of <a href="/practicing-rails">Practicing Rails</a> to finding and fixing the errors you’ll run into as you create your apps. <strong><a href="/practicing-rails">Grab the first chapter for free here</a>.</strong></p>
tag:www.justinweiss.com,2015-09-01:/articles/should-you-use-scopes-or-class-methods/Should you use scopes or class methods?2015-09-01T07:30:32Z2015-09-01T07:30:32Z
<p><em>This article is <a href="http://kydonia.net/blog/npmachine/2016/12/27/Should-You-Use-Scopes-or-Class-Methods.html">also available in Korean</a>, thanks to Soonsang Hong!</em></p>
<p><a href="http://guides.rubyonrails.org/active_record_querying.html#scopes">Scopes</a> are a great way to grab the right objects out of your database:</p>
<figure class="code"><figcaption><span>app/models/review.rb</span></figcaption><pre class="highlight"><code class="language-ruby"><span class="k">class</span> <span class="nc">Review</span> <span class="o"><</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
<span class="n">scope</span> <span class="ss">:most_recent</span><span class="p">,</span> <span class="o">-></span> <span class="p">(</span><span class="n">limit</span><span class="p">)</span> <span class="p">{</span> <span class="n">order</span><span class="p">(</span><span class="s2">"created_at desc"</span><span class="p">).</span><span class="nf">limit</span><span class="p">(</span><span class="n">limit</span><span class="p">)</span> <span class="p">}</span>
<span class="k">end</span></code>
</pre></figure>
<p>You’d use the scope like this:</p>
<figure class="code"><figcaption><span>app/models/homepage_controller.rb</span></figcaption><pre class="highlight"><code class="language-ruby"><span class="vi">@recent_reviews</span> <span class="o">=</span> <span class="no">Review</span><span class="p">.</span><span class="nf">most_recent</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span></code>
</pre></figure>
<p><strong>Calling that scope, though, looks <em>exactly</em> like calling a class method on <code>Review</code></strong>. And it’s easy to build it as a class method, instead:</p>
<figure class="code"><figcaption><span>app/models/review.rb</span></figcaption><pre class="highlight"><code class="language-ruby"><span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">most_recent</span><span class="p">(</span><span class="n">limit</span><span class="p">)</span>
<span class="n">order</span><span class="p">(</span><span class="s2">"created_at desc"</span><span class="p">).</span><span class="nf">limit</span><span class="p">(</span><span class="n">limit</span><span class="p">)</span>
<span class="k">end</span></code>
</pre></figure>
<figure class="code"><figcaption><span>app/controllers/homepage_controller.rb</span></figcaption><pre class="highlight"><code class="language-ruby"><span class="vi">@recent_reviews</span> <span class="o">=</span> <span class="no">Review</span><span class="p">.</span><span class="nf">most_recent</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span></code>
</pre></figure>
<p><strong>So why would you use a scope when you could use regular Ruby class methods?</strong> Is it worth keeping these totally separate, but equivalent, concepts in your head? What if you run into weird bugs? Isn’t all this extra stuff the kind of thing that makes Rails harder to learn?</p>
<p>When <em>would</em> it make sense to use a scope instead of a class method?</p>
<h2 id="why-use-scopes-when-we-already-have-class-methods">Why use scopes when we already have class methods?</h2>
<p>What if you wanted to grab all the reviews written after a specific date? But if no date was specified, you wanted <em>all</em> the reviews returned instead?</p>
<p>As a scope, that looks like this:</p>
<figure class="code"><figcaption><span>app/models/review.rb</span></figcaption><pre class="highlight"><code class="language-ruby"><span class="n">scope</span> <span class="ss">:created_since</span><span class="p">,</span> <span class="o">-></span><span class="p">(</span><span class="n">time</span><span class="p">)</span> <span class="p">{</span> <span class="n">where</span><span class="p">(</span><span class="s2">"reviews.created_at > ?"</span><span class="p">,</span> <span class="n">time</span><span class="p">)</span> <span class="k">if</span> <span class="n">time</span><span class="p">.</span><span class="nf">present?</span> <span class="p">}</span></code>
</pre></figure>
<p>Easy enough, right? What about the class method?</p>
<figure class="code"><figcaption><span>app/models/review.rb</span></figcaption><pre class="highlight"><code class="language-ruby"><span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">created_since</span><span class="p">(</span><span class="n">time</span><span class="p">)</span>
<span class="k">if</span> <span class="n">time</span><span class="p">.</span><span class="nf">present?</span>
<span class="n">where</span><span class="p">(</span><span class="s2">"reviews.created_at > ?"</span><span class="p">,</span> <span class="n">time</span><span class="p">)</span>
<span class="k">else</span>
<span class="n">all</span>
<span class="k">end</span>
<span class="k">end</span></code>
</pre></figure>
<p>It takes a little bit of extra work. Scopes prefer to return scopes, so they’re easy to chain together:</p>
<figure class="code"><pre class="highlight"><code class="language-ruby"><span class="no">Review</span><span class="p">.</span><span class="nf">positive</span><span class="p">.</span><span class="nf">created_since</span><span class="p">(</span><span class="mi">5</span><span class="p">.</span><span class="nf">days</span><span class="p">.</span><span class="nf">ago</span><span class="p">)</span></code>
</pre></figure>
<p><strong>But to get the class method to work the same way, you have to specifically handle the case where time is nil.</strong> Otherwise, the <em>caller</em> would have to figure out whether it has a valid, chainable scope.</p>
<p><strong><a href="/blog/2014/06/24/simplify-your-ruby-code-with-the-robustness-principle/">Methods that always return the same kind of object are really useful</a></strong>. You don’t have to worry as much about edge cases or errors. You can assume you’ll always be handed back an object you can use.</p>
<p>Here, it means you can chain scopes together, without having to worry about <code>nil</code> values coming back.</p>
<p>There are still ways you can break the assumption that you’d always get a scope back:</p>
<figure class="code"><figcaption><span>app/models/review.rb</span></figcaption><pre class="highlight"><code class="language-ruby"><span class="n">scope</span> <span class="ss">:broken</span><span class="p">,</span> <span class="o">-></span> <span class="p">{</span> <span class="s2">"Hello!!!"</span> <span class="p">}</span></code>
</pre></figure>
<figure class="code"><pre class="highlight"><code class="language-irb"><span class="gp">irb(main):001:0></span><span class="w"> </span><span class="no">Review</span><span class="p">.</span><span class="nf">broken</span><span class="p">.</span><span class="nf">most_recent</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="gr">NoMethodError: undefined method `most_recent' for "Hello!!!":String</span></code>
</pre></figure>
<p>But I’ve never had that happen in real code.</p>
<p><strong>The thing I love most about scopes is that they express <em>intent</em></strong>. You’re telling the next person who reads your code, “This method can be chained, will eventually turn into a list of objects, and will help you select the right set of objects.” That’s a whole lot more than a generic class method says.</p>
<h2 id="when-should-you-use-a-class-method-instead-of-a-scope">When should you use a class method instead of a scope?</h2>
<p><strong>Because scopes express intent, I use them whenever I’m chaining simple, built-in scopes (like <code>where</code> and <code>limit</code>) into more complicated scopes</strong>. Finding the right bunch of objects is what scopes were designed for.</p>
<p>There are two exceptions:</p>
<ol>
<li>
<strong>When I need to preload scopes, <a href="http://www.justinweiss.com/blog/2015/06/23/how-to-preload-rails-scopes/">I turn them into associations instead</a></strong>.</li>
<li>
<strong>When I do more than chain built-in scopes into larger scopes, I use class methods</strong>.</li>
</ol>
<p>When your scope logic gets complicated, a class method feels like the right place to put it.</p>
<p>Inside a class method, you can easily mix Ruby code with database code. If you have sorting code that’s easier to write in Ruby, you could grab your objects in their default order, and use <a href="http://ruby-doc.org/core-2.2.3/Enumerable.html#method-i-sort_by">sort_by</a> to put them in the right order.</p>
<p>Or, if you’re feeling particularly tricky, a class method could grab data from a few different places: your database, Redis, or an external API or service. Then, it could assemble it all into a collection of objects that <em>feels</em> like a scope that’s been turned into an array.</p>
<p><strong>Even then, it’s still good to put your selecting, sorting, joining, and filtering code inside scopes. Then, use your scopes inside your class method.</strong> You’ll end up with a clearer class method, and scopes you can use throughout your app.</p>
<hr>
<p>Scopes are one of my favorite Rails features. <strong>You can do some powerful stuff – read my article on <a href="/blog/2014/02/17/search-and-filter-rails-models-without-bloating-your-controller/">sorting and filtering Rails models</a> to see an especially useful scope example.</strong></p>
<p>And there’s a really simple way to master using scopes: play with them inside tiny, focused apps. <strong><a href="/practicing-rails">The free sample chapter of Practicing Rails</a> will show you how.</strong> Check it out!</p>
tag:www.justinweiss.com,2015-07-29:/articles/how-to-predict-the-future-of-programming/How to predict the future of programming2015-07-29T05:52:27Z2015-07-29T05:52:27Z<p>Why did Rails become so popular, so quickly?</p>
<p>The simplicity helped, especially if you came from the Java, XML, Enterprise world. <a href="https://www.youtube.com/watch?v=Gzj723LkRJY">It was also marketed incredibly well</a>. But that’s not everything.</p>
<p><strong>A lot of Rails’ success in the startup world came from a simple fact: The problems businesses have aren’t that unique.</strong> Rails was great at creating <a href="https://en.wikipedia.org/wiki/Create,_read,_update_and_delete">CRUD</a> sites, while remaining flexible. And that’s really all a <em>ton</em> of businesses need. Especially at the beginning.</p>
<p>But this isn’t just true for businesses. <strong>A lot of the problems we face as software developers don’t change.</strong> Sure, our solutions evolve. They cycle. We get better. But the same solutions discovered by the last generation of developers can still help us today.</p>
<p>So, do you want to know the answers to the problems you’ll face in the future? The best thing you can do is look to the past.</p>
<h2 id="look-to-the-past">Look to the past</h2>
<p><strong>On <a href="http://martinfowler.com">his website</a>, Martin Fowler has an unbelievable collection of good solutions to common problems</strong>. Have you been <a href="http://blog.arkency.com/2015/03/fast-introduction-to-event-sourcing-for-ruby-programmers/">hearing devs talk about Event Sourcing</a>? He wrote the <a href="http://www.martinfowler.com/eaaDev/EventSourcing.html">definitive article</a> on it 10 years ago. Chasing performance and reliability problems with your new REST API or <a href="https://en.wikipedia.org/wiki/Service-oriented_architecture">Service-Oriented Architecture</a>? It’s <a href="http://www.drdobbs.com/errant-architectures/184414966">his first law of distributed objects</a>, from close to 15 years ago.</p>
<p><a href="http://avdi.org">Avdi Grimm</a> told me that “If you want to lead the technology curve, start investigating whatever Martin Fowler was writing about a decade ago.” That’s totally true. <strong>The time you spend reading through the <a href="http://martinfowler.com">patterns on his website</a> will be a great investment in your programming future.</strong> And that’s not even mentioning <a href="http://refactoring.com/catalog/">the refactoring patterns</a>.</p>
<p>Going further, just about any book or article written by the <a href="http://www.agilemanifesto.org">authors of the Agile Manifesto</a> is worth reading – 15 years ago, they were working through the same software architecture problems we run into today.</p>
<p><strong>You can find a lot of their discussions on the <a href="http://www.c2.com/cgi/wiki">C2 Wiki</a></strong>. The debates we have about <a href="http://www.c2.com/cgi/wiki?TestDrivenDevelopment">when TDD makes the most sense</a>? They’re all there. And they’ve <em>been</em> there. The wiki has been around for a while, and it’s still a fantastic resource.</p>
<p>Books from the late 90’s to the early 2000’s are also helpful. I smiled all the way through <a href="http://www.amazon.com/Smalltalk-Best-Practice-Patterns-Kent/dp/013476904X">Smalltalk Best Practice Patterns</a> and <a href="http://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420">Patterns of Enterprise Application Architecture</a> (which was a huge influence on Rails), because they described problems I’ve had <em>so well</em>.</p>
<hr>
<p>Just like design fashions, software development practices cycle. From distributed to centralized, from client side to server side, from dynamic to static.</p>
<p>Do you want to get ahead, understand what’s coming, and maybe even <em>drive</em> what comes next? Look to the past. <strong>Research the solutions to the problems that our current solutions will cause.</strong> And help bring the good practices of the last generation of software developers to the next.</p>
tag:www.justinweiss.com,2015-07-21:/articles/turn-ruby-conference-videos-into-your-own-personal-podcast/Turn Ruby conference videos into your own personal podcast2015-07-21T06:58:03Z2015-07-21T06:58:03Z
<p>Ruby conferences are awesome. There are so many people sharing so much knowledge, and you’ll take something away from almost every talk. <strong>And even if you can’t be there, new conferences mean lots of new talk videos.</strong></p>
<p>But there’s a problem. Videos take time. Even at 1.5x, they’ll still last 20 or 30 minutes each. And that’s focused time that’s hard to find as often as I’d like.</p>
<p>Podcasts, though, <a href="http://www.justinweiss.com/blog/2014/05/13/how-to-learn-ruby-while-you-walk-the-dog/">have already found a place in my life</a>. I start almost every commute by firing up <a href="https://overcast.fm">Overcast</a> and listening to a few episodes. And besides the commute, you can listen to them while you walk the dog, or do the dishes. You can hear them as you go off to sleep.</p>
<p><strong>So, after conference videos are posted, I’d love to take some of the non-code-heavy talks and put them where I’ll naturally hear them: inside my podcast player.</strong> And it turns out there’s a pretty easy way to do just that.</p>
<h2 id="creating-a-personal-podcast-with-huffduffer">Creating a personal podcast with Huffduffer</h2>
<p><strong><a href="https://huffduffer.com">Huffduffer</a> is a website that turns audio files you find anywhere on the web into your own personal podcast station.</strong> This is really cool! But there’s a problem when you try it with conference talks:</p>
<p><strong>Most conference videos are conference <em>videos</em>.</strong></p>
<p>So, before you can add a talk to Huffduffer, you have to grab just the audio out of it. And to do that, you have to find a way to download the video.</p>
<h2 id="fetching-a-video-with-youtube-dl">Fetching a video with <code>youtube-dl</code>
</h2>
<p><strong>When you see a video on a site like Youtube, Vimeo, or Confreaks, and you’d rather have it on your machine, you can use a little tool called <a href="https://rg3.github.io/youtube-dl/"><code>youtube-dl</code></a>.</strong> On a Mac, it’s easy to install using <a href="http://brew.sh">Homebrew</a>:</p>
<figure class="code"><pre class="highlight"><code class="language-sh">brew <span class="nb">install </span>youtube-dl</code>
</pre></figure>
<p>(You can install it on other systems using <a href="https://rg3.github.io/youtube-dl/download.html">the instructions on the site</a>).</p>
<p>Once it’s installed, if you wanted to download <a href="http://kyfast.net">Kylie Stradley’s</a> <a href="http://confreaks.tv/videos/railsconf2015-amelia-bedelia-learns-to-code">great RailsConf 2015 talk</a> so you could watch it offline, run:</p>
<figure class="code"><pre class="highlight"><code class="language-sh">youtube-dl http://confreaks.tv/videos/railsconf2015-amelia-bedelia-learns-to-code</code>
</pre></figure>
<p>This is close to what we want. But to put it in a podcast, you only need the audio. <code>youtube-dl</code> supports that with the <code>-x</code> flag, but you have to install <code>ffmpeg</code> first:</p>
<figure class="code"><pre class="highlight"><code class="language-sh"><span class="nv">$ </span>brew <span class="nb">install </span>ffmpeg
<span class="nv">$ </span>youtube-dl <span class="nt">-x</span> http://confreaks.tv/videos/railsconf2015-amelia-bedelia-learns-to-code
<span class="o">[</span>generic] railsconf2015-amelia-bedelia-learns-to-code: Requesting header
WARNING: Falling back on generic information extractor.
<span class="o">[</span>generic] railsconf2015-amelia-bedelia-learns-to-code: Downloading webpage
<span class="o">[</span>generic] railsconf2015-amelia-bedelia-learns-to-code: Extracting information
<span class="o">[</span>download] Downloading playlist: Confreaks TV | Amelia Bedelia Learns to Code - RailsConf 2015
<span class="o">[</span>generic] playlist Confreaks TV | Amelia Bedelia Learns to Code - RailsConf 2015: Collected 1 video ids <span class="o">(</span>downloading 1 of them<span class="o">)</span>
<span class="o">[</span>download] Downloading video 1 of 1
<span class="o">[</span>youtube] bSbla50tqZE: Downloading webpage
<span class="o">[</span>youtube] bSbla50tqZE: Extracting video information
<span class="o">[</span>download] Destination: RailsConf 2015 - Amelia Bedelia Learns to Code-bSbla50tqZE.m4a
<span class="o">[</span>download] 100% of 31.88MiB <span class="k">in </span>00:05
<span class="o">[</span>ffmpeg] Correcting container <span class="k">in</span> <span class="s2">"RailsConf 2015 - Amelia Bedelia Learns to Code-bSbla50tqZE.m4a"</span>
<span class="o">[</span>youtube] Post-process file RailsConf 2015 - Amelia Bedelia Learns to Code-bSbla50tqZE.m4a exists, skipping</code>
</pre></figure>
<p>Then, in Huffduffer, click the “Huffduff it” link in the header, and you’ll run into the last hoop you have to jump through.</p>
<h2 id="uploading-the-audio-with-dropbox">Uploading the audio with Dropbox</h2>
<p>You can’t upload your new audio file to Huffduffer, because Huffduffer wants a <em>link</em> to the file, not the file itself.</p>
<p><strong>If you’re a Dropbox user, you can easily get the file onto the internet if you drop it into Dropbox’s <code>Public/</code> folder.</strong> Then, you can right click and “Copy Public Link” to get the link you’ll use on Huffduffer.</p>
<p>Finally, use the “RSS” link on Huffduffer to get your podcast into your favorite podcast player.</p>
<p>Sadly, as a podcast, you miss out on the (frankly awesome) pictures in this talk. And it doesn’t work well with code- or demo-heavy talks (though you might still be able to get the gist of it).</p>
<p>But sometimes, it’s not a choice between listening to a talk or watching a talk. It’s between listening to a talk and not experiencing it at all. If those are your options, audio-only seems like a decent compromise.</p>
<h2 id="putting-it-all-together">Putting it all together</h2>
<p>So, here’s that process again:</p>
<ol>
<li>Sign up for a free <a href="https://huffduffer.com">Huffduffer</a> account.</li>
<li>Install <code>youtube-dl</code>.</li>
<li>Install <code>ffmpeg</code>.</li>
<li>Download the talk’s audio with <code>youtube-dl -x <url_to_talk_video></code>.</li>
<li>Toss the audio file into <code>~/Dropbox/Public</code>, or somewhere else that’s publicly accessible.</li>
<li>Click “Huffduff it,” and paste the link to your new audio file.</li>
<li>Listen to the new episode of your very own conference podcast!</li>
</ol>
<p>If you’re a fan of podcasts, give this a try. It’s <em>really</em> nice to have conference talks pop up where you’re already listening.</p>
tag:www.justinweiss.com,2015-07-15:/articles/a-web-server-vs-an-app-server/A web server vs. an app server2015-07-15T07:13:18Z2015-07-15T07:13:18Z<p>When you research how to deploy your Rails app, you’ll see a lot of names: <a href="https://httpd.apache.org">Apache</a>, <a href="http://unicorn.bogomips.org">Unicorn</a>, <a href="http://puma.io">Puma</a>, <a href="https://www.phusionpassenger.com">Phusion Passenger</a>, <a href="http://nginx.org">Nginx</a>, <a href="http://rainbows.bogomips.org">Rainbows</a>, and many more. They all seem to fit under the “deploying Rails” category of software, but there’s a key difference between them. Some are “web servers,” and others are “app servers.”</p>
<p><strong>Once you understand which is which, and where each category fits in your system, deployment will make a lot more sense.</strong> But the categories aren’t always clear.</p>
<p>What’s a web server, and how is it different than an app server? Can you use one without the other? And where does <a href="https://rack.github.io">Rack</a> fit in?</p>
<h2 id="whats-a-web-server">What’s a web server?</h2>
<p><strong>A <em>web server</em> is a program that takes a request to your website from a user and does some processing on it. Then, it might give the request to your Rails app.</strong> Nginx and Apache are the two big web servers you’ll run into.</p>
<p>If the request is for something that doesn’t change often, like CSS, JavaScript, or images, your Rails app probably doesn’t need to see it. The web server can handle the request itself, without even talking to your app. It’ll usually be faster that way.</p>
<p>Web servers can handle SSL requests, serve static files and assets, compress requests, and do lots of other things that almost every website needs. And if your Rails app <em>does</em> need to handle a request, the web server will pass it on to your app server.</p>
<h2 id="whats-an-app-server">What’s an app server?</h2>
<p><strong>An <em>app server</em> is the thing that actually runs your Rails app.</strong> Your app server loads your code and keeps your app in memory. When your app server gets a request from your web server, it tells your Rails app about it. After your app is done handling the request, the app server sends the response back to the web server (and eventually to the user).</p>
<p>You can run most app servers by themselves, without a web server in front of it. That’s probably what you do in development mode! <strong>In production, though, you’ll usually have a web server in front.</strong> It’ll handle multiple apps at once, render your assets faster, and deal with a lot of the processing you’ll do on every request.</p>
<p>There are a <em>ton</em> of app servers for Rails apps, including Mongrel (which isn’t used much anymore), Unicorn, Thin, Rainbows, and Puma. Each has different advantages and different philosophies. But in the end, they all accomplish the same thing – keeping your Rails app running and handling requests.</p>
<h2 id="what-about-passenger">What about Passenger?</h2>
<p><a href="https://www.phusionpassenger.com">Phusion Passenger</a> is a little unique. In “standalone mode,” it can act just like an app server. <strong>But it can also be built right into a web server, so you don’t <em>need</em> a separate app server to run your Rails apps.</strong></p>
<p>This can be really convenient. Especially if you’re planning to run a bunch of apps and don’t want to spend time setting up an app server for each one. After installing Passenger, you just point the web server directly at your Rails app (instead of an app server), and your Rails app will start handling requests!</p>
<p><strong>Passenger is a nice option, but having a separate app server can be still be good.</strong> Keeping the app server separate gives you the flexibility to choose an app server that best fits your needs, and you can run and scale it on its own. Still, I’m going to try it again the next time I deploy a new small app. I’m hoping it’ll make it easier to deploy future apps to the same server.</p>
<h2 id="what-about-rack">What about Rack?</h2>
<p><a href="https://rack.github.io">Rack</a> is the magic that lets any of these app servers run your Rails app. (Or Sinatra app, or Padrino app, or…)</p>
<p>You can think of Rack as a common language that Ruby web frameworks (like Rails) and app servers both speak. Because each side knows the same language, it means Rails can talk to Unicorn and Unicorn to Rails, without having either Rails or Unicorn know anything about the other.</p>
<h2 id="how-do-they-relate">How do they relate?</h2>
<p>So, how does this all fit together?</p>
<p>Out of these pieces, a web request will hit your web server first. If the request is something Rails can handle, the web server will do some processing on the request, and hand it off to the app server. The app server uses Rack to talk to your Rails app. When your app is done with the request, your Rails app sends the response back through the app server and the web server to the person using your app.</p>
<p>More specifically, Nginx might pass a request to Unicorn. Unicorn gives the request to Rack, which gives it to the Rails router, which gives it to the right controller. Then, your response just goes back through the other way.</p>
<hr>
<p>This overview might be simplified. <strong>But even just knowing these categories will help you put the software you run into into the right mental buckets.</strong></p>
<p>After you understand how app servers and web servers fit together, it’ll be a lot easier to debug server problems when you have them. You’ll know all the different places you could look, and how they interact. And once the next interesting app server arrives, it’ll be even easier for you to swap it in!</p>
<p>If you’d like to learn more about how Rails interacts with the web, check this article out: <a href="https://www.justinweiss.com/articles/how-rails-sessions-work/">How Rails Sessions Work</a>.</p>
tag:www.justinweiss.com,2015-07-08:/articles/the-easiest-way-to-get-into-open-source/The easiest way to get into open source2015-07-08T03:23:04Z2015-07-08T03:23:04Z
<p><em>This article is <a href="https://emaren84.github.io/blog/archivers/the-easiest-way-to-get-into-open-source-kor">also available in Korean</a>, thanks to Dohyung Ahn!</em></p>
<p>Thom Parkin made a <a href="http://www.justinweiss.com/blog/2014/10/28/how-to-go-beyond-documentation-and-learn-a-new-library/#comment-1657912979">great point in the comments of an earlier article of mine</a>:</p>
<blockquote>
<p>Great advice. But you missed one very important [final] point. Since this is Open Source, once you have figured out the details of that feature/function where the documentation is a bit light, YOU SHOULD UPDATE THE DOCS AND SUBMIT A PULL REQUEST. In that way the entire community benefits, and you can even gain some “coder cred” for your participation!</p>
</blockquote>
<p><strong>I’m happy Thom mentioned this, because it’s so important</strong>. Fixing documentation is the easiest way to start contributing back to the projects you use and love.</p>
<p>My first contributions to projects like Rails, Rubinius, and Elixir have all been doc fixes. I’ve made small tweaks to make things clearer, explained some things that you could only discover by reading the code, even just fixed broken formatting. These have all been quick, easy ways to help out some big open source projects. Even when they’re my only contributions to a project, they’ve still helped future users, and Future Me. And that’s what open source is all about.</p>
<h2 id="why-documentation-fixes-are-such-a-great-way-to-get-started">Why documentation fixes are such a great way to get started</h2>
<p>Doc fixes are the least intimidating way to contribute to a big project like Rails:</p>
<ul>
<li>
<p><strong>You don’t have to set up the project in order to fix the bug</strong>. Since you’re just updating the documentation, you don’t have to get the tests or the app running. Sometimes, you won’t even have to clone the project to your machine – you can make your change right on GitHub!</p>
</li>
<li>
<p><strong>If the maintainer asks you to make changes to your pull request, they’re usually a matter of wording or taste</strong>. Those kind of changes can be easier to stomach than criticism of your code. And it’s easier for you to make those changes, because you don’t have to update tests or code, just words.</p>
</li>
<li>
<p><strong>Documentation is <em>hard</em> for a project maintainer, so updates are appreciated</strong>. Often, authors are too close to the code to understand where the confusing parts are. They need other, newer developers to tell them where the docs need help. It takes practice to see your project as a beginner would, and not everyone has built that skill.</p>
</li>
<li>
<p><strong>Finally, you’re starting to build a relationship with the maintainer, with a low-impact change</strong>. You’re not changing the direction of the project, like you would if you were contributing an entire feature. So your change is easier for a maintainer to review, and they’ll usually respond to you more quickly. Your merge request won’t get stuck in the “Is this a good idea?” phase.</p>
</li>
</ul>
<p>As you keep building that relationship, you’ll start to be seen as a reliable contributor. Your pull requests will get reviewed faster, and it’ll be easier for both of you to talk through more complicated feature requests and bug fixes.</p>
<p>They’re easier to start, they’re easier to do, and they tend to get merged more quickly. So why wouldn’t your first contribution be a doc fix?</p>
<h2 id="how-to-start-contributing-back-updated-documentation">How to start contributing back updated documentation</h2>
<p>There’s an important way contributing doc updates is like fixing bugs: <strong>They both rely on being sensitive to things that feel wrong</strong>. You have to pay attention.</p>
<p>When you run into behavior you didn’t expect, it might be time to update the docs. If you have to dive into the code to solve a problem, you might also want to tell other people about it. You should even be sensitive to broken formatting and typos in the documentation you read. If you’re not going to fix it, who will?</p>
<p>Once you have a good idea of where to make the change and how you want to word it, make your change and send a pull request through GitHub.</p>
<p>If you’re still trying to decide on the best way to update the docs, open an issue on GitHub. It can be something like this:</p>
<p>“Hey, this was confusing to me. I was thinking of updating it to look something like this: … What do you think? Anything else I should mention?” Together, you can come up with wording that satisfies everyone.</p>
<p>Finally, don’t be discouraged if you don’t get a response. Big projects have a lot going on, so it’s easy for your contribution to fall through the cracks. <strong>In a week or so, if you still don’t hear from anyone, ask the maintainer again</strong>.</p>
<p>Documentation is often the first thing you encounter when you work with a library, so it’s important that it’s detailed and clear.</p>
<p>So when you’re confused about the code you use, or have to dive into the source, make it easier for the next person. Write a quick update, and contribute it back. It’s the easiest way I know of to become an open source contributor.</p>
<p><em>This article was originally sent to the people on <a href="/list">my list</a>. To read more like it, <a href="/list">sign up here!</a></em></p>
tag:www.justinweiss.com,2015-06-30:/articles/creating-easy-readable-attributes-with-activerecord-enums/Creating easy, readable attributes with ActiveRecord enums2015-06-30T07:39:15Z2015-06-30T07:39:15Z
<p>Imagine a question that can be either “pending”, “approved”, or “flagged”. Or a phone number that’s a “home”, “office”, “mobile”, or “fax” (if it’s 1982).</p>
<p><strong>Some models call for this kind of data.</strong> An attribute that can have only one of a few different values. And that set of values almost never changes.</p>
<p>It’s a situation where, if it were plain Ruby, you’d just use a symbol.</p>
<p>You could create a PhoneNumberType or QuestionStatus model and a <code>belongs_to</code> relationship to hold these values, but that doesn’t seem worth it. You could stuff them in a yaml file, but now you have to look in a totally different place to figure out what your object can do.</p>
<p>In 4.1, Rails took a stab at solving this problem with <a href="http://api.rubyonrails.org/v4.1.0/classes/ActiveRecord/Enum.html">ActiveRecord enums</a>.</p>
<h2 id="a-few-values-in-the-model">A few values, in the model</h2>
<p>ActiveRecord enums are pretty easy. You give your model an <code>integer</code> column:</p>
<figure class="code"><pre class="highlight"><code class="language-sh">bin/rails g model phone number:string phone_number_type:integer</code>
</pre></figure>
<p>List the values that attribute can take:</p>
<figure class="code"><figcaption><span>app/models/phone.rb</span></figcaption><pre class="highlight"><code class="language-ruby"><span class="k">class</span> <span class="nc">Phone</span> <span class="o"><</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
<span class="n">enum</span> <span class="ss">phone_number_type: </span><span class="p">[</span><span class="ss">:home</span><span class="p">,</span> <span class="ss">:office</span><span class="p">,</span> <span class="ss">:mobile</span><span class="p">,</span> <span class="ss">:fax</span><span class="p">]</span>
<span class="k">end</span></code>
</pre></figure>
<p>And now you can deal with strings instead of numbers.</p>
<p>Instead of this:</p>
<figure class="code"><pre class="highlight"><code class="language-irb"><span class="gp">irb(main):001:0></span><span class="w"> </span><span class="no">Phone</span><span class="p">.</span><span class="nf">first</span><span class="p">.</span><span class="nf">phone_number_type</span>
<span class="p">=></span> <span class="mi">3</span></code>
</pre></figure>
<p>You’ll see this:</p>
<figure class="code"><pre class="highlight"><code class="language-irb"><span class="gp">irb(main):002:0></span><span class="w"> </span><span class="no">Phone</span><span class="p">.</span><span class="nf">first</span><span class="p">.</span><span class="nf">phone_number_type</span>
<span class="p">=></span> <span class="s2">"fax"</span></code>
</pre></figure>
<p>You can <em>change</em> that attribute using either strings or ints:</p>
<figure class="code"><pre class="highlight"><code class="language-irb"><span class="gp">irb(main):003:0></span><span class="w"> </span><span class="n">phone</span><span class="p">.</span><span class="nf">phone_number_type</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">phone</span><span class="p">.</span><span class="nf">phone_number_type</span>
<span class="p">=></span> <span class="s2">"office"</span>
<span class="gp">irb(main):004:0></span><span class="w"> </span><span class="n">phone</span><span class="p">.</span><span class="nf">phone_number_type</span> <span class="o">=</span> <span class="s2">"mobile"</span><span class="p">;</span> <span class="n">phone</span><span class="p">.</span><span class="nf">phone_number_type</span>
<span class="p">=></span> <span class="s2">"mobile"</span></code>
</pre></figure>
<p>Or even using a bang method:</p>
<figure class="code"><pre class="highlight"><code class="language-irb"><span class="gp">irb(main):005:0></span><span class="w"> </span><span class="n">phone</span><span class="p">.</span><span class="nf">office!</span>
<span class="p">=></span> <span class="kp">true</span>
<span class="gp">irb(main):006:0></span><span class="w"> </span><span class="n">phone</span><span class="p">.</span><span class="nf">phone_number_type</span>
<span class="p">=></span> <span class="s2">"office"</span></code>
</pre></figure>
<p>You get methods for asking if your attribute has some specific value:</p>
<figure class="code"><pre class="highlight"><code class="language-irb"><span class="gp">irb(main):007:0></span><span class="w"> </span><span class="n">phone</span><span class="p">.</span><span class="nf">office?</span>
<span class="p">=></span> <span class="kp">true</span></code>
</pre></figure>
<p>And you can find <em>all</em> objects with the value you’re looking for:</p>
<figure class="code"><pre class="highlight"><code class="language-irb"><span class="gp">irb(main):008:0></span><span class="w"> </span><span class="no">Phone</span><span class="p">.</span><span class="nf">office</span>
<span class="go"> Phone Load (0.3ms) SELECT "phones".* FROM "phones" WHERE "phones"."phone_number_type" = ? [["phone_number_type", 1]]</span></code>
</pre></figure>
<p>If you want to see all the different values you can use, along with the numbers they’re associated with, use the <code>phone_number_types</code> class method:</p>
<figure class="code"><pre class="highlight"><code class="language-irb"><span class="gp">irb(main):009:0></span><span class="w"> </span><span class="no">Phone</span><span class="p">.</span><span class="nf">phone_number_types</span>
<span class="p">=></span> <span class="p">{</span><span class="s2">"home"</span><span class="o">=></span><span class="mi">0</span><span class="p">,</span> <span class="s2">"office"</span><span class="o">=></span><span class="mi">1</span><span class="p">,</span> <span class="s2">"mobile"</span><span class="o">=></span><span class="mi">2</span><span class="p">,</span> <span class="s2">"fax"</span><span class="o">=></span><span class="mi">3</span><span class="p">}</span></code>
</pre></figure>
<p>Which makes them easy to put into an HTML form:</p>
<figure class="code"><figcaption><span>app/views/phones/_form.html.erb</span></figcaption><pre class="highlight"><code class="language-erb"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"field"</span><span class="nt">></span>
<span class="cp"><%=</span> <span class="n">f</span><span class="p">.</span><span class="nf">label</span> <span class="ss">:phone_number_type</span> <span class="cp">%></span><span class="nt"><br></span>
<span class="cp"><%=</span> <span class="n">f</span><span class="p">.</span><span class="nf">select</span> <span class="ss">:phone_number_type</span><span class="p">,</span> <span class="no">Phone</span><span class="p">.</span><span class="nf">phone_number_types</span><span class="p">.</span><span class="nf">keys</span> <span class="cp">%></span>
<span class="nt"></div></span></code>
</pre></figure>
<p><img src="/images/posts/enum.png" class="img-responsive" width="238" height="234" alt="An enum in a form"></p>
<h2 id="a-few-things-to-watch-for">A few things to watch for</h2>
<p>Enums aren’t without their problems, though. You have to keep a few things in mind if you don’t want to run into trouble later on.</p>
<p><strong>When you define an enum, order matters.</strong> So if you go back to your code and decide that those values should really be in alphabetical order:</p>
<figure class="code"><figcaption><span>app/models/phone.rb</span></figcaption><pre class="highlight"><code class="language-ruby"><span class="k">class</span> <span class="nc">Phone</span> <span class="o"><</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
<span class="n">enum</span> <span class="ss">phone_number_type: </span><span class="p">[</span><span class="ss">:fax</span><span class="p">,</span> <span class="ss">:home</span><span class="p">,</span> <span class="ss">:mobile</span><span class="p">,</span> <span class="ss">:office</span><span class="p">]</span>
<span class="k">end</span></code>
</pre></figure>
<p>Your phones won’t have the right types anymore. You can get around this by telling <code>enum</code> which number goes with which value:</p>
<figure class="code"><figcaption><span>app/models/phone.rb</span></figcaption><pre class="highlight"><code class="language-ruby"><span class="k">class</span> <span class="nc">Phone</span> <span class="o"><</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
<span class="n">enum</span> <span class="ss">phone_number_type: </span><span class="p">{</span><span class="ss">fax: </span><span class="mi">3</span><span class="p">,</span> <span class="ss">home: </span><span class="mi">0</span><span class="p">,</span> <span class="ss">mobile: </span><span class="mi">2</span><span class="p">,</span> <span class="ss">office: </span><span class="mi">1</span><span class="p">}</span>
<span class="k">end</span></code>
</pre></figure>
<p>But really, your best option is to keep the order consistent.</p>
<p>A bigger problem is what to do outside the Rails world. Even though Rails sees these enum values as strings, they’re just numbers inside your database. <strong>So someone looking at your raw data will have <em>no</em> idea what those numbers mean.</strong> This also means that every app that reads that database will have to know that enum mapping.</p>
<p>You could dump your enum mapping to the database or a yaml file if you really needed other people to see them. But that’s not DRY, because now you’re defining your enum in two places. And if you’re going that far, it might be better to do what we were avoiding in the beginning: create a totally separate model and association, so that a Phone would <code>belong_to</code> a PhoneNumberType.</p>
<p>But if you’re keeping it simple, enums are a great way to start.</p>
<p><strong>P.S. In case you missed it, <em>Practicing Rails</em> is going to be included in the <a href="http://rubybookbundle.com/?c=jw">Ruby Book Bundle</a>, launching on Monday, July 6. Get it and 5 other great Ruby books at a huge discount!</strong></p>
tag:www.justinweiss.com,2015-06-23:/articles/how-to-preload-rails-scopes/How to preload Rails scopes2015-06-23T20:17:34Z2015-06-23T20:17:34Z
<p><em>This article is <a href="http://kydonia.net/blog/npmachine/2016/11/25/How-to-Preload-Rails-Scopes.html">also available in Korean</a>, thanks to Soonsang Hong!</em></p>
<p>Rails’ <a href="http://guides.rubyonrails.org/active_record_querying.html#scopes">scopes</a> make it easy to find the records you want:</p>
<figure class="code"><figcaption><span>app/models/review.rb</span></figcaption><pre class="highlight"><code class="language-ruby"><span class="k">class</span> <span class="nc">Review</span> <span class="o"><</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
<span class="n">belongs_to</span> <span class="ss">:restaurant</span>
<span class="n">scope</span> <span class="ss">:positive</span><span class="p">,</span> <span class="o">-></span> <span class="p">{</span> <span class="n">where</span><span class="p">(</span><span class="s2">"rating > 3.0"</span><span class="p">)</span> <span class="p">}</span>
<span class="k">end</span></code>
</pre></figure>
<figure class="code"><pre class="highlight"><code class="language-irb"><span class="gp">irb(main):001:0></span><span class="w"> </span><span class="no">Restaurant</span><span class="p">.</span><span class="nf">first</span><span class="p">.</span><span class="nf">reviews</span><span class="p">.</span><span class="nf">positive</span><span class="p">.</span><span class="nf">count</span>
<span class="go"> Restaurant Load (0.4ms) SELECT `restaurants`.* FROM `restaurants` ORDER BY `restaurants`.`id` ASC LIMIT 1
(0.6ms) SELECT COUNT(*) FROM `reviews` WHERE `reviews`.`restaurant_id` = 1 AND (rating > 3.0)
</span><span class="p">=></span> <span class="mi">5</span></code>
</pre></figure>
<p>But if you’re not careful with them, you’ll seriously hurt your app’s performance.</p>
<p>Why? <strong>You can’t really preload a scope.</strong> So if you tried to show a few restaurants with their positive reviews:</p>
<figure class="code"><pre class="highlight"><code class="language-irb"><span class="gp">irb(main):001:0></span><span class="w"> </span><span class="n">restauraunts</span> <span class="o">=</span> <span class="no">Restaurant</span><span class="p">.</span><span class="nf">first</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="gp">irb(main):002:0></span><span class="w"> </span><span class="n">restauraunts</span><span class="p">.</span><span class="nf">map</span> <span class="k">do</span> <span class="o">|</span><span class="n">restaurant</span><span class="o">|</span>
<span class="gp">irb(main):003:1*</span><span class="w"> </span><span class="s2">"</span><span class="si">#{</span><span class="n">restaurant</span><span class="p">.</span><span class="nf">name</span><span class="si">}</span><span class="s2">: </span><span class="si">#{</span><span class="n">restaurant</span><span class="p">.</span><span class="nf">reviews</span><span class="p">.</span><span class="nf">positive</span><span class="p">.</span><span class="nf">length</span><span class="si">}</span><span class="s2"> positive reviews."</span>
<span class="gp">irb(main):004:1></span><span class="w"> </span><span class="k">end</span>
<span class="go"> Review Load (0.6ms) SELECT `reviews`.* FROM `reviews` WHERE `reviews`.`restaurant_id` = 1 AND (rating > 3.0)
Review Load (0.5ms) SELECT `reviews`.* FROM `reviews` WHERE `reviews`.`restaurant_id` = 2 AND (rating > 3.0)
Review Load (0.7ms) SELECT `reviews`.* FROM `reviews` WHERE `reviews`.`restaurant_id` = 3 AND (rating > 3.0)
Review Load (0.7ms) SELECT `reviews`.* FROM `reviews` WHERE `reviews`.`restaurant_id` = 4 AND (rating > 3.0)
Review Load (0.7ms) SELECT `reviews`.* FROM `reviews` WHERE `reviews`.`restaurant_id` = 5 AND (rating > 3.0)
</span><span class="p">=></span> <span class="p">[</span><span class="s2">"Judd's Pub: 5 positive reviews."</span><span class="p">,</span> <span class="s2">"Felix's Nightclub: 6 positive reviews."</span><span class="p">,</span> <span class="s2">"Mabel's Burrito Shack: 7 positive reviews."</span><span class="p">,</span> <span class="s2">"Kendall's Burrito Shack: 2 positive reviews."</span><span class="p">,</span> <span class="s2">"Elisabeth's Deli: 15 positive reviews."</span><span class="p">]</span></code>
</pre></figure>
<p>Yep, that’s an <a href="http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations">N+1 query</a>. The biggest cause of slow Rails apps.</p>
<p><strong>You can fix this pretty easily, though, if you think about the relationship in a different way.</strong></p>
<h2 id="convert-scopes-to-associations">Convert scopes to associations</h2>
<p>When you use the Rails association methods, like <code>belongs_to</code> and <code>has_many</code>, your model usually looks like this:</p>
<figure class="code"><figcaption><span>app/models/restaurant.rb</span></figcaption><pre class="highlight"><code class="language-ruby"><span class="k">class</span> <span class="nc">Restaurant</span> <span class="o"><</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
<span class="n">has_many</span> <span class="ss">:reviews</span>
<span class="k">end</span></code>
</pre></figure>
<p>But if you check out <a href="http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html">the documentation</a>, you’ll see that they can do more. You can pass other parameters to those methods and change how they work.</p>
<p><code>scope</code> is one of the most useful. <strong>It works just like the <code>scope</code> from earlier:</strong></p>
<figure class="code"><figcaption><span>app/models/restaurant.rb</span></figcaption><pre class="highlight"><code class="language-ruby"><span class="k">class</span> <span class="nc">Restaurant</span> <span class="o"><</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
<span class="n">has_many</span> <span class="ss">:reviews</span>
<span class="n">has_many</span> <span class="ss">:positive_reviews</span><span class="p">,</span> <span class="o">-></span> <span class="p">{</span> <span class="n">where</span><span class="p">(</span><span class="s2">"rating > 3.0"</span><span class="p">)</span> <span class="p">},</span> <span class="ss">class_name: </span><span class="s2">"Review"</span>
<span class="k">end</span></code>
</pre></figure>
<figure class="code"><pre class="highlight"><code class="language-irb"><span class="gp">irb(main):001:0></span><span class="w"> </span><span class="no">Restaurant</span><span class="p">.</span><span class="nf">first</span><span class="p">.</span><span class="nf">positive_reviews</span><span class="p">.</span><span class="nf">count</span>
<span class="go"> Restaurant Load (0.2ms) SELECT `restaurants`.* FROM `restaurants` ORDER BY `restaurants`.`id` ASC LIMIT 1
(0.4ms) SELECT COUNT(*) FROM `reviews` WHERE `reviews`.`restaurant_id` = 1 AND (rating > 3.0)
</span><span class="p">=></span> <span class="mi">5</span></code>
</pre></figure>
<p>Now, you can preload your new association with <code>includes</code>:</p>
<figure class="code"><pre class="highlight"><code class="language-irb"><span class="gp">irb(main):001:0></span><span class="w"> </span><span class="n">restauraunts</span> <span class="o">=</span> <span class="no">Restaurant</span><span class="p">.</span><span class="nf">includes</span><span class="p">(</span><span class="ss">:positive_reviews</span><span class="p">).</span><span class="nf">first</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="go"> Restaurant Load (0.3ms) SELECT `restaurants`.* FROM `restaurants` ORDER BY `restaurants`.`id` ASC LIMIT 5
Review Load (1.2ms) SELECT `reviews`.* FROM `reviews` WHERE (rating > 3.0) AND `reviews`.`restaurant_id` IN (1, 2, 3, 4, 5)
</span><span class="gp">irb(main):002:0></span><span class="w"> </span><span class="n">restauraunts</span><span class="p">.</span><span class="nf">map</span> <span class="k">do</span> <span class="o">|</span><span class="n">restaurant</span><span class="o">|</span>
<span class="gp">irb(main):003:1*</span><span class="w"> </span><span class="s2">"</span><span class="si">#{</span><span class="n">restaurant</span><span class="p">.</span><span class="nf">name</span><span class="si">}</span><span class="s2">: </span><span class="si">#{</span><span class="n">restaurant</span><span class="p">.</span><span class="nf">positive_reviews</span><span class="p">.</span><span class="nf">length</span><span class="si">}</span><span class="s2"> positive reviews."</span>
<span class="gp">irb(main):004:1></span><span class="w"> </span><span class="k">end</span>
<span class="p">=></span> <span class="p">[</span><span class="s2">"Judd's Pub: 5 positive reviews."</span><span class="p">,</span> <span class="s2">"Felix's Nightclub: 6 positive reviews."</span><span class="p">,</span> <span class="s2">"Mabel's Burrito Shack: 7 positive reviews."</span><span class="p">,</span> <span class="s2">"Kendall's Burrito Shack: 2 positive reviews."</span><span class="p">,</span> <span class="s2">"Elisabeth's Deli: 15 positive reviews."</span><span class="p">]</span></code>
</pre></figure>
<p>Instead of 6 SQL calls, we only did two.</p>
<p>(Using <code>class_name</code>, you can have multiple associations to the same object. This comes in handy pretty often.)</p>
<h2 id="what-about-duplication">What about duplication?</h2>
<p>There still might be a problem here. The <code>where("rating > 3.0")</code> is now on your Restaurant class. If you later changed positive reviews to <code>rating > 3.5</code>, you’d have to update it twice!</p>
<p>It gets worse: If you also wanted to grab all the positive reviews a person has ever left, you’d have to duplicate that scope over on the User class, too:</p>
<figure class="code"><figcaption><span>app/models/user.rb</span></figcaption><pre class="highlight"><code class="language-ruby"><span class="k">class</span> <span class="nc">User</span> <span class="o"><</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
<span class="n">has_many</span> <span class="ss">:reviews</span>
<span class="n">has_many</span> <span class="ss">:positive_reviews</span><span class="p">,</span> <span class="o">-></span> <span class="p">{</span> <span class="n">where</span><span class="p">(</span><span class="s2">"rating > 3.0"</span><span class="p">)</span> <span class="p">},</span> <span class="ss">class_name: </span><span class="s2">"Review"</span>
<span class="k">end</span></code>
</pre></figure>
<p>It’s not very <a href="http://www.c2.com/cgi/wiki?DontRepeatYourself">DRY</a>.</p>
<p>There’s an easy way around this, though. <strong>Inside of <code>where</code>, you can use the <code>positive</code> scope you added to the Review class:</strong></p>
<figure class="code"><figcaption><span>app/models/restaurant.rb</span></figcaption><pre class="highlight"><code class="language-ruby"><span class="k">class</span> <span class="nc">Restaurant</span> <span class="o"><</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
<span class="n">has_many</span> <span class="ss">:reviews</span>
<span class="n">has_many</span> <span class="ss">:positive_reviews</span><span class="p">,</span> <span class="o">-></span> <span class="p">{</span> <span class="n">positive</span> <span class="p">},</span> <span class="ss">class_name: </span><span class="s2">"Review"</span>
<span class="k">end</span></code>
</pre></figure>
<p>That way, the <em>idea</em> of what makes a review a positive review is still only in one place.</p>
<hr>
<p>Scopes are great. In the right place, they can make querying your data easy and fun. But if you want to avoid N+1 queries, you have to be careful with them.</p>
<p><strong>So, if a scope starts to cause you trouble, wrap it in an association and preload it</strong>. It’s not much more work, and it’ll save you a bunch of SQL calls.</p>
tag:www.justinweiss.com,2015-06-16:/articles/a-guide-to-the-best-beginning-rails-resources/A guide to the best beginning Rails resources2015-06-16T06:19:09Z2015-06-16T06:19:09Z
<p>There are a ton of books, videos, podcasts, and courses for learning Rails. <strong>There’s no way you’d have time to go through them all!</strong> So what’s the best way for an absolute beginner to learn Ruby and Rails? Which resources should you start with, and when?</p>
<h2 id="books-and-websites">Books and websites</h2>
<p><strong>If you’re totally new to programming, the best place to start is <a href="https://pragprog.com/book/ltp2/learn-to-program">Learn to Program</a>, by Chris Pine</strong>. It’s an intro to the core programming ideas you’ll need to know. If you’re planning to learn Ruby and Rails, it’s especially great, because it uses Ruby for all of the examples.</p>
<p><strong>After that, Daniel Kehoe’s <a href="http://learn-rails.com/learn-ruby-on-rails.html">Learn Ruby on Rails</a> is a gentle introduction to Rails</strong>. It teaches you a small part of Rails that will prepare you to take on the harder resources.</p>
<p><strong>If you already know a few other languages or frameworks, check out the free <a href="http://guides.rubyonrails.org/getting_started.html">Getting Started with Rails</a> guide</strong>. It’s a good, short intro to Rails, that will teach you Rails’ concepts and core ideas.</p>
<p>Once you know the basics, there are two bigger books that will fill out your Rails knowledge.</p>
<p><strong><a href="https://pragprog.com/book/rails2/agile-web-development-with-rails">Agile Web Development with Rails</a> is my favorite general Rails book</strong>. It does a good job of teaching first by example, and then by reference. We use it at work to teach devs without Rails experience, and like most of the rest of the <a href="https://pragprog.com">Pragmatic Bookshelf</a> books, it’s very good.</p>
<p><strong>The <a href="https://www.railstutorial.org">Ruby on Rails Tutorial</a> is the other big Rails resource</strong>. It walks you through most of what you need to know to build a fully functional example app. I know a lot of great Rails developers who got started with the Rails Tutorial. And the <a href="https://www.railstutorial.org/book">web version is free</a>, so you can see if it’s your style before you commit to it. If you put in the effort, you’ll get a lot out of it.</p>
<p>Once you’ve gone through one or two of these books, it’s pretty normal to feel confused and frustrated. Especially when you try to put everything together and build your own apps. <strong>My book, <a href="https://www.justinweiss.com/practicing-rails/">Practicing Rails</a>, will help you solve the most painful problems you’ll run into as you start your programming career.</strong> In <em>Practicing Rails</em>, you’ll learn how to debug your code when it breaks, pick up some processes you can follow to turn the ideas in your head into real features, and discover how to write tests without getting stuck.</p>
<p>While you build your own apps, there are two resources you’ll use more than any others:</p>
<p><strong>The <a href="http://guides.rubyonrails.org">Rails Guides</a> will teach you the most important parts of Rails with documentation and examples</strong>. I go back to these <em>all the time</em>. And they’re always up to date.</p>
<p><strong>When you want to know how to call a Rails method, or even whether a method exists to do what you want to do, you’ll need the official <a href="http://api.rubyonrails.org">Rails API documentation</a></strong>.</p>
<p><em>(There are much better ways of browsing the API documentation, though, and I talk through a few of them in <a href="/practicing-rails-course">one of the lessons in my free email course</a>)</em>.</p>
<p>You can start building simple apps without knowing a whole lot of Ruby, but spending more time learning Ruby will become important, quickly. <strong>And <a href="https://pragprog.com/book/ruby4/programming-ruby-1-9-2-0">Programming Ruby</a> is the best book I’ve found to get comfortable with the language</strong>.</p>
<h2 id="videos-and-guided-courses">Videos and guided courses</h2>
<p>Books and websites are my favorite way to learn new things about Ruby and Rails. But if you prefer watching to reading, there are lots of great screencasts and courses you can check out, too.</p>
<p><strong>If you want a video course to teach you Ruby and Rails, I’ve heard lots of praise for the <a href="https://pragmaticstudio.com">Pragmatic Studio</a> courses</strong>. They sound like a great place to start.</p>
<p><strong>The <a href="http://railscasts.com">RailsCasts</a> haven’t been updated in a few years, but they’ll still show you great answers to common web problems</strong>. The APIs might have changed, but the ideas have stayed pretty much the same. They’re definitely worth watching.</p>
<p><strong>Avdi Grimm’s <a href="http://www.rubytapas.com">Ruby Tapas</a> screencasts will show you fun Ruby code in 5-10 minute videos</strong>. They’re Ruby-focused (rather than Rails-focused), but I always learn a lot from them. You can find a few free sample videos on the site, but they’re all great. It’s really worth subscribing to.</p>
<p><strong>The <a href="https://www.destroyallsoftware.com/screencasts">Destroy All Software</a> screencasts aren’t specifically about Ruby and Rails, but watching them will make you a better developer, whatever your language.</strong></p>
<p><strong>Finally, <a href="https://www.bloc.io">bloc.io</a> is an online bootcamp some readers have recommended</strong>. They pair you with a mentor who can help you with your specific problems when you get stuck.</p>
<p>One-on-one help is great – it can be exactly what you need while you’re learning. If you can’t find a friend or mentor to help you out, <a href="https://www.getdrip.com/3522028/campaigns/3566296/emails/39216/archive">I wrote an email to my list about where you should look</a>. <em>(By the way, you can <a href="/list">sign up here</a> to get helpful emails like that every Friday)</em>.</p>
<h2 id="what-do-i-recommend">What do I recommend?</h2>
<p>I know, that’s still a whole lot of stuff! <strong>My recommendation, if you like reading and already know the programming basics, is to start with <a href="https://pragprog.com/book/ruby4/programming-ruby-1-9-2-0">Programming Ruby</a> and <a href="https://pragprog.com/book/rails4/agile-web-development-with-rails-4">Agile Web Development with Rails</a></strong>. While you read, build some tiny sample apps to try out the things you learn. (You’ll learn more about how to do that <a href="/practicing-rails">in the free sample chapter of Practicing Rails</a>).</p>
<p>Do you have any other recommendations for resources that helped you out? Anything you can’t believe I missed? Comment and tell us all about them!</p>
<p><em>This article was inspired by a question from James on <a href="/advice">my advice page</a>. If you’re stuck on questions about Ruby and Rails, and need some help or advice, <a href="/advice">ask me there</a>!</em></p>
tag:www.justinweiss.com,2015-06-09:/articles/youve-got-the-rails-basics-so-why-do-you-feel-so-star-slow-star/You've got the Rails basics. So why do you feel so slow?2015-06-09T03:56:10Z2015-06-09T03:56:10Z<p>You’re confident about the core ideas behind Rails. You can write working code, no problem. And you’re learning more about code quality, refactoring, writing great tests, and object-oriented design.</p>
<p>By this point, you’re starting to feel like you’re getting it, that you’re on the path to becoming an expert. When you look backwards, you see just how far you’ve come, and you’re pretty happy with your progress.</p>
<p><strong>So why do you feel so slow?</strong> Now that you care about testing, maintainability, and design, it feels like it takes you way more time to ship anything!</p>
<p><strong>Is it even <em>possible</em> to ship high quality code quickly?</strong></p>
<h2 id="its-all-part-of-the-process">It’s all part of the process</h2>
<p>This feeling is incredibly common, no matter what you’re learning.</p>
<p><strong>Now that you’re no longer a beginner, you’re starting to see all the different shapes that your code could have.</strong> You have more alternatives to think through whenever you put down a line of code. You have to test edge cases you never recognized before.</p>
<p>You’ve learned lots of helpful skills. But right now, they still take a lot of thought. You have to weigh every decision you make, so you feel comfortable that you’re making the right decision based on the things you’ve learned.</p>
<p>It will get faster, though. <strong>The skills you’ve learned will become more automatic. You’ll build intuition. And you’ll be able to make better decisions more quickly.</strong></p>
<p>Which is nice to know, but it doesn’t help you <em>right now</em>. <strong>So what <em>can</em> you do now, to finish things faster?</strong></p>
<h2 id="take-it-in-stages">Take it in stages</h2>
<p>If you’re obsessed with writing perfect, high-quality, highly-maintainable code every time you put your fingers on the keyboard, you’ll never get anything done.</p>
<p><strong>When I get stuck, I write code the same way I write articles.</strong> You’d start with a rough draft. Maybe sketch out some tests, code, or comments. Or even write some ideas out on paper. At this point, you wouldn’t worry about structure, you’re just using code to clear up the vague ideas you have in your head.</p>
<p><strong>Then, I turn those ideas into a straightforward implementation.</strong> What you might call “The simplest thing that could possibly work.” It’s not perfect, and not even close. But don’t worry about it. Because once the code works, you’ll do a tidying pass. TDD edge cases, refactor obviously bad code, or make names clearer.</p>
<p>These “refined drafts” are usually good enough to ship. But I’ll usually do a few more passes. Not too many, though – you’ll soon start to see diminishing returns. You’ll spend more time cleaning up the code than it’s worth.</p>
<p>Then, if you really want to end up with the cleanest possible code, let it settle for a while. <strong>Come back to it in a few weeks or months, and do another pass at it.</strong> By that time, you’ll know more about your system, and you’ll have learned more about how to write great, highly-maintainable code. So you’ll do an even better job.</p>
<p>Just like writing, that process is:</p>
<ol>
<li>Sketch out a rough outline, draft, or prototype.</li>
<li>Write a simple, unedited, straightforward implementation (often guided by TDD, or written along with tests).</li>
<li>Refine, refactor, and clean up that implementation a little bit.</li>
<li>Let it settle.</li>
<li>Come back to it, and do one more pass.</li>
</ol>
<p>It sounds like a lot more work. <strong>But when you go in stages like this, you’ll move faster, without always second-guessing yourself.</strong> And you won’t end up overthinking decisions between a few just-as-good options.</p>
<p><em>This article was inspired by a question from Topher on <a href="/advice">my advice page</a>. If you’re stuck on questions about Ruby and Rails, and need some help or advice, <a href="/advice">ask me there</a>!</em></p>
tag:www.justinweiss.com,2015-06-01:/articles/3-ways-to-configure-your-ruby-api-wrappers/3 ways to configure your Ruby API wrappers2015-06-01T21:01:05Z2015-06-01T21:01:05Z
<p>When you use Ruby to wrap an API, you have to have a way to configure it. Maybe the wrapper needs a username and secret key, or maybe just a host.</p>
<p>There are a few different ways to handle this. So which one should you choose?</p>
<h2 id="the-easy-global-way">The easy, global way</h2>
<p>You might want your service to act like it’s always around. <strong>No matter where you are in your app, you’d have it ready to use.</strong> Otherwise, you’ll spend three lines of configuring it for every line of using it!</p>
<p>You could make the configuration global, using constants or class attributes:</p>
<figure class="code"><figcaption><span>config/initializers/product_api.rb</span></figcaption><pre class="highlight"><code class="language-ruby"><span class="no">ProductApi</span><span class="p">.</span><span class="nf">root</span> <span class="o">=</span> <span class="s2">"https://staging-host.example.com/"</span>
<span class="no">ProductApi</span><span class="p">.</span><span class="nf">user</span> <span class="o">=</span> <span class="s2">"justin"</span>
<span class="no">ProductApi</span><span class="p">.</span><span class="nf">secret</span> <span class="o">=</span> <span class="s2">"mysecret123"</span></code>
</pre></figure>
<figure class="code"><figcaption><span>app/controllers/products_controller.rb</span></figcaption><pre class="highlight"><code class="language-ruby"><span class="k">def</span> <span class="nf">show</span>
<span class="vi">@product</span> <span class="o">=</span> <span class="no">ProductApi</span><span class="p">.</span><span class="nf">find</span><span class="p">(</span><span class="n">params</span><span class="p">[</span><span class="ss">:id</span><span class="p">])</span>
<span class="k">end</span></code>
</pre></figure>
<p><a href="https://github.com/jpoz/APNS">Lots of gems</a> use this pattern. It’s pretty easy to write, and really easy to use. But it has some big problems:</p>
<ul>
<li>
<p><strong>You can only have one <code>ProductApi</code>.</strong></p>
<p>If you want to use the Product API as two different users, or hit different servers from a single app, you’re out of luck.</p>
</li>
<li>
<p><strong><code>ProductApi</code> has global data that’s easy to accidentally change.</strong></p>
<p>If a thread or a part of your app changed <code>ProductApi.user</code>, everything else using <code>ProductApi</code> would break. And those are <em>painful</em> bugs to track down.</p>
</li>
</ul>
<p>So, class variables have some problems. <strong>What if you configured <em>instances</em> of your Product API class, instead?</strong></p>
<h2 id="what-would-it-look-like-with-initialize">What would it look like with <code>#initialize</code>?</h2>
<p>If you used instances, you’d create and configure your API wrapper when you need it:</p>
<figure class="code"><figcaption><span>app/controllers/products_controller.rb</span></figcaption><pre class="highlight"><code class="language-ruby"><span class="k">def</span> <span class="nf">show</span>
<span class="n">product_api</span> <span class="o">=</span> <span class="no">ProductApi</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span>
<span class="ss">root: </span><span class="s2">"https://staging-host.example.com/"</span><span class="p">,</span>
<span class="ss">user: </span><span class="s2">"justin"</span><span class="p">,</span>
<span class="ss">secret: </span><span class="s2">"mysecret123"</span><span class="p">)</span>
<span class="vi">@product</span> <span class="o">=</span> <span class="n">product_api</span><span class="p">.</span><span class="nf">find</span><span class="p">(</span><span class="n">params</span><span class="p">[</span><span class="ss">:id</span><span class="p">])</span>
<span class="k">end</span></code>
</pre></figure>
<p>Now, you can pass different details to your API whenever you use it. No other methods or threads are using your instance, so you don’t have to worry about it changing without you knowing it.</p>
<p>This seems better. But it’s still not as easy as it should be. <strong>Because you have to configure your API <em>every time</em> you use it.</strong></p>
<p>Most of the time you don’t care how the API is set up, you just want to use it with sane options. But when you’re working with instances, every part of your app that uses the API has to know how to configure it.</p>
<p>But there’s a way to get the convenience of global access, using good defaults, while still being able to change it if you need to.</p>
<p><strong>And this pattern shows up all the time in an interesting place: OS X and iOS development.</strong></p>
<h2 id="how-do-you-get-good-defaults-and-flexibility">How do you get good defaults <em>and</em> flexibility?</h2>
<p>What if you could configure each instance of your API wrapper, but you also had a global “default” instance when you just didn’t care?</p>
<p><strong>You’ll see this “defaultSomething” or “sharedWhatever” pattern all over the iOS and Mac OS SDKs:</strong></p>
<figure class="code"><pre class="highlight"><code class="language-objc"><span class="p">[[</span><span class="n">NSURLSession</span> <span class="nf">sharedSession</span><span class="p">]</span> <span class="nf">downloadTaskWithURL</span><span class="p">:</span><span class="s">@"http://www.google.com"</span><span class="p">];</span>
<span class="p">[[</span><span class="n">NSFileManager</span> <span class="nf">defaultManager</span><span class="p">]</span> <span class="nf">removeItemAtPath</span><span class="p">:...];</span></code>
</pre></figure>
<p>And you can still ask for instances of these classes if you need more than what the default gives you:</p>
<figure class="code"><pre class="highlight"><code class="language-objc"><span class="n">NSURLSession</span> <span class="o">*</span><span class="n">session</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSURLSession</span> <span class="nf">sessionWithConfiguration</span><span class="p">:...];</span>
<span class="n">NSFileManager</span> <span class="n">fileManager</span> <span class="o">=</span> <span class="p">[[</span><span class="n">NSFileManager</span> <span class="nf">alloc</span><span class="p">]</span> <span class="nf">init</span><span class="p">];</span></code>
</pre></figure>
<p>You could build something like that in Ruby, with a <code>default_api</code> class method:</p>
<figure class="code"><figcaption><span>app/controllers/products_controller.rb</span></figcaption><pre class="highlight"><code class="language-ruby"><span class="k">def</span> <span class="nf">show</span>
<span class="vi">@product</span> <span class="o">=</span> <span class="no">ProductApi</span><span class="p">.</span><span class="nf">default_product_api</span><span class="p">.</span><span class="nf">find</span><span class="p">(</span><span class="n">params</span><span class="p">[</span><span class="ss">:id</span><span class="p">])</span>
<span class="k">end</span>
<span class="o">...</span>
<span class="k">def</span> <span class="nf">show_special</span>
<span class="n">special_product_api</span> <span class="o">=</span> <span class="no">ProductApi</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span>
<span class="ss">root: </span><span class="s2">"https://special-product-host.example.com/"</span>
<span class="ss">user: </span><span class="s2">"justin"</span>
<span class="ss">secret: </span><span class="s2">"mysecret123"</span><span class="p">)</span>
<span class="vi">@special_product</span> <span class="o">=</span> <span class="n">special_product_api</span><span class="p">.</span><span class="nf">find</span><span class="p">(</span><span class="n">params</span><span class="p">[</span><span class="ss">:id</span><span class="p">])</span>
<span class="k">end</span></code>
</pre></figure>
<p>And the implementation might look something like this:</p>
<figure class="code"><pre class="highlight"><code class="language-ruby"><span class="k">class</span> <span class="nc">ProductApi</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">root</span><span class="p">:,</span> <span class="n">user</span><span class="p">:,</span> <span class="n">secret</span><span class="p">:)</span>
<span class="vi">@root</span><span class="p">,</span> <span class="vi">@user</span><span class="p">,</span> <span class="vi">@secret</span> <span class="o">=</span> <span class="n">root</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">secret</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">default_api</span>
<span class="vi">@default_api</span> <span class="o">||=</span> <span class="n">new</span><span class="p">(</span>
<span class="ss">root: </span><span class="no">ENV</span><span class="p">[</span><span class="s1">'PRODUCT_API_ROOT'</span><span class="p">],</span>
<span class="ss">user: </span><span class="no">ENV</span><span class="p">[</span><span class="s1">'PRODUCT_API_USER'</span><span class="p">],</span>
<span class="ss">secret: </span><span class="no">ENV</span><span class="p">[</span><span class="s1">'PRODUCT_API_SECRET'</span><span class="p">])</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">find</span><span class="p">(</span><span class="n">product_id</span><span class="p">)</span>
<span class="o">...</span>
<span class="k">end</span>
<span class="k">end</span></code>
</pre></figure>
<p>Here, I used environment variables in <code>default_api</code>, but you could also use <a href="http://www.justinweiss.com/blog/2015/02/24/how-to-configure-your-rails-app-to-ship/">config files</a>. And you could switch the <code>||=</code> to use <a href="http://www.justinweiss.com/blog/2014/12/01/better-globals-with-a-tiny-activesupport-module/">thread- or request-local storage</a> instead.</p>
<p>But this is a decent start.</p>
<hr>
<p>Most gems I’ve seen, like the <a href="https://github.com/sferik/twitter">Twitter</a> gem, will have you configure and create each API object when you need them. This is an OK solution (though I usually see people assigning these to globals <em>anyway</em>).</p>
<p>But if you go one step further, and also use a pre-configured default object, you’ll have a much more comfortable time.</p>