giant robots smashing into other giant robots

Written by thoughtbot

lolconomy

Nearby in Open Source

We have a weekly blog post on the state of our gems, which we affectionately call “This Week in Open Source”. My favorite part about it (the reason I started it!) is that we get to thank the contributors publicly and officially.

Today I’d like to expand the thanks just a tiny bit: I’d like to thank people who are building on top of our open source work, extending it beyond our dreams. While I’m at it, I’d also like to highlight some of the non-thoughtbot open source work we build. I call this … Nearby in Open Source.

capybara-screenshot

Matthew O’Riordan (mattheworiordan) built on top of capybara-webkit to give the world capybara-screenshot. It’s pretty slick: any time you have a capybara test failure, it saves a screenshot of the headless browser.

Installation is simple; toss this in your app’s Gemfile:


group :test do
  gem 'capybara-screenshot'
end

… and that’s it. It saves screenshots away in tmp/capybara. The simplicity is beautiful.

So give it a try and maybe send him a pull request or a follow.

delayed_paperclip

Jesse Storimer (jstorimer), from all the way up in Ottawa, figured out how to process Paperclip attachments in the background using delayed_job or Resque. He packaged it all together as delayed_paperclip, and it’s the way to go for delaying Paperclip processing. It even works with S3.

It’s a little trickier than capybara-screenshot to get running, due to the nature of the beast. But it’s also well-documented in the README.

In your Gemfile add delayed_paperclip:


gem 'paperclip'
gem 'delayed_paperclip'
gem 'resque'

You must also have Resque (or DJ) configured and running properly.

To have things function more smoothly you should add an attachment_processing boolean to your database table. Like this:


./script/rails g migration add_avatar_processing_to_users avatar_processing:boolean

In your model you need to explicitly state that the attachment is to be processed in the background:


class User < ActiveRecord::Base
  has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" }

  process_in_background :avatar
end

And there you go; background processing for your Paperclip uploads. Thanks, Jesse!

mongoid-paperclip

Speaking of Paperclip, Michael van Rooijen (meskyanichi) of The Netherlands figured out how to use MongoDB to store file upload data. He’s named this solution mongoid-paperclip.

The set up is straight-forward. In your Gemfile:


gem 'mongoid-paperclip', :require => 'mongoid_paperclip'

And in your model, where normally you would use has_attached_file, instead use has_mongoid_attached_file:


class User
  include Mongoid::Document
  include Mongoid::Paperclip

  has_mongoid_attached_file :avatar
end

We hack code too

Speaking of having things to share, we coders at thoughtbot are also coders outside of thoughtbot. Here’s a quicker summary of some sweet hacks we’ve rocked:

Nick Quaranto

Nick is qrush on Github. Follow him if you like these things:

gitready
A bunch of tips for using git.
rubygems.org
Some central storage Web site for gems. You might have heard of it.
danger_danger
A sample Web site, mixing Rails with high_voltage. He wrote a blog post about this.
counter
A tool to help score a game of Carcassonne.

Jason Morrison

Jason is jasonm on Github. Maybe these tickle your fancy:

Sample apps:

backbone_sync-rails
A spike of a WebSockets-based, instant feedback, Rails and Backbone app.
chat_app
A chat app showing how to mix Backbone, Cucumber, and Jasmine.

Presentations:

backbone-js-on-rails-talk
A talk on mixing Backbone and Rails, delivered at NH.rb and Boston.rb last month.
backbone-front-end-presentation
A talk on using Backbone, delivered at the Boston Frontend Developers meetup.

Ben Orenstein

Ben is the amusingly-named r00k on Github. Two things in the past month, both related to his mouth:

talk_notes
Notes from his talk on Vim for Rails, which he gave both at RailsConf 2010 and at the first Boston Vim meetup.
dtx_site
The Web site for the quartet in which he sings.

Chad Pytel

Chad, or cpytel as we like to call him, had one talk-related repo last month:

fowa-backbone
A talk on Backbone delivered at the Future of Web Apps in London.

Gabe Berke-Williams

Gabe, with his long name and all, can be followed as gabebw on Github. Here’s some chat-related stuff he’s done in the past month:

chat_stew
An Adium log parser.
pidgin2adium
A tool for importing pidgin logs into Adium.
memetron
Natural language processing simulator for things that Reddit finds funny.
fuckyeahfuckyeahproxy
A proxy server to make Campfire understand images that don’t end in .jpg, specifically targetting fuckyeah.heroku.com.

Harold Gimenez

Harold—hgimenez on Github—

presentations
A talk on using Redis, amusingly titled “Redis: Nimble Data Bacon”, presented at PG West 2011.
truncate_html
A classic Rails gem for truncating a piece of HTML. (I also wrote this a bunch of years back!)
stack
A sample app, serving as a gentle introduction to test-driven development.

Mike Burns

I can be found on Github as mike-burns. Some things I’m excited about:

liaison
An abstraction of the Rails presenter pattern, in a non-intrusive, object-oriented manner.
method_missing
Those methods that should have existed on Ruby’s Method object.

… And More?

Those are the gems that metaphorically came across my metaphorical desk over the past literal month. Do you have any to share? Any you’ve written?

dancroak

cURLing with Rails’ authenticity_token

Our event, Developers Developers Developers Developers, is this weekend.

When the amount of registrations reached the capacity of the venue, we removed the registration form from the website.

However, we left the Rails route and controller around and encouraged students to register by reading the source code of the application and coding their way in. We pointed them to the staging app so they could practice before registering via the production app.

D8 registration challenge

Rails’ authenticity_token

So we just need to POST to /registrations with the right params, right? Right. However, “the right params” needs to include Rails’ authenticity_token, which the framework uses to combat CSRF. The payload also needs to include a cookie because the authenticity_token depends on it.

Curling

cURL

So here’s the cURL solution.

Step 1:

curl http://dddd-staging.heroku.com --cookie-jar cookie | grep csrf

That will store the cookies in a file named “cookie” and print out the authenticity_token you need (it’s the value of the content attribute on the csrf-token meta tag):

<meta name="csrf-param" content="authenticity_token"/>
<meta name="csrf-token" content="sNMk592JV2wwHn6DPJ8C5oy/hHDnjIlZBOHyngtTbpQ="/>

Meanwhile, the contents of the cookies file looks like this:

# Netscape HTTP Cookie File
# http://curl.haxx.se/rfc/cookie_spec.html
# This file was generated by libcurl! Edit at your own risk.

#HttpOnly_dddd-staging.heroku.com   FALSE   /   FALSE   0   _dddd_session   BAh7ByIQX2NzcmZfdG9rZW4iMXdNWm5kUWRLWGRWWGlUZSswT0VFRFN6NHl5dkNWL1NuLzZ1alh3c2lndU09Ig9zZXNzaW9uX2lkIiUwNzNmYmI2MTA0MmI5ZTgxNmUxODA0MzJhOTIyNTk2Yw%3D%3D--fb9ee7c9f96cea60d7be43ff87ce1ac9a8e53548

Step 2:

curl http://dddd-staging.heroku.com/registrations --data "registration[name]=Dan Croak&registration[twitter]=croaky&registration[school_name]=Holy Cross&registration[role]=Developer&authenticity_token=sNMk592JV2wwHn6DPJ8C5oy/hHDnjIlZBOHyngtTbpQ=" --cookie cookie

This adds the authenticity_token and also includes the cookie from the first request.

The output will be the original HTML that we fetched and replaced on the page via Ajax when registration was still open:

<div class="student">
  <div class="avatar">
    <img src="http://avatar.statusok.com/croaky?size=73" />
  </div>
  <div class="student-details">
    <div class="name">Dan Croak</div>
    <div class="twitter">@croaky</div>
    <div class="role-and-school">
      Developer, Holy Cross
    </div>
  </div>
  <h2>Thanks for registering! We can't wait to see you!</>
  <h3>Follow @<a href="http://twitter.com/thoughtbot">thoughtbot</a> and @<a href="http://twitter.com/greenhornboston">greenhornboston</a> for updates.</h3>
  <h3>We also invite you to join our private <a href="http://groups.google.com/group/developers-developers-developers-developers">mailing list</a> for speakers and attending students.</h3>
</div>

Another Approach: Using Web Inspector

However, we’re living in the future here, folks. It’s 2011, and we’ve got a GUI for everything - no need to get Terminal all over your hands.

This is a web browser, I know this

So let’s load the site normally in a web browser, view the HTML source to grab that authenticity token, insert a form into the DOM, then submit it.

I’ll be using Chrome and the WebKit Inspector here, but you could also use Firefox and the excellent Firebug plugin.

Step 1: Find the authenticity token

Here I view the HTML source and look for the authenticity token in the element:

Auth Token

Step 2: Insert a form into the HTML

Here’s the registration form that we’ll add back into the page. I made sure to insert the right authenticity token:

<form action="/registrations" method="POST">
  <input type="text" name="registration[name]"        value="Jason Morrison" />
  <input type="text" name="registration[twitter]"     value="jayunit" />
  <input type="text" name="registration[school_name]" value="RIT" />
  <input type="text" name="registration[role]"        value="Developer" />
  <input type="text" name="authenticity_token" value="iKSXdP4+Ir80ABwsmwvX5LjUKdto3n6p99E/+pgmegI=" />
  <input type="submit" />
</form>

You can insert the form anywhere. Let’s overwrite this paragraph:

Edit HTML

Paste in the HTML:

Pasted HTML

Step 3: Submit the form

Click submit, and you’re off to the races.

Form Success

See you at the event!