About

James Golick

James Golick is an engineer, entrepreneur, speaker, and above all else, a grinder.

As CTO (or something?) of BitLove, he scaled FetLife.com's traffic by more than an order of magnitude (and counting).

James spends most of his time writing ruby and scala, building infrastructure, and extinguishing fires.

He speaks regularly at conferences and blogs periodically, but James values shipping code over just about anything else.

Latest Tweets

follow me on Twitter

James on the Web

resource_controller update: Bug Fix, Generators, and Google Group!

Oct 25 2007

A week after I released resource_controller, there are a few issues that needed to be resolved.

Specifying Actions

Hampton pointed out the fact that I hadn't mentioned any way of specifying which actions a controller should respond to. You might want to have a controller that only responds to show, and index, for example. It was possible (and documented - see the RDocs), but somewhat broken. This release fixes that bug.

You can either provide a list of actions, or use :all, :except => syntax.

class PostsController < ResourceController::Base
  actions :show, :index
  ## .. or ..
  actions :all, :except => :index
end

Generators

resource_controller comes with a scaffold_resource generator now. In the 1.2.3+ stream, it will override the built-in version. I figure - if you're using resource_controller, you probably won't have much need for the default one.

It's pretty clever, too. If you have Haml installed, it generates Haml. If you have Shoulda installed, it spits out functional tests that make use of Shoulda's wonderful should_be_restful macro (note: I'm not necessarily opposed to doing the same for RSpec, if there's demand - let me know). Otherwise, it spits out erb, and the same functional tests as the generator included with rails.

The syntax is exactly the same as the built-in generator.

script/generate scaffold_resource post title:string body:text

Get It

1.2.3+ Compatible

svn export http://svn.jamesgolick.com/resource_controller/tags/stable vendor/plugins/resource_controller

Edge/Rails 2.0 Compatible

svn export http://svn.jamesgolick.com/resource_controller/tags/edge_compatible/stable vendor/plugins/resource_controller

If you're looking for older versions, try browsing http://svn.jamesgolick.com/resource_controller/tags.

For more info, see the release announcement.

Community

I also wanted to announce that I've created a google group for resource_controller.

Come join it, and discuss what can be done to make r_c even better!


Introducing resource_controller: Focus on what makes your controller special.

Oct 19 2007

If you're using rails, and you've kept up with what's happening in the community, and in the framework, you're probably writing RESTful apps. You may have noticed, like I did, that most of your controllers follow the same basic pattern - the one that the scaffold_resource (just scaffold in edge/2.0) generator spits out.

I wanted a great way to hide that pattern, and describe the unique features of my controllers through a more domain-specific API. Since I tend to write a lot of nested, and polymorphic resources, I also wanted to DRY up all of that code, and make generating urls a lot more intuitive. Finally, I wanted all of that code to be well-tested, so that I could count on hacking it up when I needed new features, without breaking things.

So, I created it, and here it is.

resource_controller

A basic, out of the generator resource just requires inheriting from ResourceController::Base.
class PostsController < ResourceController::Base  
end

API

Before/after callbacks, responses, and flash messages are managed through an extremely flexible API. I tried my best, here, to make syntax succinct when your needs are succinct, and allow API calls to be organized in an intuitive way. What I came up with was a scoping system, where calls to the various API methods can be chained, or scoped with a block.

Take the create action, for example. You might want to add a before block, to assign the author attribute of your post model to the current user.
class PostsController < ResourceController::Base
  create.before do
    @post.author << current_user
  end
end
As your application matures, you may want to add an RJS response to your create method, for some AJAXy goodness. Easy.
class PostsController < ResourceController::Base
  create.before do
    @post.author << current_user
    
    response do |wants|
      wants.html
      wants.js
    end
  end
end
Actually, there's even a shortcut for adding responses. You can omit the response block, if you just want to add responses to what's already provided by resource_controller (just HTML) or has been added elsewhere.
class PostsController < ResourceController::Base
  create do
    before do
      @post.author << current_user
    end
    
    wants.js
  end
end
Since I commonly use the same RJS template for several actions, I've found this short-form really handy, because I can use a one-liner to add the same response to several actions.
class PostsController < ResourceController::Base
  [create, update].each { |action| action.wants.js {render :template => "post.rjs"} }
end
Oh yeah, and you can change the flash too.
class PostsController < ResourceController::Base
  create.flash "Wow! RESTful controllers are so easy with resource_controller!"
end
For more API details, and examples, see the RDocs.

Helpers

Helpers are used internally to manage objects, generate urls, and manage parent resource associations.

If you want to customize certain controller behaviour, like member-object, and collection fetching, overriding helper methods is all it takes.

Note:For certain resource_controller functionality to work properly, user-defined helpers must make use of the other r_c helpers. The following examples do not follow that convention for clarity purposes - see the docs for more details.

If you wanted, for example, to use a permalink for your post, you'd need to alter the way that posts are fetched. Just override the object method.
class PostsController < ResourceController::Base
  private
    def object
      @object ||= Post.find_by_permalink(param[:id])
    end
end
You'll probably also want to add pagination to your index method. In the same way we altered member object fetching, we can change collection fetching behavior.
class PostsController < ResourceController::Base
  private
    def collection
      @collection ||= Post.find(:all, :page => {:size => 10, :current => params[:page]})
    end
end
Details and examples in the RDocs.

Namespaced Resources

...are handled automatically, and any namespaces are available, symbolized, in array form from the namespaces helper method.

Nested Resources

Again, handled automatically. This can be a real pain, and it's a lot easier with r_c. With an ActiveRecord-like syntax, just say belongs_to :model, and resource_controller takes care of the associations for you.
class CommentsController < ResourceController::Base
  belongs_to :post
end

Polymorphic Resources

This is a concept that can be found in a lot of my apps. Prior to resource_controller, it was a real pain on various levels. I solved some of my problems with urligence, and took things the rest of the way with resource_controller. It really does pretty much everything for you.

Just use the belongs_to syntax in your controller, and r_c infers whichever association (if any) is present when an action is called. The arguments passed to belongs_to are single possible parents; there is no support for deeply nested resources (although, I'm not necessarily opposed to adding it, if there is demandwe).
class CommentsController < ResourceController::Base
  belongs_to :post, :product
end
In the above example, the controller will automatically infer the presence of either a parent Post, or Product, and scope all the comments to that parent. The controller will also respond without a parent if you have that in your routes.

Thanks to urligence, generating urls in your polymorphic controller's views is really easy. The object_url, and collection_url helpers will maintain your parent resource's scope automatically.
# /posts/1/comments
object_url          # => /posts/1/comments/#{@comment.to_param}
object_url(comment) # => /posts/1/comments/#{comment.to_param}
edit_object_url     # => /posts/1/comments/#{@comment.to_param}/edit
collection_url      # => /posts/1/comments

# /products/1/comments
object_url          # => /products/1/comments/#{@comment.to_param}
object_url(comment) # => /products/1/comments/#{comment.to_param}
edit_object_url     # => /products/1/comments/#{@comment.to_param}/edit
collection_url      # => /products/1/comments

# /comments
object_url          # => /comments/#{@comment.to_param}
object_url(comment) # => /comments/#{comment.to_param}
edit_object_url     # => /comments/#{@comment.to_param}/edit
collection_url      # => /comments
More in the RDocs.

Getting it

resource_controller is available under the MIT License.

It is currently available in two streams:

1.2.3+ Compatible

Install it:

svn export http://svn.jamesgolick.com/resource_controller/tags/stable vendor/plugins/resource_controller

SVN (stable): http://svn.jamesgolick.com/resource_controller/tags/stable

SVN (ongoing): http://svn.jamesgolick.com/resource_controller/trunk

Note: If you want to run the tests, cd in to the test directory, and type rake test.

Edge/Rails 2.0 Compatible

Install it:

svn export http://svn.jamesgolick.com/resource_controller/tags/edge_compatible/stable vendor/plugins/resource_controller

SVN (stable): http://svn.jamesgolick.com/resource_controller/tags/edge_compatible/stable

SVN (ongoing): http://svn.jamesgolick.com/resource_controller/branches/edge_compatible

Note: If you want to run the tests in the edge-compatible version, cd in to the test directory, and type rake rails:freeze:edge. I didn't want people to have to download all of edge rails just to get the plugin.

Also, check out the rdoc

Feedback

Drop me a line and let me know what you think. I'd love to hear your suggestions for API or implementation improvements, or anything else!


Rails polymorphic url generation sucks. Here's something better.

Oct 11 2007

If you've ever written a rails app with a lot of polymorphic resources, you've probably noticed that generating urls for your polymorphic routes is a real pain. In edge rails, some of the problems have been solved by the new polymorphic url methods. Unfortunately, those solutions are both inadequate, and "not recommended for use by end users" (see DHH's comment at the bottom). The problem is that if you want to use the same views and controller code without a lot of ugly conditionals to generate your urls, you're out of luck.

The Problem

## routes.rb

map.resources :photos
map.resources :users, :has_many => :photos
map.resources :tags, :has_many => :photos

## photos_controller.rb

class PhotosController
  ## in the create method
  wants.html { redirect_to url_for(url_helper_params) } # I know DHH doesn't want us to use this, but how else can I get this effect?

  ## in the destroy method
  wants.html { redirect_to photos_url } # unfortunately, this will drop any parent paths we may have
                                        # a user who called DELETE /users/james/photos/1 ends up at /photos instead of /users/james/photos)

  private
    # Note: I actually use a modification to make_resourceful to do this far more cleanly, but wanted to be as complete as possible in this example.
    def parent_object
      case
        when params[:user_id] then User.find_by_id(params[:article_id])
        when params[:tag_id] then Tag.find_by_id(params[:news_id])
      end    
    end
  
    def url_helper_params
      [parent_object, @photo].reject { |obj| obj.nil? } # we have to get rid of any the parent_object if it's nil, or else this will fail :(
    end
end

# index.rhtml

<%= link_to "New Photo", new_photo_path %> # same problem as our destroy redirect
We have routes like /users/james/photos, and /tags/montrealonrails/photos. We want to seamlessly maintain the top level of the path without resorting to conditionals or repetition. That is, if you browse to /users/james/photos, and click on the show link, you should go to /users/james/photos/1, not /photos/1. There should also be a polymorphic plural url helper. We have url_for for members (/photos/1), but for collections (/photos), we're stuck resorting to calling the url helpers themselves. So, to create a collection url, we'd have to check what the parent object was, and then call the appropriate helper based on that. And, all of this is further complicated when there are namespaces (/cms/products). Wouldn't it be great if there was a better way?

Stupid Simple Urls

Try saying that three times fast. Done? Good, because it's not called that - I was just messing with you.

URLigence

Intelligent url building.
## routes.rb

map.resources :photos
map.resources :users, :has_many => :photos
map.resources :tags, :has_many => :photos

map.namespace :admin do |admin|
  admin.resources :products, :has_many => :options
  admin.resources :options
end

##

assert_equal "/photos", smart_url(:photos)
assert_equal "/photos", smart_url(nil, nil, nil, :photos) # in case your parent objects aren't there
assert_equal "/users/james/photos", smart_url(User.find_by_name(:james), :photos)
assert_equal "/users/james/photos/1", smart_url(User.find_by_name(:james), Photo.find_by_id(1))
assert_equal "/photos/1", smart_url(nil, Photo.find_by_id(1)) # in the case that your parent object isn't there
assert_equal "/photos/1/edit", smart_url(:edit, Photo.find_by_id(1))

assert_equal "/admin/products", smart_url(:admin, :products)
assert_equal "/admin/products/1", smart_url(:admin, Product.find_by_id(1))
assert_equal "/admin/products/1/options", smart_url(:admin, Product.find_by_id(1), :options)
assert_equal "/admin/products/1/edit", smart_url(:edit, :admin, Product.find_by_id(1))
assert_equal "/admin/options", smart_url(:admin, nil, :options) # in the case that your parent object isn't there
It's pretty straightforward. Just call smart_url with any parameters that might be there, including ones that might be nil, and symbols at the beginning for namespaces (simple_url/cms/products), member actions (/products/1/edit), or both (/cms/products/1/edit), objects in the middle, and a symbol at the end for a resource's index method (/products). That's it.

Get It

Get version 0.1 at http://svn.jamesgolick.com/urligence/tags/stable. Oh, and don't take the name of the tag too seriously - I just wrote it tonight.

svn export http://svn.jamesgolick.com/urligence/tags/stable vendor/plugins/urligence

Let me know what you think of it.


Testing Misconceptions #1: Exploratory Programming

Oct 05 2007

So, my last essay on testing was ycombinatored, and then reddited the next day. Cool! I'm honored to have so many people reading, and discussing my article. It's a pleasure.

I found some of the discussion very interesting. It seems like a lot of developers still don't believe in unit testing their code. In fact, many made arguments that questioned, or even outright dismissed the value of unit testing (for more such comments, see the reddit and ycombinator threads, or the thread of comments on the article itself). What surprised me most, though, was the number of misconceptions people have about what testing actually is, why we test, and how long it takes. Many, if not most, of the anti-testing arguments are based on entirely false premises.

In this on-going series, I'll put those misconceptions to the test (pun intended), and provide my take on what the truth is.

Testing Myth #1: I can't test first, because I don't have an overall picture of my program.

BTUF (Big Test Up Front) incurrs [sp] many of the same risks as BDUF (Big Design Up Front). It assumes you are creating artifacts now that will last and not change drastically in the future.
Yes, TDD implies that there is a more or less exact specification. Otherwise, if you're just experimenting, you would have to write the test and your code, and that's going to make you less inclined to throw it away and test out something else (see "Planning is highly overrated").
When I really have latitude in my goals, my code is just about impossible to pin down until it's 95% implemented.
How can you test something if you don't even know how or if it works? You need to hack on it and see if you can get things going before you nail it down, no?
According to this group, testing first is impossible because they're not sure exactly what they're writing. Some of them go so far as to equate testing first with big up front designs. The assumption, in both cases, is that writing your tests first means writing all of your tests first, or at least enough to require a general overview of your program. Nothing could be further from the truth.

It seems likely to me that this group's misconception stems from mixing up unit testing with acceptance testing. Acceptance testing, whether automated or manual, would require an overall specification for how (at least some major portion of) the system should function. Nobody is suggesting that you write your acceptance tests first.

Unit tests verify components of your program in isolation. They should be as small as possible. And, in fact, if your unit tests know enough about your program that they're starting to look like acceptance tests, their effectiveness is going to be diminished considerably. That is, you don't want your unit tests to have an overall picture of what you're building. They should have as little of that picture as possible.

Separating Concerns

Writing tests first doesn't mean you can't explore. It means that the exploration process happens in your tests, instead of your code - which is great! In your tests is where the exploration process belongs.

When you explore in your implementation code, you're trying to answer two questions at once: "What should my code do?" and "What's the best way to implement my code's functionality?". Instead of trying to juggle both concerns at once, testing first divides your exploration in to two stages. It creates a separation of concerns. You might even say that TDD is like MVC for your coding process.

You begin your exploration, of course, by putting together some preliminary tests for the first bit of functionality you're going to write. By considering the output before the implementation, you gain several advantages. The classic example, here, is that you get the experience of using your interface, before you've invested any time in bad API design ideas you may have had. But wait, there's more!

You also get the opportunity to focus on what your code will do. Before I began practicing TDD, I would regularly be almost all the way through writing a block of code before I realized that the idea just wasn't going to work. The thing is, when you're exploring, and you're focused on one or two implementation lines at a time, the result of the code becomes an afterthought. By spending that minute or two up front thinking about what should come out of your code, you'll save yourself a ton of backtracking, and rethinking later on.

That's all for today

I hope you enjoyed the first installment of Testing Misconceptions. I'd love to hear your feedback, or ideas for topics. Please feel free to leave them in the comments, or shoot me an email. Please check back for more episodes.


Montreal on Rails #3

Oct 03 2007

With our new digs, things were better than ever at last night's MoR. It's really great to see so many people sharing their knowledge, and just participating in the Montreal community. Aside from my presentation, Gary, and Francois both gave outstanding talks.

Javascripting for Rails Devs

Gary Haran talked to us about how to use prototype.js to ease some of the pains of writing javascript, and get yourself a beautiful ruby-like API. Since Gary taught me everything I know about Javascript while I was working at ZipLocal, I have been pushing him to share his knowledge with the masses, and he finally did with last night's presentation. Javascript (especially when combined with prototype) is awesome, and I hope this will be the first of many presentations from Gary on how to harness the awesome power in JS with less of the pain.

Piston: Vendor branch management made simple

François Beausoleil, the author of Piston, the excellent vendor branch management gem, was nice enough to come all the way to Montreal, and talk to us about his creation. In a nutshell, Piston aims to solve all of the problems that you get, when you depend on svn:externals to manage plugins in your rails app. Things like a new revision of a plugin breaking all your tests, and blocking deployment of a critical bug fix come to mind. I had heard a lot about Piston before his talk, but I am now fully sold, and will spend some time converting my current apps to use it this afternoon.

After all the talks were over, I had some great conversations with some of the awesome Montrealers who attend these great events. I talked Giraffes with Mat, iPhone(s) with Carl, number puzzles with Daniel, debated test macros with Marc-André, and discussed the latest and greatest in photography world with Alain Pilon. All in all, a great evening. Thanks to Fred and Ben for the space!

For more on last night's event, check out the photos, and my post about my presentation. As I said in my other post, video of last night's presentations will be available very soon.


Plugins I've Known and Loved #1

Oct 03 2007

Last night at Montreal on Rails, I gave a talk about two of my favourite Rails plugins: make_resourceful & shoulda. For those of you who were unable to attend, the videos will be available very soon for your consumption.

make_resourceful

By encapsulating the standard RESTful controller pattern, make_resourceful allows you to focus on what's really important in your controllers, and saves you a ton of keystrokes along the way. The stable version is available here. Although, I prefer to live on the edge. Also, please join the discussion.

shoulda

Shoulda is the awesome set of test macros, and extensions to test/unit by the folks over at thoughtbot. A major time and keystroke saver for test-driven developers. (You are writing tests, right? No? Start here.) So, get your shoulda here, and be sure to check out the rDocs and tutorials.

Also, please check out the presentation slides, and the source code from my demo (note: see here for where I started, and HEAD of trunk is roughly where I ended). Also, see my review of MoR#3.