RubyFlow : The Ruby Community Blog

Home   Submit   Sign Up   Log In   leaders   Twitter   RSS Feed  

justinweiss — 51 posts

Where Does Your Code Go?
After you finish the Rails tutorials and start your own app, things get confusing. Like where does your non-CRUD, general logic go? How does grabbing followers from Twitter fit into MVC? Ask two people, and you get four answers. So where do you put your code, and still keep things simple?
What happens when you have a bad abstraction? You have to dig out the API reference every time to understand what that method that clearly should have been named leaderboard is actually called. And whenever you touch the code, something breaks, and you blow the rest of your day trying to debug it (because you tweaked position, but didn’t update score at the same time). So how do you build good abstractions, while staying far away from the bad?
In Rails, you might set data once during a request, but use it in every layer of your app. Which user is making the request? What permissions do they have? Using a Ruby global variable or class variable for this would be bad -- multiple threads could overwrite it, and you'd end up with a huge mess. Instead, you need something that's global, but for just that request.
Each... or else
I love each, but I have a problem with it. How do you handle an empty collection?
If you don’t know the difference between the various Ruby and Rails consoles, you’ll have some problems. Maybe you’ll require a file and get the wrong version. Or a library you thought would be avaliable, wasn’t. So how do you make sure you’re using the right console at the right time?
Have you ever wanted to pass a method to a function that only takes a block? Or figure out which of your object's superclasses broke the method you're trying to call? Those things are easy to do with the method method. Use it well, and you can learn about your dependencies, save yourself hours of debugging, and get your code to the places it needs to be.
When you generate a scaffold in Rails, you'll see the usual respond_to blocks. But some of your actions, like index, don't have them. And those actions, when hit with a bad format, will raise the wrong kind of error. You want to handle bad formats correctly, but littering all your controllers with big respond_to blocks is crazy. It feels un-Rails-ish. So what do you do?
You're working with a brand new library or feature, and you just can't understand the documentation. Maybe it's hard to set up, so you have to bounce between RDocs until you learn how everything fits together. Maybe the documentation doesn't even exist. Or maybe you just learn best by seeing lots of examples. You need some help. But where do you learn how to use a feature, if not its documentation?
Maybe you’ve learned the “what” of Rails, but don’t understand the “why” and the “how.” Maybe you're about to give up on Rails because you just can’t put the pieces together. If you feel like running away when you stare at your newly-generated Rails app, I wrote a book for you.
So, you’re working on a new app, and Rails just generated a test for you. You uncomment it, come up with a name, and you’re ready to write your test, right? But then what? What do you write first? What should your test code look like? If you follow a simple pattern, you’ll turn those stubbed out lines of code into clear, well-structured test cases.
How does Rails handle gems?
If you're not sure how Bundler works, the way gems get pulled into Rails might seem a little too magical. How does adding a line to a Gemfile get code into your app? How do Bundler, Rails, and RubyGems work together to make handling dependencies easy?
There are lots of good places to learn Ruby. But learning isn’t just reading books or watching videos. It’s running head-first into a problem, getting stuck, struggling, getting frustrated, looking things up, having it click, playing around with it, and finally (finally!) getting something working. You have to use the things you learn, or they won’t stick with you. And there are a few great ways I’ve found to do just that.
How do gems work?
Gems might seem magical. But with a little investigation, they’re pretty easy to understand.
Can you learn Rails before learning Ruby? You can, for a little while. But if you want to learn enough Ruby to master Rails, study Ruby on its own. There are tons of Ruby books out there. I counted four shelves the last time I was in a bookstore. A lot of them are good. But there are a few that are in a class of their own. And they'll help you through the entire process of picking up Ruby.
Say you have an Article model, and it could be either a draft or a published article. The published article needs more validation than the draft. What’s the best way to write this? Rails has a lightly documented, little-known feature that makes these problems really easy to handle.
The Rails 4.2 announcement had some interesting news about the upcoming Rails 5: It’s probably going to require Ruby 2.2. Which will make it the first Rails version to take advantage of all the good stuff from Ruby 2. The post mentioned garbage collected symbols and keyword arguments. But to me, one of the most interesting Ruby 2 features is Module#prepend.
Exceptions should be exceptional, they should be unexpected. But how unexpected can an error be if you see it thirty times a day?

Most noisy exceptions fall into a few basic categories. And for each of these categories, you can use some patterns to cut down the noise and make your users happier at the same time.
The first beta of Rails 4.2 was announced last week, and it already looks amazing. I’m really excited to use ActiveJob, Web Console, Adequate Record, and Foreign Key support in my own apps. But the beauty of Rails is in the details. And if you do a little digging, you’ll find some less advertised features that will totally improve your daily work with Rails.
Rails' i18n library is more powerful than it looks. You don't need to only use it for translation. The i18n library is useful anywhere you want to decouple the text you display from the place you display it. I'm going to share a few of the things that we learned that have come in handy, along with a crazy abuse of the library that ended up working out incredibly well for us.
So, you've finished a few Rails tutorials. You might have taken a class or two or watched some screencasts. You've followed along and built a copy of some tutorial apps. It's pretty clear that it's time to move to the next level in your Rails development. Somehow, though, you're stuck. There are tons of books, classes, and videos for people just starting out. But where are all the tutorials for intermediate Rails devs?
You want to test-drive some code, but you're stuck. Maybe you're not totally sure what your object's interface should look like. You might not be sure you can test what you're thinking of building. Or you could be procrastinating, because you just don't feel like writing tests right now. How do you get the benefits of TDD when you don't feel like TDDing?
Memoization is really common in Ruby, but the most popular pattern for memoizing method calls has some major flaws. I wrote about some of the more advanced patterns you can use to memoize your method calls, and show some interesting Ruby tidbits along the way.
The Rails ecosystem moves fast, way too fast for print. If you're like me, you want to learn the most recent version of your frameworks and gems. But the best resources are often a few versions behind. Once you build experience with an older version of a gem, how do you get caught up?
API docs will tell you how to use an API. But when things go wrong, you can be left on your own. Error messages are often incomplete, misleading, or unhelpful. And what are you supposed to do with NoMethodError: undefined method '[]' for nil:NilClass, anyway? When you learn an API, framework, or library, you can't just learn how to use it when things go well. You also need to figure out what to do when it hands an error back.
There's a lot of good, free Rails information around. But as you improve your development skills, it can be hard to find knowledge that's useful to you. If it's too basic, you'll just read about things you already know. Too advanced, and your eyes glaze over and your brain shuts off. You can't just type "intermediate-level Rails blogs" into Google and hope some good sites pop out. To get the information you're looking for, you're going to have to do some digging.
Last week, I wrote about methods with consistent return values, and how they'll make your code simpler. But how does that happen? Why does the right refactoring make your code easier to work with? What makes good abstraction good, and bad abstraction bad? I mean, you can’t just blindly rearrange your code and end up with quality software. If you can learn why these techniques work, you’ll be better able to understand where your code needs help. And you’ll be able to use the right tools where they matter the most.
Your current_user method returns a User, except when there is no user and it returns nil. A search method returns an Array of results, unless there’s only one result, and it returns just that result instead. Seems reasonable, right? Maybe even convenient! But soon, these decisions will bury your code under a mountain of if statements. There is a way to prevent this, though, and all it takes is a little thoughtfulness.
After you build a few Rails apps, you'll begin to have some preferred ways of working with them. Maybe you always want to use awesome_print in your Rails consoles. Or you might want rails new to create projects that use rspec instead of minitest. Sure, it's only a little annoying to have to specify these preferences each time you run a command. But they're easy to forget. With a few small tweaks, you can have these commands remember your preferences, so you won't have to.
Angular vs Ember. RSpec vs Minitest. Haml vs Slim vs ERB. You have so many choices to make when you start a new project. There are vocal defenders on each side. And soon you realize that you could have started your project in the time you’ve wasted reading that fourth tutorial or 30-comment thread about whether Sass is better than Less. How can you choose the right library, so you can start writing actual code?
The culture of testing is one of the best things about the Rails community. But if you’re coming from a place where you weren’t testing at all, TDD can be especially hard to learn. It’s clear that you can’t really go from zero to TDD in a single step. So, what do you do? How can you learn TDD without being overwhelmed?
While you’re building software, there will be things that will frustrate you every time you have to write them. Bits of code that look ugly. Or those lines you can never quite remember how to write, so you find an example somewhere else in your codebase to copy and paste. These break your flow! So it’s important to recognize them, and make them more convenient.
When you read Rails blogs and books, or watch conference talks, you’ll learn a lot about making your models skinnier. These techniques are awesome, because your models will get too big or complex to handle. But do you really want to go as far as having your models only responsible for persistence, associations, and validations? How do you decide which logic should stay in your ActiveRecord models, anyway?
There’s never enough time to learn everything you want. Books and screencasts are great, but they take time and focus. And doing the dishes, commuting to work, and walking the dog can get boring. It’s nice to have those moments to think or relax. But most of the time, I want to take advantage of those minutes of boredom and learn something!
That giant mess of if statements keeps staring you in the face. You feel like you should be able to simplify it, except for that Business Logic that keeps getting in the way. For example, say you have a sales platform where you build Quotes, which have many LineItems. Except, you can have a quote with duplicate line items if they’re ads, but if you have multiple websites, you have to sum the prices together and have it show up as a single line item. Oh and also, if you buy a website and already have five ads in your quote, you have to give them a 20% discount on the website.

I can hear you throwing your laptop through the window from all the way over here.
I’ve written a lot about TDD. So, it’s no surprise that when I published my last article at almost the exact minute David Heinemeier Hansson mentioned TDD during his RailsConf keynote, I got some questions: Do you agree with DHH’s opinions on TDD? Do you still recommend TDD? If not, what should I do instead?
A reader had a question about getting started with TDD, so I answered it.
At some point in your Rails career, you’ll run into a controller that’ll make you want to give up programming forever. As great as it would be to just close your eyes and pretend it doesn’t exist, someday you’ll have to fix a bug in one of these controllers. And, being a good software developer, you want to leave the code better than you found it. But how do you refactor it, especially if you don't have good tests to rely on?
If you need something done in Ruby, a gem for it probably exists. Well, a dozen gems for it probably exist. Some of them are elegant, featureful, and well-maintained, and others were written to solve one use case the author ran into that one time. You have lots of gems to choose from, so how do you choose the right one? This choice is important — by the time you regret adding a gem to your project, it’s painful to change back.
Partial caching is a great way to get some major page speed improvements without a lot of work. But if you forget a touch: true on one of your associations, or your template dependencies aren’t working right, your cached partials won’t get updated. Rails' development environment usually runs with caching disabled, so you'll need a simple way of enabling caching temporarily to investigate and reproduce your caching bugs.
You know what you want to do, but your code just isn't cooperating. Maybe it has a few too many levels of indentation, or chains a half dozen methods, or looks asymmetrical. Whatever it is, something just feels off. You could ignore it -- I mean, you have a backlog full of features you still want to write, and it's really not that bad. But that would be a mistake: Your code is trying to tell you something, and you don't want to miss it.
Last week, I talked about three conventions that can help you beat procrastination and get your new Rails project started. But you still have a tough choice to make. Which code do you write first? Authentication? The part that talks to Twilio? And how would you even begin to work on the forum post recommender engine? Yep, at some point you actually have to write the code, and to do that, you need a place to start.
You’ve just typed rails new on your next project. Now what? Where do you start? There are tons of decisions you have to make up front, and it’s easy to feel lost, and procrastinate, and get frustrated, and never finish your app.
“Don’t Repeat Yourself” is one of the most valuable ideas from one of the most valuable books I read during my software development career. If you can refactor away duplicate code, you will produce more general, more stable code. When you start DRY-ing up your code, though, you’ll start to run into some problems: code that doesn’t handle edge cases well, code that’s too generalized and hard to read, or code that’s hard to find. If refactoring toward DRYness doesn’t work all the time, how do you know when you should refactor?
Good developers know they should test their code. Too often, though, the tests get skipped, rushed through, or never started. There are some really common traps I’ve seen people fall into, and they’ll kill your motivation to test every time.
Searching, sorting, and filtering in Rails controllers can be a pain. ElasticSearch and Solr are great, high-powered solutions, but are really big dependencies for a small app. Luckily, Rails includes scopes, which can provide you with a lot of what you need for simple searching, filtering, and sorting. If you take advantage of scope chaining, you can build the features you want without taking on big dependencies or writing a bunch of repetitive search code yourself.
I’ve heard from some people that are worried about breaking apart large Rails views into smaller partials: How much time does rendering a partial really take? Will the performance impact of calling the partials outweigh the benefits in code readability?

Here's a benchmark to get a sense of how much more expensive partial rendering can be, and whether it matters.
While you’re writing your Rails app, you might run into a problem that you could solve more easily with a different data store. For example, you might have a leaderboard that ranks users by the number of points they got for answering questions on your site. With Redis Sorted Sets, a lot of the implementation is done for you. Awesome! But where do you put the code that interacts with Redis?
Writing code feels so much easier than writing tests for it, and does that one-line method really need to be tested, anyway? But soon, your code is only 20% covered by tests, and any change you make to your code feels like trying to replace the middle layer of a house of cards without knocking the whole thing over. This isn’t a skill failure. It’s a process failure. With a few changes in how you write new features, you can protect your code without your tests slowing you down.
You’ve started a new project and it’s time for your code to depend on a third-party service. It could be something like ElasticSearch, Resque, a billing provider, or just an arbitrary HTTP API. You’re a good developer, so you want this code to be well tested. But how do you test code that fires off requests to a service that’s totally out of your control?
Robut is a simple bot that connects to a HipChat server using their new XMPP interface. Using simple plugins, it can listen, perform actions, and respond to what's being said. Robut includes some sample plugins, including a hook to the TWSS gem and an Rdio client for queueing and playing music.
Reactive Resource 0.5 has been released, which brings ActiveRecord-style 'has_many', 'has_one', and 'belongs_to' associations to ActiveResource models, provides better support for singleton resources, and fixes other miscellaneous problems I've run into while wrapping REST APIs.