You are currently browsing the monthly archive for October, 2008.

It seems that a lot of the Rails applications I’ve been working on have a User model that has a many-to-many relation with a Role model, so that users can have a role like “admin” or “manager”, or even multiple roles. Along with this comes the necessity to conditionally show things in views. Recently I’ve started moving away from having explicit @current_user.has_role(”whatever”) calls in the views, to some code in the application_helper.rb file:


module ApplicationHelper

  def admin_only(&block)
    role_only("administrator", &block)
  end

  def manager_only(&block)
    role_only("manager", &block)
  end

private

  def role_only(rolename, &block)
    if not @current_user.blank? and @current_user.has_role?(rolename)
      block.call
    end
  end
end

Now in views I can easily mark off sections that should be displayed to only one user type:


<% admin_only do %>
  <!-- administrator content goes here -->
<% end %>
<% manager_only do %>
  <!-- manager content goes here -->
<% end %>

It would be easy to extend the role_only method to take an array of roles and check for membership in any of them, but I haven’t had need of that yet.

Hat tip to Aaron Longwell for introducing me to this technique.

The problem with code review jobs is that you can end up reviewing some pretty sad code.

  • newgem 1.0.0 all thanks to Cucumber - Dr. Nic revises his gem generation tool with lots of new features.
  • Looks like I’ve got another bit of new business spinning up. This is good, though I’ve still got hours free.

  • Announcing the textile_toolbar Plugin - A way to bring some UI goodness to textile editing. Looks useful. (via Matthew Bass)
  • Merb 1.0 RC3 Released! - They’re apparently getting close.
  • App School Launch: TaskFive - An application in a week. Nice story, and potentially useful application as well.
  • Braid 0.5 - This tool for vendoring git and svn repos is moving along. (via RubyFlow)

  • I18n: An Overview - Good summary of the new 2.2 features from Ryan Bigg.
  • The Rails Envy guys, Gregg Pollack and Jason Seifer, are back with another of their “Envycast” screencasts: 45 minutes about Ruby on Rails 2.2, which is scheduled to be released realsoonnow. They were kind enough to send me a review copy (which means, yes, I didn’t pay for it), and here are some impressions.

    You certainly get enough for your money when you purchase their “Package Deal” for $16: the screencast itself in QuickTime, iPod/iPhone, and Ogg Theora formats, a 120-page PDF ebook by Carlos Brando in English and Portuguese, and a set of code samples (you can also buy the video or the ebook separately for $9 each).

    Let’s take the pieces one at a time. Unlike some other screencasts, the Rails Envy guys are using green-screen technology to insert themselves in front of the slides and code samples. This adds some action to what might otherwise be a pretty dry pile of information though (fortunately, I think) the cheesy jokes are not as non-stop as in their classic “Ruby on Rails vs.
    ” commercials. They pack a pretty good amount of information into the screencast, touching on dozens of new features in the time they have; in some areas, they’re more comprehensive than the official release notes.

    The PDF is even more comprehensive than the screencast; it covers a ton of stuff out of the changelogs, with code samples and explanations (in fact, it includes the changelogs as an appendix). If you want a complete overview of the changes coming down the pike for Rails 2.2, the PDF is the single best resource I’ve seen so far.

    The code samples parallel the ebook; they’re set up as a series of tests, so you can run rake against it (this will be useful as 2.2 proceeds from RC1 to release, to see what might have changed), or dig in to test cases to see the new functionality in action.

    So, is it worth the money? Well, you could get all of this information elsewhere: the Rails changelogs and source code and git repository are all public. In theory, it’s easy enough to look at the git logs going back from now to the 2.1 timeframe to see everything. But as someone who’s done just that (to help compile the 2.2 release notes), I can tell you it’s a non-trivial exercise. There’s a lot of stuff in the commit log that doesn’t make immediate sense, and there are older commits that have been changed by newer ones. This set of resources does all that work for you.

    But, one caution: Rails 2.2 just reached the RC1 point, and while the code is mostly locked down, it’s still changing. The odds are pretty good that some part of this material will be obsolete when Rails 2.2 actually ships - and while it should be easy enough for Rails Envy to update the code and ebook, I’m not sure what they’ll do if there ends up being a bug in the screencast. Hopefully they have some plan for that.

    If you’re considering whether to upgrade to 2.2, these resources will give you an early look at how you stand to benefit (as well as listing which 2.1 bugs have been fixed). Personally, I think the video is overkill, but I’m not all that much of a screencast fan; I can scan and even read written material much faster. But the ebook is definitely a valuable addition to the written material on Rails, and at $9, it should be a trivial amount of money for any developer to spend to get up to speed.

  • acs_as_conference - There are a mighty lot of Rails and Ruby conferences these days. I heard good things about this one last time around - and hey, Florida in February, how can you lose?
  • Optimizing RDoc - Hongli Lai attacks RDoc and wins. A good look at how to optimize Ruby code, too.
  • Looks like I’m looking for another consulting project; one major one just wrapped, so I have some pretty substantial hours open going into November.

  • Fixtureless datas with Machinist and Sham - Another alternative for generating repeatable test data for Rails applications. I may look into this, or try to sort out the morass of competing Factory Girl branches, for my next project.
  • authgasm - “Rails authentication done right.” The code in the readme looks nice; I haven’t walked through trying to use it yet.
  • Scaling ActiveRecord with MySQLPlus - With Rails becoming threadsafe, people are looking at other bottlenecks.
  • There are a few guides floating around about how to contribute your own code to Rails. But none of them (or at least none of the ones that I found) walk you through every step of the way. So, here’s an attempt to fill that gap.

    Step 0: Learn at least something about Ruby and Rails. If you don’t understand the syntax of the language, common Ruby idioms, and the code that already exists in Rails, you’re unlikely to be able to build a good patch (that is, one that will get accepted). You don’t have to know every in-and-out of the language and the framework; some of the Rails code is fiendishly complex. But Rails is probably not appropriate as the first place that you ever write Ruby code. You should at least understand (though not necessarily memorize) The Rails Way
    and The Ruby Programming Language.

    Step 1: Install git. You won’t be able to do anything without the Rails source code, and this is a prerequisite. The git homepage has installation instructions. If you’re on OS X, use the Git for OS X installer. Everyday Git will teach you just enough about git to get by. The PeepCode screencast on git ($9) is easier to follow.

    Step 2: Get the Rails source code. Don’t fork the main Rails repository. Instead, you want to clone it to your own computer. Navigate to the folder where you want the source code (it will create its own /rails subdirectory) and run:

    
    git clone git://github.com/rails/rails.git
    

    Step 3: Set up and run the tests. All of the Rails tests must pass with any code you submit, otherwise you have no chance of getting code accepted. This means you need to be able to run the tests. For the tests that touch the database, this means creating the databases. With MySQL:

    
    mysql> create database activerecord_unittest;
    mysql> create database activerecord_unittest2;
    mysql> GRANT ALL PRIVILEGES ON activerecord_unittest.*
           to 'rails'@'localhost';
    mysql> GRANT ALL PRIVILEGES ON activerecord_unittest2.*
           to 'rails'@'localhost';
    

    If you’re using another database, check the files under activerecord/test/connections in the Rails source code for default connection information. You can edit these files if you must on your machine to provide different credentials, but obviously you should not push any changes back to Rails.

    Now if you go back to the root of the Rails source on your machine and run rake with no parameters, you should see every test in all of the Rails components pass. After that, check out the file activerecord/RUNNING_UNIT_TESTS for information on running more targeted tests.

    Step 4: Fork Rails. You’re not going to put your patches right into the master branch, OK? Think of a name for your new branch and run

    
    git checkout -b my_new_branch
    

    It doesn’t really matter what name you use, because this branch will only exist on your local computer.

    Step 5: Write your code. You’re on your branch now, so you can write whatever you want (you can check to make sure you’re on the right branch with git branch -a). But if you’re planning to submit your change back for inclusion in Rails, keep a few things in mind:

  • Get the code right
  • Include tests that fail without your code, and pass with it
  • Update the documentation
  • Step 6: Sanity check. You know at least one other Rails developer, right? Show them what you’re doing and ask for feedback. Doing this in private before you push a patch out publicly is the “smoke test” for a patch: if you can’t convince one other developer of the beauty of your code, you’re unlikely to convince the core team either.

    Step 7: Update your copy of Rails. It’s pretty likely that other changes to core Rails have happened while you were working. Go get them:

    
    git checkout master
    git pull
    

    Now reapply your patch on top of the latest changes:

    
    git checkout my_new_branch
    git rebase master
    

    No conflicts? Tests still pass? Change still seems reasonable to you? Then move on.

    Step 8: Create your patch. Still in your branch, run

    
    git commit -a
    git format-patch master --stdout > my_new_patch.diff
    

    Sanity check the results of this operation: open the diff file in your text editor of choice and make sure that no unintended changes crept in.

    Step 9: Create a Lighthouse account. You will need one to send in a ticket with your patch. You can do this at the free signup page.

    Step 10: Create a ticket with your patch. Go to the Rails Lighthouse page. Sign in if necessary. Click on “Add New Ticket.” Fill in a reasonable title and description, remember to attach your patch file, and tag the ticket with the ‘patch’ tag and whatever other subject area tags make sense.

    Step 11: Get some feedback. The Contributing to Rails page suggests using the rubyonrails-core mailing list or the #rails-contrib channel on IRC freenode for this. You might also try just talking to Rails developers that you know.

    Step 12: Lather, rinse, release. It’s entirely possible that the feedback you get will suggest changes. Don’t get discouraged: the whole point of contributing to an active open source project is to tap into community knowledge. If people are encouraging you to tweak your code, then it’s worth making the tweaks and resubmitting. If the feedback is that your code doesn’t belong in the core, you might still think about releasing it as a plugin.

    And then…think about your next contribution!

    Rails 2.2RC1 is out. Here’s the official announcement. And here are the Ruby on Rails 2.2 Release Notes - of which I am rather fond, because I wrote the bulk of them.

    Some other Rails 2.2 stuff:

  • Ruby on Rails 2.2 - The Rails Envy guys want to sell you PDF and videocast guides to the new features.
  • What’s New in Edge Rails: Rails 2.2 Released - Summary of Features</a> and What’s New in Edge Rails: Even Better Conditional GET Support - Coverage from Ryan Daigle.
  • And more general links:

  • “raise NoMethodError” raises NoMethodError. Raise it with
    NoMethodError.new instead.
    - My first commit to the core Rails code. Hopefully not the last.
  • Good Homes Wanted - A batch of Rails and Ruby projects looking for new maintainers, including some fairly prominent ones.
  • SIPr - SIP stack written in Ruby. If only I had time to play with VOIP stuff…
  • REST: Some tips and implementing “Forgot your password?” - Some ideas about RESTful design.
  • Thinking Sphinx - New PDF from PeepCode.
  • GitHub Rebase #1 - Nick Quaranto is starting a new series to look at activity over on GitHub.
  • How to Spot a Help Vampire - Wisdom from #rubyonrails.
  • There’s a mismatch between the most recent Rails releases (2.1.2 and 2.2RC1) and older versions of RubyGems. Judging by what I’ve seen in various discussion fora, this is well on the way to being a FAQ. It’s made more fun by the facts that

  • The error message doesn’t implicate RubyGems
  • You may think you’re up-to-date on RubyGems when you’re not
  • If you’re affected, you’ll see this message when you try to run script/generate in a Rails application:

    
    undefined method empty?' for /_generator$/:Regexp
    

    If you see this, don’t panic. It just means you need a newer RubyGems release. I’m not sure how current you need to be, but 1.1.1 is definitely too old. As I write this, 1.3.0 is current.

    Now, in theory, to update to the latest version of RubyGems, you just need to run

    
    sudo gem update --system
    

    But - depending on what version of RubyGems you have installed, running that command may lie and tell you that you have nothing to update. If you’re currently on RubyGems 1.1 or 1.2, you need to run a different set of commands to update RubyGems:

    
    sudo gem install rubygems-update
    sudo update_rubygems
    

    You can check your current RubyGems version with

    
    gem -v
    

    If it reports 1.3.0 or later, you should be good to use the recent Rails releases.

    There’s a small change in Active Record behavior that’s going to bite some existing applications under Rails 2.2: private methods on an association proxy are actually private. To illustrate, this code would work in Rails 2.1:

    user.rb:

    
    class User < ActiveRecord::Base
      has_one :account
    end
    

    account.rb:

    
    class Account < ActiveRecord::Base
      belongs_to :user
      private
        def secret_code
          "ABCDE"
        end
    end
    

    Controller code:

    
    @u = User.first
    @code = u.account.secret_code
    

    With Rails 2.1, you’ll actually get the secret code in @code, even though it comes from a private method of the account object. Rails 2.2 is stricter about this: that same code will fail with a NoMethodError. If you want to access a private method across an association proxy now, you’ll need to use @code = u.account.send(”secret_code”).

    Directly accessing private methods on an Active Record instance itself was already blocked in Rails 2.1, but Rails 2.2 updates that failure to give back a NoMethodError as well.

  • Learn the Language, Then the Framework - Good advice, though I’m afraid I’ve built much of my own career on ignoring good advice.
  • Path Finder 5.0 - Supposed to be a really good Finder replacement, and the new version is just out. I’m contemplating trying it, at least.
  • Rails 2.1.2: Security, other fixes - Worth upgrading if you’re on the 2.1 branch. The 2.2 release candidate is just around the corner as well.
  • Thread safety for your Rails - Yes, it’s there. No, it’s not magic pixie dust. Pratik Naik explains.
  • I’ve been nibbling away at how to write the code in Rails controllers recently, and I’m at a point where I’m fairly happy with what I’m doing. The two design requirements for me were:

    1. Write as little code as possible
    2. Get decent SEO-friendly URLs

    Rails already supports friendly URLs, sort of, with to_param. Consider the canonical Post model from a blogging application:

    
    class Post < ActiveRecord::Base
      def to_param
    	"#{id}-#{title}".gsub(" ","-").downcase.gsub(/[^a-z0-9-]/,"").gsub(/(-)*$/,"")
      end
    end
    

    Armed with that definition, it’s possible to write a controller that works with URLs like /blogs/6-my-latest-blog-entry:

    
    class PostsController < ApplicationController
    
      def index
        @posts = Post.find(:all)
      end
    
      def show
        @post = Post.find(params[:id])
      end
    
      def new
        @post = Post.new
      end
    
      def edit
        @post = Post.find(params[:id])
      end
    
      def create
        @post = Post.new(params[:post])
        if @post.save
          flash[:notice] = 'Post was successfully created.'
          redirect_to(@post)
        else
          render :action => "new"
        end
      end
    
      def update
        @post = Post.find(params[:id])
    
        if @post.update_attributes(params[:post])
          flash[:notice] = 'Post was successfully updated.'
          redirect_to(@post)
        else
          render :action => "edit"
        end
      end
    
      def destroy
        @post = Post.find(params[:id])
        @post.destroy
        redirect_to(posts_url)
      end
    end
    

    OK, works fine. But there are a couple of things that annoy me. First is repeating the code to turn things into a slug in every model (though, with Inflector.paramterize coming in 2.2, this is going to get easier). Second is having to include a numeric ID at the start of the parameter. Third is those repeated calls to find(params[:id]).

    Enter a couple of plug-ins: finder_filter, which gets rid of some of the duplication, and from_param, which handles the URLs a bit better. With those installed, I can rewrite the code this way:

    
    class Post < ActiveRecord::Base
      def to_param
    	title.urlize
      end
    end
    
    class PostsController < ApplicationController
      finder_filter :only => [:show, :edit, :update, :destroy]
    
      def index
        @posts = Post.find(:all)
      end
    
      def show
      end
    
      def new
        @post = Post.new
      end
    
      def edit
      end
    
      def create
        @post = Post.new(params[:post])
        if @post.save
          flash[:notice] = 'Post was successfully created.'
          redirect_to(@post)
        else
          render :action => "new"
        end
      end
    
      def update
        if @post.update_attributes(params[:post])
          flash[:notice] = 'Post was successfully updated.'
          redirect_to(@post)
        else
          render :action => "edit"
        end
      end
    
      def destroy
        @post.destroy
        redirect_to(posts_url)
      end
    end
    

    Perfect? Naw, not really. But to my eyes, better. And getting better a little bit at a time is good enough for me.

    The originals of those two plugins are not mine: finder_filter comes from Matthew Bass, and from_param comes from Michael Bleigh. But I’ve tweaked them both to work better together, which is why I linked to my forks of the projects.

    I seem to be developing more expertise than I really wanted in liquid templates.

  • Simple Test Metrics in Your Rails App, and What They Mean - Some thoughts about appropriate code/test rations and rcov numbers.
  • Yesterday was all about frustration. Hopefully today will be better.

  • Why online advertising sucks, and is a bubble - Doc Searls nails it. In an era of economic contraction, I expect online ad budgets to get slashed as sponsors get tired of the lack of demonstrable ROI. This will be followed by many marginal Web 2.0 companies going belly up. Have a nice day.
  • wysihat - In true NIH fashion, 37signals is building a framework for WYSIWYG javascript editors.
  • Suspenders - The thoughbot guys join the list of those with their own “tweaked Rails” starter projects.
  • Announcing Mingle 2.1 - Version bump to ThoughtWorks’ agile project management tool.
  • Spent part of yesterday scheming over new business venture. I believe every consultant should always have at least one scheme coming soon.

  • Observation - Rails Consulting Rates Lower Than .NET Rates - Rob Bazinet muses and asks for feedback.
  • Rails Rumble 2008 Apps - Just in case you want to see what others managed to build in 48 hours.
  • Weekends are always so much better for writing code than Mondays are.

  • The Hobo Cookbook - Guidance for folks who want to use the Hobo framework for Rails.
  • Using DTrace to observe the SQL statements on a live running MySQL database - Something I’ve missed from SQL Server. Here’s instructions to make it easy in OS X.
  • Non-test code is trivial - Yes, testing is hard.
  • Elements of Ruby Style - An attempt at a Ruby style guide. In my experience, such things lead only to arguments or concentration on form over function, but hey, maybe this one will be different. (via RubyFlow)
  • Validating slugs against existing routes in Rails - Useful if you allow unadorned /:user-supplied-id routes.
  • Multiselect control in Rails with a Many to Many relationship - One of several guides out there on this subject.
  • suprails - “Super Rails” command that comes with its own DSL to let you install gems, freeze rails, set up git, and perform other pre-coding steps.
  • Response Splitting Risk - A security issue in Rails is causing new point versions to come out. Here’s the 2.0.5 release announcement.
  • JavaScript: TraceMonkey - Instructions for turning on the new, faster JavaScript engine in Firefox 3.1 beta 1.
  • Delegates are a useful feature that I haven’t seen used in that many Rails codebases - perhaps I’ve just been looking at the wrong codebases. Active Support makes them available for Modules generally, but the use case I find myself most often exercising is with Active Record classes. Delegates let you take some methods and send them off to another object to be processed.

    For example, suppose you have a User class for anyone registered on your site, and a Customer class for those who have actually placed orders:

    
    class User << ActiveRecord::Base
      belongs_to :customer
    end
    
    class Customer << ActiveRecord::Base
      has_one :user
    end
    

    If you’re hanging on to a Customer instance, you can get their User information with methods like @customer.user.name and @customer.user.email.

    Delegation allows you to simplify this:

    
    class User << ActiveRecord::Base
      belongs_to :customer
    end
    
    class Customer << ActiveRecord::Base
      has_one :user
      delegate :name, :email, :to => :user
    end
    

    Now you can refer to @customer.name and @customer.email directly. That’s all been around and works in the current release version of Rails.

    Delegate prefixes just appeared in edge Rails and will work in Rails 2.2. If you delegate behavior from one class to another, you can now specify a prefix that will be used to identify the delegated methods. For example:

    
    class User << ActiveRecord::Base
      belongs_to :customer
    end
    
    class Customer << ActiveRecord::Base
      has_one :user
      delegate :name, :email, :to => :user, :prefix => true
    end
    

    This will produce delegated methods @customer.user_name and @customer.user_email. You can also specify a custom prefix:

    
    class User << ActiveRecord::Base
      belongs_to :customer
    end
    
    class Customer << ActiveRecord::Base
      has_one :user
      delegate :name, :email, :to => :user, :prefix => :account
    end
    

    This will produce delegated methods @customer.account_name and @customer.account_email.

    Just mass-unfollowed a bunch of people on Twitter. Sorry, folks, but something had to give.

  • Liquid Wiki - The Liquid markup language is something I’m currently struggling to make work. Documentation is sketchy, to say the least.
  • Rails for .NET Developers - Latest book from Pragmatic. I read it in manuscript; good stuff.
  • RailsConf’09: Accepting Proposals for Vegas! - Call me back when RailsConf is held in a city fit for human beings.
  • Rails 2.2 won’t be all about new features. The Rails team is also taking advantage of this release to deprecate some existing features. Here’s a list of what will be going away in the 2.2 release:

  • The country_select helper has been removed. This is the one most likely to affect existing applications, I think, but it’s going away because of arguments over which list of countries to use. The deprecation page points to a couple of replacement plugins.
  • Rails::SecretKeyGenerator has been replaced by ActiveSupport::SecureRandom.
    render_component is deprecated. If you need it, grab the render_components plugin.
  • ActiveRecord::Base.allow_concurrency no longer has any effect. Might as well stop calling it. Remember, though, that ActiveRecord is getting connection pool management.
  • ActiveRecord::Errors.default_error_messages has been deprecated in favor of I18n.translate(’activerecord.errors.messages’)
  • The %s and %d interpolation syntax for internationalization is deprecated.
  • String#chars has been deprecated in favor of String#mb_chars.
  • Durations of fractional months or fractional years are deprecated. Use Ruby’s core +Date+ and +Time+ class arithmetic instead.
  • Tonight I’m demonstrating Rails to the local .NET user group. I may survive.

  • Firefox 3.1 beta 1 now available for download - The alphas were pretty rough, but I’ll be giving the beta a try shortly.
  • Slim-Attributes v0.5.0 released - ActiveRecord patch to speed up performance if you don’t feel like limiting your finds to only the fields you need.
  • ScrumNinja - New hosted project management tool built for Scrum teams.
  • BackgrounDRb 1.1 - Better scripting, logging, tests, yay.
  • The week started out with a bang: I completed the first draft of Getting Started with Rails and got started on a new client project as well.

  • Rails Migrations Cheatsheet - A compact guide, available in either HTML or PDF.
  • Announcing follow cost: Is that Twitter celebrity worth the pain? - According to this tool, following me results in much pain.
  • Blank: A Starter App for r_c and shoulda Users - Another attempt at a Rails starter app with all the trimmings. (via RailsGuts, Blank)
  • suprails - Early days yet, but worth watching: the plan is to create a configurable Rails application generator driven by its own little DSL.
  • Life in the fast lane - Thoughtbot introduces Pacecar, a plugin to generate a whole bunch of named scopes for you.
  • You’ll be seeing plenty about the big new Rails 2.2 features soon enough, I’m sure. But there is also a sprinkling of new helpers of one sort or another coming in this version. Here’s a selection that you might like:

  • Model.find_last_by_attributes - The opposite of find_first_by_attributes.
  • Model.find_by_attributes! - Raises an exception instead of returning nil if nothing can be found.
  • Date and Time classes now supply past?, today?, and future? for comparisons.
  • Array#second through Array#tenth are aliases for Array#[1] through Array#[9]
  • Enumerable#several is the equivalent of collection.size > 1
  • Inflector#parameterize produces a URL-ready version of its input, for use in +to_param+.
  • It was a fairly productive weekend for me: a new version of db_populate, a minor update to from_param, the first complete draft of The Rails Initialization Process, and a big chunk of work on Getting Started with Rails.

  • FiveRuns TuneUp for Merb - The FiveRun guys bring their monitoring solution to Merb as well as Rails.
  • About metric_fu 0.8.0 - Solution for generating metrics reports, ideal for use with continuous integration.
  • Coming home to Vim - I’m glad it works for some people (in this case, Jamis Buck). Personally, I wouldn’t touch vi/vim/emacs with a stick.
  • 2 Weeks in Rails - Another new roundup.
  • Exceptional.launch(:paid_plans => true) Exceptional has announced their formal launch & paid plans.
  • Test Your Rake Tasks - Something I really need to get a handle on for a project I’m on now.
  • Rails and the (Possibly) Coming Economic Downturn - John Moody proposes a discussion topic: how do you avoid becoming roadkill?
  • Spree 0.4.0 Released - New version of this open-source Rails e-commerce platform.
  • Blacktree Visor - Pull-down console window for OS X. Cute, but I found it less effective for working than actually having a Terminal window open where I could see when a long-running process completed.
  • Incompatibility between Rails 1.1.6 and Ruby 1.8.6 - I’m sorry to say that I just needed to deploy this fix.
  • I was complaining a few days ago that I was having trouble with authentication in cucumber stories in conjunction with RSpec. It turned out I was making a very stupid mistake (”administrator” and “admin” are not, in fact, the same thing). But in the interests of helping out anyone who ends up here via search engine, here’s how I’ve got it sorted out for now.

    Here’s one of our current cucumber scenarios:

    
      Scenario: See all vendors
    	Given I am logged in as a user in the administrator role
    	And There are 3 vendors
    	When I go to the manage vendors page
    	Then I should see the first 3 vendor names
    

    And here’s the corresponding part of the step file that handles the login:

    
    Given /i am logged in as a user in the (.*) role/i do |role|
      @user = Factory.create(:user, :name => "the user",
        :login => "the_login",
        :password => "password",
        :password_confirmation => "password")
      @role = Factory.create(:role, :rolename => role)
      @user.roles << @role
      visits "/login"
      fills_in("login", :with => "the_login")
      fills_in("password", :with => "password")
      clicks_button("Log in")
    end
    

    Note that I’m using Factory Girl to instantiate objects in this application’s tests.

    There may be a better pattern for this - I’m just getting started with cucumber. But for now, it works for me.

  • Random - An alternative to faker for generating fake data in ruby. This one includes a hook to add your own file of arbitrary random data.
  • Ruby DSLs: instance_eval with delegation - Dan Manges presents an approach to sensibly using some ruby magic.
  • Ruby on Rails: Opportunity in a Financial Downturn - I agree that there’s an opportunity if you’re good. If you’re not good, you’re going to be roadkill.
  • Has My Gem Built Yet? - Service to check whether GitHub has gotten round to building a gem from your latest upload.
    • webrat_story_steps - Looks useful for webrat-based testing, though it’s a bit out of sync with the latest webrat release.
    • Captor: A Capistrano GUI - Interesting, though unfinished.
    • zena - New Rails-based CMS just going into beta after extensive alpha testing.

    For the most part, routing is unchanged in the upcoming Rails 2.2 release. But there are two changes that add a little extra syntactic sugar to your routes.

    First, as Ryan Daigle covered last month, there’s a new :shallow option for nested routes. This change goes a long way to answer the classic objections to deeply-nested routes. What shallow nesting does is give you additional route helpers. For example, with this declaration:

    
    map.resources :rooms, :shallow => true do |room|
      room.resources :shelves do |shelf|
        shelf.resources : books
      end
    end
    

    Any of these routes will be recognized:

    
    /rooms/1/shelves/2/books/3   ==> room_shelf_book_path(1,2,3)
    /shelves/2/books/3           ==> shelf_book_path(2,3)
    /books/3                     ==> book_path(3)
    

    You can also combine shallow nesting with :has_one or :has_many for a more compressed syntax:

    
    map.resources :rooms, :has_many => { :shelves => :books }, :shallow => true
    

    The second change is that you can now supply an array of methods for new member or collection routes on resources. With Rails 2.1, you had to either pick a method or use the wildcard :any method. With Rails 2.2, you can specify just the verbs that a route really needs:

    
    map.resources :books, :collection => { :search => [:get, :post] }
    

    Now I know that getting to the Rapleaf API from Rails is trivial. I may never need this knowledge again.

    • Tunnel 1.1 - Nothing to do with Rails, really; just a cute game for MacBooks that uses the accelerometer as a control device.
    • Is the Hourly Model Broken? - Musings from RedMonk’s Stephen O’Grady. He’s writing from the analyst perspective, but this applies just as much to developers.
    • Release 0.8.0 - Of the Mack framework, that is.
    • Splitting models into several smaller files in Rails - I’m personally not convinced big models are a problem (I’d rather look in one large file than 6 small ones when tracing code). But if you disagree, here’s a solution for loading the pieces.
    • Can’t activate rubyforge (=0.4.5) problems - Adding a bit of Google juice to this solution (uninstall and reinstall) since I ran smack into the problem tonight.

    With the imminent release of Rails 2.2, I’ve been spending a lot of time looking at the source code and git checkins. One area where developers will appreciate some small tweaks is migrations.

    If you’re not working on a multi-developer team, the default (UTC-based) numbering for migrations is a nuisance. You’ll be able to change that by setting a configuration variable:

    
    config.active_record.timestamped_migrations = false
    

    That will give you the old, integer prefixes instead of the new fancy ones. Once you have those, it becomes easier to edit and re-run a specific migration, thanks to the fact that rake db:migrate:redo now takes an optional VERSION to specify the target migration to redo.

    Finally, Rails 2.2 is getting transactional migrations - if you use PostgreSQL. Historically, multiple-step Rails migrations have been a source of trouble. If something went wrong during a migration, everything before the error changed the database and everything after the error wasn’t applied. Also, the migration version was stored as having been executed, which means that it couldn’t be simply rerun by rake db:migrate:redo after you fix the problem. Transactional migrations change this by wrapping migration steps in a DDL transaction, so that if any of them fail, the entire migration is undone.

    I’m too lazy to build from source if there’s not a good reason, and for running MySQL on OS X, I’ve yet to come across a good reason. So, I just use the MySQL Community downloads. Over the weekend I upgraded from 5.0.37 to the latest 5.1 download, because I was hard up against a MySQL bug that was fixed in later builds.

    Unfortunately, while just running the installer for 5.1 worked great, it pointed the new server at a brand new set of databases - orphaning the couple of dozen databases I was working with. This was Not Good. The fix comes in two parts.

    First, create /etc/my.cnf, with a single entry pointing to the old database files:

    [mysqld]
    datadir=/usr/local/mysql-5.0.37-osx10.4-i686/data

    Second, tell MySQL to upgrade the files:

    sudo mysql_upgrade -u root

    My latest work in progress: The Rails Initialization Process.

    The default merging behavior of git is pretty good - until it blows chunks and litters your merged file with dozens of >>>> markers. I had this happen to me again this weekend, and was finally motivated to do something about it.

    To change the default merging behavior in git, you run

    git config –global merge.tool toolname

    To see the list of available tools, type

    git mergetool

    Most of the tools that git understands are unix-y. There is one OS X tool on the list: opendiff, which launches the FileMerge tool. But honestly, I’ve never been that impressed with FileMerge’s merge algorithm.

    Fortunately, xxdiff is a pretty good tool, and it’s available as a Darwin port. So, assuming you already have your OS X box set up to install ports, you can have this as your default git merge user interface by running:

    sudo port install xxdiff
    git config –global merge.tool xxdiff

    Now files needing a merge will open in the xxdiff user interface - which is an ugly XWindows thing, but it’s powerful. I’d love to see git hook up to something like Araxis Merge or Changes (when their 2.0 version with 3-way merge comes out), but I’m not nearly motivated enough to hack around in the git source yet.

    So far October is shaping up to be a pretty interesting month.

    Anyone had to manage cucumber/webrat stories that include logging on to a session via restful authentication? How’d you do it?