Nick has spoken at a bunch of Ruby and Open-Source conferences including RailsConf, WindyCityRuby, GoRuCo, Ruby Hoedown, Lone Star Ruby Conf, and RubyNation, and he's always interested in speaking about web development, Ruby, Rails, JavaScript, Backbone, and other topics.
A reverse chronological archive of all posts by Nick Gauthier.
Last night I had the best idea for a JavaScript framework. It was going to use the dom with data attributes in a totally unobtrusive way. It would have global repositories for remote data, do caching, and attach controllers to the dom automatically.
This morning, I realized that's pretty much how Angular.js rolls, so I decided to learn the basics.
1. Setup Rails
First, I setup a Rails app as the back-end. I used Rails 4.0.0.beta1. I also decided that since Angular does so much heavy data-a...
Recently, I've been reading Practical Object-Oriented Design in Ruby by Sandi Metz (I highly recommend it!) and it got me thinking more about OO design in Rails. I realized that one of the patterns I've been using synced really well with the messages in the book, and I wanted to share it.
Model Loading Filters
One of the most common Rails controller patterns is the before filter that fetches the record being accessed during member route actions. It looks like this:
class PostController < ...
I've been using Rails 4 (beta) a lot recently. In a previous post we looked at how ActionController::Live can be used with Server-Sent Events, but the problem with that is that there's no way for the client to communicate back to the web server. Enter: WebSockets.
The main issue with implementing WebSockets is that they have to keep their connections open for a long period of time, and when you're only running a small cluster of Rails servers, it eats up potential connections fast. That's wh...
I had a simple problem: one user takes an action, and I want it to be reflected immediately on another user's screen.
There are lots of potential ways to solve this: polling, long polling, websockets, etc. However I had a specific goal in mind: use the stack I already had and keep complexity to a minimum. I didn't want to use websockets because of the extra setup on the server. Nginx just got a websockets proxy patch, but I don't feel like compiling nginx from source on my deployment machine...
In this screencast I cover how to extract reusable pieces of code from a Backbone.js application using Mixins. The style is similar to Ruby on Rails's Concerns in that it encapsulates both instance and class methods.
If you like this screencast, consider buying Mobile Web Patterns with Backbone.js.
In this screencast we go over three different ways of booting your application:
jQuery onReady in the JavaScript file
Application.boot method called from html
Unobtrusive boot based on a data attribute
If you like this screencast, consider buying Mobile Web Patterns with Backbone.js.
All the code is in CoffeeScript, for more information, check out CoffeeScript's web site.
If you're setting up an unsubscribe link for your emails in a Rails application, it's important to make it secure and seamless. We want to have it function properly if the user is not logged in without having them log in first. We also want to make sure it's not easy to forge. The url should be something like this:
http://example.com/unsubscribe/0938745209387452093478530938742509384752
So, we need some way to encode a user's information securely and create a url, then we also need to decode...
This evening I decided to put Ubuntu on my Nexus 7 to see how it performs and what packages are available on ARM. I'm happy to report that Ruby 1.9.3 (p194) and Rails 3.2.9 work perfectly (albeit slowly :-D).
Step 1: Ubuntu
I followed Ubuntu's steps for installation and it worked fine. There was an odd issue connecting via ssh, but I think it was my router. I had to ssh out of the tablet to my desktop before the desktop could ssh to the tablet. iptables was empty on both. Dunno what was u...
Here is a talk I gave at the Baltimore Javascript users group. It is an introduction to backbone.js, featuring about 25 minutes of slides and an hour of live coding an example application.
Live coding starts at 27:47
Check out my ebook, Recipes with Backbone!
The Problem
Non-technical teammates can't run the app. You've got designers, project managers, qa, and more. Whenever developers add a dependency to the project, a lot of hand-holding needs to occur to get everyone setup.
Not everyone is comfortable on the terminal, nor should they be.
go.sh
My first solution to this problem was to place go.sh in the root of the project. This command installed bundler, bundled the project, and ran the server. This worked fine, until the first dependency s...
Using Domino with RSpec is awesome. I'll let the code speak for itself.
We have an html page:
<!doctype html>
<html>
<head>
<title>Domino Rspec</title>
</head>
<body>
<h1>Domino Rspec</h1>
<ul>
<li><span class='name'>John Doe</span> Age <span class='age'>47</span></li>
<li><span class='name'>Jane Doe</span> Age <span class='age'>37</span&g...
var self = this
I see this in a lot of javascript code. The first thing it makes me think of is Avdi Grimm's excellent talk Confident Code. I think that var self = this is an example of "timid code" in javascript. Avdi explains how timid code suffers from a "Lack of certainty" and it "lives in fear ... constantly second-guessing itself ... [and] imposes cognitive load on the reader". I highly recommend you read the slides or watch the video even if you don't code ruby.
Why?
Here's why v...
Background
I was looking at git-deploy and it looks really awesome. But it got me thinking: We have tools like bundler and rack that can handle gem versioning and dependencies, and creating clean interfaces for web applications. Why can't we use those tools for deploying our own code?
I think ruby gems are a great way of packaging code up, and that any code you write should become a gem if it needs to be re-used. Gems are pretty easy to write, and they automatically help you package and ver...
Raphael.js is a cool vector graphic drawing library for javascript. It uses SVG (VML on IE) to draw just about anything, and provides lots of easy helper methods. The coolest thing about SVG is that since it's XML it can be inserted directly into the dom, so every element has its own dom node.
One of my favorite things about Backbone.js is that the only assumption it makes about Views is that they will have a dom element, el. So, I thought it would be really cool if you used a Backbone.js vi...
Today I played around with Ember.js. I wanted to make my own Pomodoro timer, and I figured it would be a good way to try it out.
One of the reasons I'm really excited about Ember is that its goal is to cut down on boilerplate code especially in regards to keeping views up to date.
I'd like to mention that I have no idea whether or not I really did this right. Ember's docs are in a state of flux as the framework has yet to hit 1.0 and so much is changing. Also, I was particularly confused by...
In Ruby on Rails development, we have great gems like Guard that will re-run tests or other tasks based on changing files. I was interested in finding something more lightweight but less configurable and flexible that I could use on smaller projects.
I ended up writing this quick bash script that I put on my path called live:
#/usr/bin/env sh
# Usage "live command"
clear
$*
while inotifywait -qr -e close_write *; do clear; $*; done
This script takes a command as an argument and re-runs ...
Here's a talk I gave at Bmore on Rails (Baltimore's Rails user group). I talk about MVC vs Model 2 and how they apply to Rails. I talk about Frameworks vs Libraries and White Box vs Black box. Also I talk about a theoretical framework I experimented with to try to implement a more object oriented system for dealing with the web in Ruby (based on Rack).
Enjoy.
Today I setup a new development machine. My preferred OS is Xubuntu, which is Ubuntu + XFCE (a light window manager). In the past I've used RVM and have been happy with it, except for one thing: compiling.
I used to use Gentoo, which is a linux distribution in which all software is installed by downloading the source and compiling. This is a brutal and intense introduction to linux, and I learned a hell of a lot using Gentoo in college. However, I feel like I've paid my dues in linux boot ca...
I got a Samsung Galaxy Nexus yesterday and @reillyhawk asked me to share a review. Disclaimer: I've had this device for 20 hours.
It's big, but it's the same weight as my old HTC Incredible (135g vs 130g). It has an extra inch of screen space (4.65" vs 3.7"). The feeling in your hand is like a well balanced sword. Seriously.
It's so big my thumb can't reach the opposite corner with the phone in the crook of my palm. The opposite corner is a common place for non-standard menus. Dear apps: us...
I'm excited to announce that I'm now open for business!
If you don't already know me, let me introduce myself: my name is Nick Gauthier and I am a Ruby and Javascript coder and I specialize in web development with the Rails framework. I particularly enjoy performance-tweaking applications, designing application architecture, and writing clean, object-oriented, and test-driven code. I've spoken at a couple of conferences including RailsConf 2011, and I recently wrote an e-book called Recipes ...
Chris Strom and I have finished our e-book on Backbone JS: "Recipes with Backbone". It is now available at http://recipeswithbackbone.com for $24.The book is targeted at the intermediate to advanced level backbone developer, but that's not to say beginners won't get anything out of it. To quote the site: This is not the definitive guide to Backbone.js. This is not an introduction to Backbone.js. This is the book you read after you read the tutorial. This is the book that teaches you to k...
Gregory Moeck's awesome post Stubbing is Not Enough got my brain back on the subject of mocking. Readers of this blog may note that I had quite a rant against mocking almost a year ago and Gregory posted a response. I think the result of that post and the discussion that ensued was not that mocking and/or stubbing were bad practices, but that when they are applied inappropriately they can quickly deteriorate the tests and the design of an application.After reading Gregory's article, I wanted...
Chris Strom and I have released the alpha of Recipes with Backbone. It's an e-book containing intermediate to advanced design patterns and best practices for Backbone.js. Grab it now for 50% off the list price. You'll get future versions of the book for free when you buy the alpha.http://recipeswithbackbone.comThanks!
Ah yes, the Rails Controller, a source of much contention among Rails developers. So many different ways to manage control flow, load objects, respond in standard and erroneous ways. My opinion up until recently was "I'll just put a bunch of conditionals in there for different situations."Recently, I've been working more on API endpoints and so responding with nice error messages has been more of a priority. I started using Exceptions more throughout my code thanks to Avdi Grimm, and I recen...
EventMachine's asynchronous and evented nature can be pretty tough to test. Here are some simple Test::Unit helpers I use along with a sample example:def eventmachine(timeout = 1) Timeout::timeout(timeout) do EM.run do EM.epoll yield end end rescue Timeout::Error flunk 'Eventmachine was not stopped before the timeout expired' endThis is a helper that runs eventmachine in a timeout so that if it hangs the test suite flunks out after a second. Very handy.def ...
A nice thing about backbone is being able to bind a view render to new data. But sometimes you get new data, but it's not actually new, it's the same data that has not been updated. This will still cause the view to repaint because the event will fire.To combat this, I've started putting signatures on my views.In the initializer for the view:this.signature = "";Then in the render method, I do a reduction on the data that drives the view and compare signatures and decide to paint or not:// Cr...
Backbone is a really interesting framework, and my favorite part so far is the following idea:If you use a callback, you're Doing It WrongThis has held true for me for my development with Backbone so far. When you make data calls to the server, you let the appropriate events notify interested parties when objects are changed or updated or refreshed.However, with non-data operations, callbacks can be really useful. Today, I needed to animate an object, using jQuery's slideUp. I wanted the sli...
I just had a tough time getting Rails 3 to play nice with Backbone JS, and it turned out to be a simple problem with a simple solution. Backbone was not sending the csrf authenticity token embedded in the page when it sent create/update/delete requests, and Rails was destroying the session when it detected the invalid request.Here is all the javascript it took to get Backbone to include the token with all requests:/* alias away the sync method */Backbone._sync = Backbone.sync;/* define a new...
Goal: Make integration tests drier by adding a view abstraction layerRuby on Rails has a bunch of popular of test frameworks, such as:RSpecCucumberTest::UnitSteakBut one common aspect to all of the frameworks, out of the box, is that they're very procedural. Cucumber is designed so that each scenario has a set of steps. There is a single, global, collection of steps. RSpec is global by nature, there are no test classes, just describe blocks.There is no doubt in my mind that these frameworks ...
Stemming from a workflow discussion on twitter featuring @bryanl, @eee_c, @pjb3, @stevenhaddox, and @webandy, I decided to share my workflow. Originally, we were talking about Mac Apps (specifically the paid ones), but that turned into "how do you work". Here are my goals for a good workflow:GoalsEasily navigate applications and contextsMinimize distractionMaximize focusGet work doneEasily navigate applications and contextsI need to be able to quickly get to certain applications in order to ...
Below is a public excerpt from the
recently release RSpec book
:
module Codebreaker
describe Game do
describe "#start" do
it "sends a welcome message" do
output = double('output')
game = Game.new(output)
output.should_receive(:puts).with('Welcome to Codebreaker!')
game.start
end
it "prompts for the first guess"
end
end
end
This example illustrates
what is wrong with standard BDD as practiced today
. Consider the following corr...
GOAL: Provide a Ruby interface for running JSLint on javascript files using v8.require 'jslintrb-v8'puts JSLint.new.check("var x = 5")Will return the string:Error at line 1 character 1: Missing "use strict" statement. var x = 5 Error at line 1 character 10: Missing semicolon. var x = 5Also, all of jslint's configuration options are available in the constructor:JSLint.new(:undef => false, :sub => true)JSLintRB-v8 on GithubJSLintRB-v8 on Rdoc.info
The problem: You have an ActiveRecord model (or any object, really) and you want to output it to json, but you need some specific methods and maybe some processing of its attributes before you can call .to_json.Let's pretend we have the following object:class Widget attr_accessor :id attr_accessor :name attr_accessor :gadgetsendclass Gadget attr_accessor :id attr_accessor :nameendAnd we want this json from a widget:{ id : 'widget-47', name: 'name of widget', children: [ { id ...
These are instructions for setting up a very bare cucumber stack for testing a rich javascript application.All code available here: https://github.com/ngauthier/cucumber-webapp-demoThe following stack is used: Cucumber Capybara Selenium WEBrickFirst, we make our awesome javascript powered webapp:<!DOCTYPE html><html> <head> <script type='text/javascript' src='jquery-1.4.3.min.js'></script> <script type='text/javascript'> $(function() { ...
It's the canonical ruby metaprogramming example. You have this:def large_image image_base + '-large.png'enddef medium_image image_base + '-medium.png'enddef small_image image_base + '-small.png'endAnd you do some dynamic programming to define the methods with similar content:%w(large medium small).each do |size| class_eval %{ def #{size}_image image_base + '-#{size}.png' end }endI have two problems with this pattern:1) The dynamic code is far less readable and clear. It might...
GET /people => List peoplePOST /people => Create personPUT /people => Replace the collectionDELETE /people => Delete the collectionGET /people/:id => List attribute of a personPUT /people/:id => update the attributes of a personPOST /people/:id => create a new collection under a personDELETE /people/:id => Delete a personIn rails, we useindex: GET /people => List peoplecreate: POST /people => Create personshow: GET /people/:id => List attribute of a pers...