This week Ben Orenstein in joined by thoughtbot CEO, Chad Pytel, to discuss thoughbot’s books, online and in-person training programs, other educational products, and the launch of thoughtbot’s new subscription to everything they teach, Learn Prime. They also discuss some changes to apprentice.io, Five Guys, and much more!
Today we’re happy to announce Learn Prime, a subscription service which gives you access to everything we teach. Your monthly $99 subscription gets you ongoing access to all of our books, screencasts, and even all our in-person and online workshops. Our workshops alone are normally over $1,000 when purchased individually!
In addition to our existing materials, we’ve created a new stream of articles only available to subscribers called Learn Bytes. We’ve already published Bytes on using subdomains in Rails, tricks for finding where a method is defined, and faking out a remote service using rack-test, with much more to come.
Subscribers also receive access to something we (humbly) consider the best resource of all: our team. Got a burning Ruby question? Need help testing something tricky? How about another set of eyes on a pull request? Head to our private Campfire room or send an email, and a thoughtbot developer will help you out.
Our goal is to create more great designers and developers. We hope this new subscription service makes our workshops and other learning materials available to even more people.
We’re are also introducing Prime for Teams. For $1999/month your entire team of up to 25 people can get access to everything provided by Prime. That’s less than the cost of your team’s daily pourovers! And for a limited time, as a special launch discount, the price for Prime for Teams is only $1299 per month!
We hope you’ll join the community of people who have already subscribed to Learn Prime. Find out more at Learn.
Searching your gem code, customizing your IRB, dealing with flashes and sessions on a mixed-version load balanced rails upgrade, RTanque, 3.2.13 performance regressions, Chart.js, and other goodness on this edition of Ruby5
By now you’ve seen how awesome NewRelic is for your web apps, but if you develop for mobile phones, you’ve been missing out on those kinds of metrics.
Until now – NewRelic can peer inside your mobile apps and tell you whats going on... before angry customers do. Don’t wait until you start stacking up the 1-star reviews to find out whats going on inside your mobile app... know your apps performance in real time.
When it comes to monitoring your mobile app – visibility is a game changer. And as always, your free account is waiting for you at NewRellic.com
It took two and a half years, but backbone is now at a 1.0 release. If you haven't checked it out yet, you should... there will be at least one question about it on the exam.
Searching Bundled Gems
How do you search through the source of your bundled gems? Jim Gay wrote an article about using The Silver Searcher to do just that.
Stephen Ball wrote this article on customizing your IRB. I particularly like his object.interesting_methods trick. That one's goin' into the act.
How do you take a 7 year old rails codebase, and upgrade it from v2.2 without any downtime? Well, if you can have a load balancer with several app instances, and roll out your upgraded app on just one of them, you can introduce it piecemeal...
Oh... except You can't run Rails versions side by side like that because of session incompatibilities.
This gem helps with that.
You kids today... When I was your age the whole Web was flat! And we liked it! Then came along all your animated gifs and spinners and 'under construction' signs... on and on in an endless progression resulting in reflections and bevels and throbbing jellybeans you all called "web 2.0".... BAH!
Flat is back. Check it out.
Do you have grand plans to take over the world? You can prototype your robot brain here, and battle them against other robot brains.
The premise is simple, and its fun! You subclass an abstract robot brain, and add behavior to a 'tick' method. You decide how to scan when and where to move, where to point your gun, and how much energy to fire with while your opponents do the same. Last robot standing wins.
Rails 3.2.13 Regressions
If you ran like a lemming to upgrade to 3.2.13, you might have seen some problems... here's a recap.
This article is heavily styled and is best viewed at PeepCode!
From the It Just Makes Sense department
As a bootstrapped company, it’s not always clear what the next step is, but an iOS app for viewing PeepCode videos has been one of the longest standing requests we’ve received. Which makes sense! It’s almost as if these devices were perfectly designed for watching PeepCode videos. The new iPhone 5 is the right dimensions for displaying HD video, which is what all our new videos have been filmed in since the end of last year (and some before that).
So we (finally) took the plunge and built an iOS app. We worked with expert iOS developer (and PeepCode author) Alex Vollmer of Radiant Capsule, and while he did most of the heavy lifting we certainly put in a lot of work and learned a lot along the way.
Solving the Progress Bar Problem
Desiging a good progress bar is famously difficult. Given that our audience is technical and speaks MB and GB, we settled on a great solution that works specifically for the content we’re delivering.
We decided to combine a standard progress bar with a numerical percentage. This works well for any videos under 100MB. But large videos might appear to be stalled if we can only show 100 points of progress. If a video is 500MB, it might take a minute or more to download 1/100th of it (5MB) and show progress.
So we also show you the number of MB remaining. This gives visual feedback that’s useful for videos larger than 100MB. The end result is that for any video you’ll download, progress is frequent and keeps you updated.
Delivering Instant Gratification
One of the things we find frustrating about video streaming applications is all the waiting.
Starting an HTTP video stream can involve an API call, requests for 2 metadata files, and another request for a media file…all before you see a single frame of video.
We wanted to improve on that by showing you some progress along the way. So you’ll see an initial spinner when you click the “Play” button on the cover. When the first API call has completed, you’ll be taken to the video player where the video will start to stream.
Splitting progress into two visual steps makes the application feel more responsive than it would if we just sent you directly to the video player where you would have to wait for 5 or 10 seconds. It’s part of the attention we’ve put into the UI of this application to make it enjoyable to use.
Note: Video streams start at low quality while the device figures out what bandwidth is available. If you have a good Internet connection, you’ll see better quality video after a few seconds. We’re working on adding full HD streams to videos, too.
The Value of a Flaky Development Server
It’s not easy to bootstrap a multimedia application that requires client, server, and media.
Due to misbehaving third-party libraries, our first implementation of a video streaming server would sometimes monopolize 100% of the server’s CPU and hang, or never return a response at all. This was bad news for the iOS client application since it couldn’t get the data it needed to start streaming a video.
Or was it? The early flakiness forced Alex to add more error checking code to the iOS client, and better error messages for the user. And it forced us to write the server code to look for timeouts or blank API responses. Overall, it made our code more robust.
And yes, we rewrote the server so it doesn’t use 100% CPU anymore. In fact, it’s been smooth sailing since the launch.
Keeping it Simple
We’ve launched version 1.0 with a simple but straightforward feature set: PeepCode Unlimited subscribers can download or stream any video we’ve published in the last two years. We’re starting with only PeepCode Unlimited subscribers so we can fine-tune our streaming infrastructure and determine what mirrors we need around the world for a top notch download and streaming experience. So far everything has been running very well.
Anyone with a PeepCode account of any kind can use the app to stream previews of current videos.
- The app will remember the playback time of each video you’ve watched. If you have iCloud, it will sync that across all your devices. So you can watch part of Play by Play with Aaron Patterson and Corey Haines on your iPhone, then resume watching on your iPad at the same time in the video.
- We’ve done extensive testing, literally all around the world (Seattle, Melbourne, Kauai, San Francisco). We hope to add video streaming mirrors for an even better experience.
- Stream to your AppleTV with AirPlay. Play by Play looks fantastic on an HDTV.
- Smart download doesn’t drain your battery if you leave the app. It resumes when you’ve re-launched the app and are back in Wi-Fi range. (Our developer tested this by walking down the street until he was out of range).
- Download full quality videos or stream up to half resolution. Our new HD videos look amazing on the iPhone 5!
- We built a custom, self-contained Sinatra server for streaming video. This will make it easier for us to deploy extra streaming or download servers around the world or whenever needed.
- A series of command line scripts together with remote APIs makes it a breeze to encode video for all the necessary formats and copy it to our servers.
We’re proud of this application, our first shipping iOS application. For a 1.0, it covers most of what’s needed for a great mobile experience.
Possibly the best evidence of how useful this application is was how much we started using it in-house! On the bus, at home streamed to an Apple TV, or on a plane. The last three months of rigorous testing and refinement have been a lot of fun.
This episode is sponsored by Top Ruby Jobs
If you're looking for a top Ruby job or for top Ruby talent, then you should check out Top Ruby Jobs. Top Ruby Jobs is a website dedicated to the best jobs available in the Ruby community.
Ruby security alerts displayed on ruby-doc
James Britt, the guy behind ruby-doc.org, realized after the recent security issues discovered in Ruby and Rails that there was no good, central, updated place to find vulnerability disclosures on Ruby. So, ruby-doc.org now sports a vulnerability disclosure banner at the top of the site for recent listings on the National Vulnerability Database for Ruby.
The Inadequate Guide to Rails Security
This week Honeybadger released a blog post explaining all the dumb things we could be doing in our Rails apps that may compromise security. It covers a wide variety of security faux pas, including reusing passwords across users and applications to hidden SQL injection issues in ActiveRecord#sum.
Lightweight Ruby process pooling with XPool
Robert Gleeson released XPool, version 0.9, which is a lightweight Ruby process pool to allow you to distribute work down to separate subprocesses. It's a little like an in-memory Delayed Job, tracking failed work and job distribution for you.
Over the past year I've written the same test a few times.
This test accomplishes what I'm looking for when I write it - verification that my-fn isn't called. However, it doesn't prevent me from future regressions where my-fn is called with 0, 2, or 2+ arguments. After being bitten by this issue a few times I decided to add an argument matching function that will accept any value for the argument at it's index, and any value for all of the arguments at a greater index. This argument matching function is
The following example is similar to what's above, except any call to my-fn will result in a failure
My original intent was to protect against the scenario I described above*; however, what I ended up with is actually flexible enough to allow me to test other situations as well. For example, I've often found myself testing that a log message was written at a certain level, but not being interested in testing the actual message. The logging I'm working with allows a variable number of arguments, so anything& is perfect for verifying that no matter what args are passed in, the tests passes as long as the level is set correctly.
anything& matching function gives me an extra bit of flexibility that can come in handy at times.
*which is similar to verifyZeroInteractions in mockito
I recently ran into some code that forced me to integrate with a Java library. While using the library I found myself wanting to do a bit of interaction testing, which I've historically done with Mockito. As a result, I added the ability to do interaction based tests on mock Java objects, directly in expectations.
Hopefully the code is what you'd expect.
The previous example creates a mock Runnable in an expect-let, expects the
run method to be run, and then calls the run method of the mock. This test is worthless in a real world context, but it's the simplest way to demonstrate the syntax for creating a mock & specifying the interaction.
mock function defined in erajure, a minimal wrapper around mockito. All of the "times" arguments are the same as what's available for function interaction tests, examples can be found here.
Ben is joined by Bryan Helmkamp, the founder of CodeClimate. In Bryan’s second appearance on the podcast, Ben and Bryan discuss the architecture behind CodeClimate, scaling the service, and growing the business. They also discuss speaking at conferences, proposal selection, two factor authentication and adding it to CodeClimate, marketing and content marketing, how to decide what to build and proving that it was worthwhile, strategies for testing at the beginning when you have few users, and Bryan reveals CodeClimate next big upcoming feature.
One a cold winter's morning this raven laid claim to a sunlit cornice. "Nevermore!"
Sinatra is a fantastic lightweight framework for building web services. We’ll use it as the server framework for the HTTP endpoints in our Service Oriented Architecture.
Unlike Rails, Sinatra isn’t all that opinionated on how you set up your application (it has a few sensible defaults), but leaves a lot of open questions on codebase structure, how to test the application, and how to make sure the client is performing as expected.
Sinatra Web Service application structure
A Sinatra application starts as an empty folder. Here’s a directory structure we’ve found works well to add a little organization.
app/ app/helpers app/models app/my_service.rb client/ client/lib/my_client.rb client/my_client.gemspec config/ config/initializers/ config/environment.rb spec/ spec/spec_helper.rb Gemfile Procfile Rakefile config.ru
app directory contains the base Sinatra app, along with any
models. The client dircotory contains the client gem which will allow other applications
to connect to the service.
config has environment settings, yml config files, and
spec directory holds our RSpec test suite.
Building a client gem
For internal (private) services we often build the client directly into the project, the advantage is you can follow the Outward-In development cycles by first building a feature into the client, and then writing request specs that use the client to connect to the web service.
This allows the us to dogfood our client gem and bring it in as the first step of our development process.
To achevie this we need to configure a few things.
1. Set up the project gemfile to use a local copy of the client in test mode
Include the client gem in your test suite.
# Gemfile group :test do gem 'my_client', path: '~/path/to/my_service/client' gem 'webmock' # ... end
2. Use webmock to send all client requests to the Sinatra application
Instead of booting up a localhost webserver every time the test suite is run, lets mount the Sinatra application as a rack app.
# spec/spec_helper.rb RSpec.configure do |config| config.include WebMock::API config.before(:each) do MyClient.base_url = 'http://www.example.com' stub_request(:any, /www.example.com/).to_rack(MyService) end end
3. Use the client in your request specs
MyService as a rack application we can now use the client
gem in our test suite. This allows the client to talk directly to the mounted
# spec/requests/widget_management_spec.rb require 'spec_helper' describe "Widget management" do it "creates a Widget" do # set up fixture data if needed response = MyClient::Widget.create(widget_params) # assert expectations on the response end end
Private gem hosting
To use the client gem in other projects we’ll need to use a private gem hosting service like Gemfury. This will allow us to include the client via gemfile in our other projects.
# Gemfile source 'https://452f6E403CDph10714e41@gem.fury.io/me/' gem 'my_client' source 'https://rubygems.org # ...
- Sinatra is great for creating lightweight services.
- Using Webmock we can test the client directly against the service.
- A private gem repo works well for hosting the shared client.
Written By Harlow Ward
Traditional Backbone.js templates typically interpolate a few values and have a little basic logic, but even the simplest of these templates knows too much. It is the view’s responsibility to manage logic, events, and the relationship with models while the template should simply manage the HTML markup.
Enter the static template. It does not contain any logic or even interpolated values. In fact, a static template does not contain any executable code at all, it is just markup.
A static template and its view might look like this:
Keeping all that logic in the view has several key advantages:
1. Easier to test
Keeping all the logic in the view makes it much easier to test-drive that behavior. This in turn increases the quality of your code and gives you greater confidence to build and refactor.
2. Doesn’t break event bindings
With traditional templates, re-rendering creates new DOM elements which requires re-binding events. The DOM for static templates, on the other hand, is only rendered once. This spells the end of your event re-binding troubles.
3. Faster re-rendering
Static templates can significantly improve your re-rendering speeds. Rendering traditional templates was an all-or-nothing decision. However, By encapsulating all the logic into methods on the view, this becomes a much more granular decision. Arbitrary sections can be ‘re-rendered’ in response to events.
By keeping a strong separation of concerns between your views and templates, you end up with code that is cleaner, more modular, more readable, more performant, and easier to maintain. Give it a try, you will be surprised by the power and simplicity of this approach.
Learn more about Backbone best practices in our book Backbone.js on Rails.
Validate password entropy with StrongPassword gem / easy browser tests with Page Object Pattern and SitePrism gem / RubyGems 2.0.3 released / Visualizing Memory Leaks / Tracking a Memory Leak blog post / Rails status bar via Glimpse gem
This episode is sponsored by New Relic
New Relic is the all-in-one web performance analytics product. It lets you manage and monitor web application performance, from the browser down to the line of code. With Real User Monitoring, New Relic users can see browser response times by geographical location of the user, or by browser type.
Entropy-based password strength checking for Ruby and Rails.
SitePrism gives you a simple, clean and semantic DSL for describing your site using the Page Object Model pattern, for use with Capybara in automated acceptance testing.
RubyGems 2.0.3 released
RubyGems 2.0.3 is a bug-fix release. To update to the latest RubyGems you can run:
gem update --system
Visualizing Memory Leaks
Conrad Irwin shares a patch for Ruby 1.9.3 that makes it easy to visualize all those terrible memory leaks you thought you'd escaped by using a high-level programming language with garbage collection.
Tracking a Memory Leak
Join Nelson Elhage on a thrilling journey deep into memory leak hell. Just remember to resist the temptation to turn and gaze on your love on the way back out.
Add a status bar to your Rails app to get a glimpse of how its working. Use one of the plugins for mysql, monogdb, postgres, redis, and more; or write your own.
We’ve just opened registration for our new online Intermediate Ruby on Rails workshop, which starts Monday, April 1st, 2013 (we’re not kidding).
The workshop is taught by Matt Mongeau, who is an experienced thoughtbot Rails developer as well as the instructor of our Intro to Ruby on Rails workshop.
Over the course of a month you will build a Rails applications alongside Matt, working directly with him on many more complex Rails topics like user authentication, complex data modeling, file uploads, refactoring, and more.
Like all our online workshops, this isn’t just a series of videos; it’s an online workshop where you work directly with Matt getting one-on-one and group support.
Furthermore, when you take an online workshop with thoughtbot, it doesn’t just stop after the initial month. You get ongoing support for any Ruby on Rails questions you may have in the future, from Matt and the rest of the thoughtbot team.
We also have special pricing for groups, so your entire company can take the workshop.
We’d love to have you take this course. You can sign up now and the course begins Monday, April 1st, 2013.
Much has been said about remote work lately. Yahoo! brought it to the fore when CEO Marissa Mayer completely cancelled their remote work policy a few weeks ago. It made mainstream press and quickly raised the ire of David Heinemeier Hansson, whose beliefs about remote work have shaped his life: half of his 37signals co-workers are remote and he too spends half his year working abroad.
At Icelab we don’t have so much a formal policy about remote work (or about anything, really), but instead some simple guiding principles: work with good people to make good things, and as long as we can keep the business running, do whatever we can to help those people lead the lives they want.
I try to embody these principles: I spent the bulk of last year working from the Philippines and Hong Kong – and just this afternoon, I’ll fly off to Tokyo, the first leg in a trip that will see me working from five countries across three continents over the course of this year. Hugh’s done some of this too, also checking in from Tokyo for a month at the start of last year. And in a couple of weeks, David’s heading to Europe for a holiday and can extend it a little while by doing some work over there too.
Having people work from overseas has been no problem at all. In fact, 2012 was our biggest, most productive year yet.
Remote work isn’t all about extending a holiday or seeing the world. It can also be about finding the right space for productivity in everyday life. Even Yahoo! recognised that you can’t be chained to the office, that “occasionally [you] have to stay home for the cable guy,” but this is more a sign of their failure to recognise the intrinsic value in a change of environment. As The Economist argued:
Plenty of evidence suggests that letting employees work from home is good for productivity. It allows them to use their time more efficiently and to spend more time with their families and less fuming in traffic jams or squashed on trains… You can shackle a Yahoo to his desk, but you can’t make him feel the buzz.
We make our offices as comfortable and conducive to productivity as possible, but good work doesn’t always happen from the same place. Good people, on the other hand, are good people everyday, regardless of their location.