Notes on designing, developing and delivering great products

Supporting Cross-Domain AJAX in Rails using JSONP and CORS

By on in Mobile, Web

The recent rise in popularity of client-side JavaScript MVC frameworks has led to a revival of web apps with thick clients. As more logic is moved to the client-side, the need to communicate with servers in different domains becomes more common. Unfortunately, JavaScript’s same origin policy prohibits you from making a request to a server in another domain. Two ways to circumvent this restriction are JSONP and CORS. In this article, we’ll take a look at supporting both of these in a Rails app.

Continue reading …


Beginning Outside-In Rails Development with Cucumber and RSpec

By on in Process, Web

The RSpec Book defines outside-in Rails development as starting with views and working your way in toward the models. By developing from the outside in, you are always taking a client perspective at each layer of the application. The end result is an absolute minimum implementation, consisting of simple, expressive interfaces.

Outside-in development doesn’t require any specific tool or language. This article will demonstrate it in Rails, using two popular testing tools: Cucumber and RSpec.

Continue reading …


Does My Rails App Need a Service Layer?

By on in Web

Sometimes during domain modeling you come across something that isn’t a thing. These operations that don’t quite belong to an object are called services. Services often live in a separate, service layer. The service layer lies between controllers and models, defining an application’s interface, its API.

Designing with services and a service layer is popular in the Java J2EE/Spring community. However, it’s not common in the Rails world. Is this because of the Ruby community’s general backlash against the complexity of Java? Or has the rise of HTTP-based JSON APIs made this architecture obsolete? To answer these questions, let’s take a deeper look at services and the benefits of a service layer.

Continue reading …


Exploring Client-side MVC with Backbone.js

By on in Web

Backbone.js continues to gain popularity in the JavaScript MVC community. I decided to give it a try by creating a simple, single-page app to CRUD a single domain model.

While it wasn’t as trivial as a traditional server-side implementation in Rails, it did turn out relatively clean. This is a long post, and if you make it through it, let me know what you think.

Continue reading …


Modern Cucumber and Rails: No More Training Wheels

By on in Process, Web

Last month, cucumber-rails 1.1 was released. This release removed web_steps.rb, a collection of step definitions for interacting with a web app.

For months, web_steps.rb contained a warning of its negative effects on feature maintenance. Like most developers, I ignored the warning. During a recent upgrade of an existing Rails app, I realized it was now gone. Instead of copying and pasting it from an older app or using the newly created cucumber-rails-training-wheels gem, I decided to accept the challenge and refactor its steps out of the app’s existing features.

After the refactor, the features read much better. They were simpler, less verbose, and felt more maintainable. I also cleaned up my factory_girl usage, which was causing issues similar to web_steps.rb. Here’s a short overview of the main refactorings.

Continue reading …


Valium extracts Model attributes without instantiating ActiveRecord objects

By on in Web

I was recently on a project that captures and logs data as ActiveRecord models.  Each datum had 10 or so numeric attributes.  One story required pulling out all the values for a particular attribute in a time range (i.e. all the temperatures for the last week).  This could involve 1000’s of rows from the database.  I cringed at the thought of instantiating that many ActiveRecord objects.  I was not, however, eager to start executing SQL in the project just for efficiency; it usually violates DRY, makes testing harder and the code more fragile.

Enter Valium, a neat gem that make it easy to use your existing ActiveRecord code – but only pull out the attributes you want.  No ActiveRecord instantiation.  Ernie Miller, the creator, has a great post on the hows and why of using this gem.  After testing it out, I was very pleased.  It was exactly the solution I was looking for.  All you do is add .values_of :field_1, :field_2, … :field_n at the end of your Relation.

Note:  I updated this post to use 0.4.0’s new syntax.

Old code changed from

fields = Dummy.since(date).select(:some_field).map(&:some_field)
fields_and_dates = Dummy.since(date).select('some_field, sample_date') \
     .collect{|d| [d.some_field, d.sample_date] }

To

fields = Dummy.since(data).value_of :some_field
fields_and_dates = Dummy.since(date).values_of :some_field, :sample_date

Not only does this look cleaner (especially the case where you are extracting multiple fields), but you are not instantiating a bunch of ActiveRecord objects.  You can reuse your existing scopes and other Relations.  No SQL required. For a quick performance test, I created a Dummy model with 20 string fields.  I seeded the database with 20,000 of these models, where each field was just the current timestamp as a string.  I then timed how long it took to extract 2 of the 20 fields using each method:

# Method 1, creating AR objects for each row
Dummy.select('field_1, field_2').collect{ |d| [d.field_1, d.field_2]}

# Method 2, using Valium to extract data w/out AR objects
Dummy.values_of :field_1, :field_2

The second (Valium) version was 4x faster. When I pulled out more fields, the performance gap narrowed. For 5, 10 and 20 fields, Valium was still about 3x faster. This is just an informal test based on execution time, and doesn’t consider the object churn and memory involved in creating ActiveRecord objects for the first (non-Valium) method. Ernie posted some benchmarks (and his script) comparing using select/map to Valium.


Designing mobile APIs – basic behaviors

By on in Mobile

As Rails developers we design APIs on a regular basis: routes for browsers to interact with a web app, JSON apis and routes for client side javascript to build dynamic pages, payloads queued for background processing on a server, and so on. As we move into mobile development we can benefit from many of the lessons we have learned about good API design, but also face some new problems and changing demands.
Continue reading …


Generating documentation from specs

By on in Web

On one of our rails projects I am creating an api to allow mobile clients to access a web service. I need to provide documentation of this API to the developers of several different clients during its development. Normally I would prefer to let my API tests act as documentation of the expected API behavior but in this case I cannot give all of the client developers access to the rails project’s git repository and even the cleanest rspec specs might not be legible to developers without ruby experience.

I also don’t want to spend time manually updating documentation every time I change the API and don’t want to risk wasting other developers’ time by providing out of date or inaccurate documentation.

Instead I hacked together a rake task to covert my API controller specs into documentation using a custom rspec formatter. Now I can automatically update the documentation as part of our CI build process.
Continue reading …


Rails 3 Upgrade Tip: Invalidate Session Cookies

By on in Everything Else

I recently finished working with Kathryn Aaker on upgrading Eggs, her farm CSA management software, to Rails 3. While there is a lot of good information out there on upgrading from Rails 2 to 3, we did run in to a few tricky snags not covered in the guides.

One such snag happened only once we actually deployed our work to production. We’d loaded the login screen on the Rails 2 version, deployed the new Rails 3 version to Heroku and then reloaded the login screen only to get a 500 error. Crap! We’d already deployed the upgrade to a staging Heroku instance with no problems. What gives?

Viewing the application logs we found:

ActionDispatch::Session::SessionRestoreError (Session contains objects whose class definition isn't available.
Remember to require the classes for all objects kept in the session.
(Original exception: uninitialized constant ActionController::Flash::FlashHash [NameError])
)
  ...

It appears that Rails 3 no longer uses ActionController::Flash::FlashHash and Eggs uses the flash to display the login message among other things. So users actively using Eggs while we did the upgrade we actually likely to get this error. And they would continue to see this error until their session expired, they restarted their browser or they cleared their cookies.

The next day was a big pickup for Clark Summit Farm and that evening a time when many were finishing up their orders for wonderfully tasty and sustainably raised beef and pork. A minute after doing the deploy Kathryn actually got a call from the CSA manager who was stressing out because she was getting errors. Double crap!

So there were users out there with encrypted session cookies that held serialized Ruby objects that no longer existed in Rails 3. How could we invalidate those session cookies?

The solution ended up beautifully simple – change the secret token stored in config/initializers/secret_token.rb.

# Your secret key for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!
# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
Foobar::Application.config.secret_token = 'ce90ddf2fb1...69bf25'

We just changed one character and redeployed. This forces all old session cookies presented by the browser to fail decryption and be invalidated. The user doesn’t have a session so they have to log in again. That works for us.

So add this to your Rails 3 upgrade checklist:

Change the secret token used to encrypt session cookies so that users who are using your application when you deploy the upgrade don’t get nasty server error pages.


Speedy Test Iterations for Rails 3 with Spork and Guard

By on in Process, Web

Overview

TDD is fun, right? Rails enthusiasts and agile evangelists alike agree. Waiting for your tests to run, however, makes for a frustrating experience. When the time between test iterations is magnified by bloated tests it can be hard to maintain a purist’s test-driven approach.

After looking into autotest, parallel testing, and in-memory databases, I have found the simplest solution to this problem in Spork and Guard, two great gems that help speed up your tests.

With proper setup and understanding of how these two tools work, you can start down the path to a more responsive test environment and reignite your love for TDD.

Assumptions

This article assumes you are on a Mac Platform, running Rails 3 on Ruby 1.9.2. The instructions should be the same or similar for other enviroments, but I have not tested that assumption. Please, leave a comment if you have trouble with your environment and I will be glad to update the article to reflect the changes.

At the time of writing, the gems referenced are versioned as follows:

  • rails 3.0.1
  • rspec-rails 2.0.1
  • rspec 2.0.0
  • spork 0.8.4
  • guard 0.2.2
  • guard-spork 0.1.3
  • rb-fsevent 0.3.9

Continue reading …