Pivotal Labs

Main menu

Skip to primary content
Skip to secondary content
  • About
  • Case Studies
  • Team
    • Executives
    • Locations
      • San Francisco (HQ)
      • Boston
      • Boulder
      • Denver
      • London
      • Los Angeles
      • New York
  • Community
    • Blogs
    • Tech Talks
    • Events
  • Careers
    • Lifestyle
    • Principles & Practices
    • Benefits
    • FAQ
    • Apply
  • Contact
    • Press Room
    • Press Releases
    • In The News
    • Press Kit
  • All
  • Labs
  • Standup
  • Tracker

Monthly Archives: September 2010

Semantic Logging with Splunk

Tuesday, September 21, 2010 | Run time: 1:00:56

With Splunk, developers can create sophisticated analytics for their system without the typical RDBMS and data cube. Rob Das from Splunk discusses what semantic events are, how Splunk works, and the best practices in creating semantic events.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Standup 09-21-2010: Ugg boots revisited

Pivotal Labs
Tuesday, September 21, 2010

Ask for Help

“Any issues with git-submodules in projects?”

Comments from Pivots regarding git-submodules:

  • Heroku doesn’t currently support them
  • You could use Bundler to include your potential submodules as a dependency.

“What do we do about spam on our blog posts? Disable comments?”

Our blogs have a forthcoming spam filtering service. Hopefully we will see this deployed soon! Until then, filtering is manual.

“What are people using for role-based permissions?”

  • declarative_authorization plugin
  • CanCan plugin is noted to be possibly a lighter weight solution for simpler cases.

Interesting Things

  • Enabling auto-flushing in Rails 3 should be done with care, as it can cause exceptions to be thrown when combined with nested permissions in possibly unexpected places.
  • When using default_scope, there is still issues with ordering your scopes in Rails 3.
  • Rails 3 automatically escapes user input thus adding a layer of protection against XSS attacks.
  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Presenters and Logical APIs

Pivotal Labs
Tuesday, September 21, 2010

MVC in Rails and Thick Views

The default way of using ActionController and ERB in Rails is to pass models into your views, and let the views figure out what to render and where. There’s been some pushback in the community on this, people are talking about getting rid of “thick views” with logicless templates like Mustache. Mustache is awesome, but if thick views are the problem, we don’t need to go that far if we just change the way we think about controllers a little bit.

Thick views are a controller problem

Consider this ERB, using a loop instead of partials for illustration:

<%@posts.each do |post|%>
  <%=post.author.name%>
<%end%>

If we write our controller like this, the controller will do two queries:

@posts = Post.all(:include => :author)

If we write our controller like this, it will do only one query in the controller:

@posts = Post.all

And the view will do as many queries as there are posts. I’m sure you’ve seen code like this in projects you have worked on. In the standard Rails model, we pass ActiveRecord objects to our views, they might or might not be pre-populated, and thin views can be hard to tell from thick views.

We can explicitly test this by mocking Post and counting queries, but that is a lot of extra work, and you have to remember to do it everywhere.

APIs are unit testable

In contrast to standard controller tests, the result of a JSON API call can be declaratively described. The difference between

{:posts => [:id => 4, :title => "Jerusalem", :author_id => 33]}

and

{:posts => [:id => 4, :title => "Jerusalem", :author => {:name => "Josephus, :id => 33}]}

Is pretty clear, and easy to assert on. If we TDD our controller methods this way it protects us from a lot of the n-query problems in views.

API work comes too late

I’ve seen serveral teams experience pain because Rails does not make it easy to develop a JSON API alongside your HTTP controllers. Rails 3 is better than Rails 2 on this, but you still have to handle the cases separately, particularly as things get more complex.

Twitter is a good example of this. The HTML endpoint recently started consuming its own JSON API over HTTP for generating pages:

One of the most important architectural changes is that Twitter.com is now a client of our own API. It fetches data from the same endpoints that the mobile site, our apps for iPhone, iPad, Android, and every third-party application use. This shift allowed us to allocate more resources to the API team, generating over 40 patches. In the initial page load and every call from the client, all data is now fetched from a highly optimized JSON fragment cache.

This is a very cool pattern in general for a web application. Consuming your own API keeps your business logic in one place, separate from your display logic. And caching on JSON API calls can be easier than caching after building HTML. Obviously you don’t want to run two processes when you’re getting started, but we can take inspiration from this as we organize our code.

The Presenter pattern

A Presenter is a controller that delivers data rather than objects. People like Martin Fowler have been talking about this for a while, and Twitter recently announced a major technical change along these lines.

From the Wikipedia article on “Presenter First”, which is mostly aimed at desktop design, but is applicable to the web, too:

When used in GUI applications, this approach allows the presentation logic and business logic of the application to be developed in a test first manner decoupled from on-screen widgets. Thus, the vast majority of the application programming can be tested via unit tests in an automated test suite. In so doing, the reliance on GUI testing tools to perform extensive system testing can be reduced to verifying basic GUI operation or eliminated entirely.

Unlike standard Rails TDD, if you construct your page data as an API call, your controller tests can now assert directly on that data, instead of the objects that your templates can query with. Testing on a data dictionary is more declarative, and it helps you write thinner views.

Make your view a logical client of your API

We can use the Presenter pattern in Rails by having our controllers call the methods that generate our JSON API at the moment right before serialization to a string. That way there is only one code path that does business logic, which solves the divergence problem.

Vanna

Vanna is an exploration of how MVP can work in Rails. It’s not fully functional (in particular it needs a way to do non-200 returns), but it is enough to illustrate the point. Mixing Vanna into ActionController::Metal restructures controller flow to mimic JSON API calls. Your controllers wind up looking like this:

class VillainsController < ApplicationController
  def index
    {:main => {"villains" => Villain.all}}
  end

  def show(opts = params)
    villain = Villain.named(opts["villain"]).first
    sidebar = catchphrases("villains" => villain["partners"])
    {:main => {:villain =>villain, :sidebar => sidebar}}
  end

  def catchphrases(opts=params)
    names = opts["villains"]
    Villain.named(names).map{|p| p["catchphrase"]}
  end
end

How does this differ from a standard Rails controller? For one thing there’s a silly “catchphrases” method, which is a placeholder for an API method that gives a set of fields for a set of records:

def catchphrases(opts=params)
  names = opts["villains"]
  Villain.named(names).map{|p| p["catchphrase"]}
end

This is structured like an API call. It expects to take in a set of keys, and return some subset of fields on the objects with those keys. Exactly the sort of thing an API does, but not something that you usually see in web apps in their early stages. There’s also an explicit (opts=params) in the signature. Let’s take a look at the show method to see why that is there:

def show(opts = params)
  villain = Villain.named(opts["villain"]).first
  sidebar = catchphrases("villains" => villain["partners"])
  {:villain =>villain, :sidebar => sidebar}
end

On the second line of the method we are explicitly calling one method in a controller from another, passing a params hash (suggested by Richard Crowley). We construct a data dictionary for these smaller calls and pass it through to our template.

Here’s what the view looks like:

<div id=main style="width:70%;float:left;border:black 5px solid;">
  <ul>
    <li><%=villain[:name]%></li>
    <li><%=villain[:catchphrase]%></li>
  </ul>
</div>
<div id=sidebar style="width:20%;float:right;border:black 5px solid;">
  <% sidebar.each do |catchphrase| %>
    <%=catchphrase%> <br/>
  <% end %>
</div>

This looks almost exactly like a standard Rails ERB template, except that the top level objects available to you are accessed as locals, not with an @.

API for free

Vanna makes all your controller methods available as API calls automatically. Because you are explicitly returning a data dictionary, there’s no need to have a different code path for your HTML and JSON. The only difference is whether you go to ERB, or call to_json on the dictionary. So now we can do our controller tests as API tests (the tests in Vanna itself are a little different):

 def test_catchphrases
   header "Accept", 'application/json'
   get "/villains/catchphrases?villains=luis"
   assert{ JSON(last_response.body) == ["Hungry like the volcano!"] }
 end

So OK, we can call our catchphrases method as a JSON call.

def test_show_has_catchphrases
  header "Accept", 'application/json'
  get "/villains/show?villain=luis"
  assert{ JSON(last_response.body)["main"]["sidebar"] == ["You're gonna get punted!"] }
end

And the same data is available inside the larger call which includes it.

def test_html_has_sidebar
  get "/villains/show?villain=luis"
  assert{last_response.body.match(/div id=sidebar/) != nil }
end

And the template actually renders out the sidebar.

Now we have a single data retrieval code path, that breaks off into HTML right before we actually render HTML.

The code for Vanna is on Github, but here’s the meat of it:

module Vanna
  def self.included(klass)
    raise "#{klass.name} does not inherit from  ActionController::Metal" unless  klass.ancestors.include?(ActionController::Metal)
    klass.send(:include,  AbstractController::Layouts)
    klass.send(:include,  AbstractController::Callbacks)
    klass.append_view_path "app/views"
    klass.class_eval("def logger; ActionController::Base.logger; end;")
  end

  def process_action(method_name, *args)
    run_callbacks(:process_action, method_name) do    dictionary = send_action(method_name, *args)    dictionary = @layout_pieces.merge(dictionary) if @layout_pieces  && dictionary.is_a?(Hash)    self.response_body = request.format.symbol == :json ?
 dictionary.to_json : html_render(dictionary)
    end
  end
  def html_render(dictionary)
    render(nil, :locals => dictionary)
  end
end

It’s an example more that a real tool – it’s a demonstration of a valuable way to think about building web applications.

Try it out

It’s extremely rough still, but it serves pages. Here’s the setup:

Gemfile

gem 'vanna', :git => 'git://github.com/MikeSofaer/vanna.git'

ApplicationController

Change ‘ActionController::Base’ to ‘Vanna::Base’

layouts/application.html.erb

Remove the javascript_include line. (and if you know what to do so this isn’t necessary, tell me.)

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Mike Gehard

Using Firebug with WebDriver in Capybara/Cucumber

Mike Gehard
Tuesday, September 21, 2010

Ever wanted to be able to debug an HTML page using the power of Firebug while running Cucumber/Capybara features/steps?

Follow these simple steps and you can get it to work:

1) Create a new “WebDriver” Firefox profile using the instructions found here

2) Fire up Firefox using the newly created profile and install/configure Firebug the way you want it. See instructions above.

3) Run your Cucumber/Capybara steps and pause the feature using a sleep() statement long enough for you to poke around in the page with Firebug.

**Note this has been proven to work on OS X, your mileage on other OS’s may be limited.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Mike Barinek

Scoping with confidence

Mike Barinek
Monday, September 20, 2010

We’ve recently scoped several projects in Boulder. While scoping, several clients asked how we’re able to estimate a project’s cost with such confidence. I’ve thought about this a bit and I actually think this is pretty interesting and remarkably similar to something we’ve all been doing for a while: estimating user stories in Tracker.

Scoping a project is very similar to determining the number of points or weight you might assign to a user story or feature in an Agile backlog. Similar to measuring the relative size or complexity of a feature, we’re just measuring the relative size or complexity of the project against similar projects that we’ve completed. The important piece here is that we’re measuring against completed projects.

With stories or features you estimate size and then derive duration in order to achieve a running feature velocity. Feature velocity is essential and the key to predictability. Completing features and measuring their associated duration is the empirical data we use to determine when a future set of stories will be completed or delivered. When scoping a project we’re missing this empirical data, although we still need to actually provide a duration to calculate the project’s cost. So how do we estimate a project’s scope and cost?

Imagine estimating a feature that you just completed for another project. You’d probably be pretty close on the points assignment as well as confidence. Now apply this to a project. It’s becomes easier to scope a project when you’ve completed a few similar projects. The more projects the better the comparison and resultant estimate.

Completed projects are valuable because we know how long they took to complete. For example, client A’s CRM was roughly 1 pair for 2 months. Client B’s CRM required 2 pairs for 4 months. And client C’s CRM, the one we’re currently estimating, is slightly more complex than client A’s although much less complex than client B’s. We’ll likely estimate client C’s CRM at 2 pairs for 2 months.

It’s actually not all gravy. There are several risks that may increase a project’s scope. For example, if we’re up against an aggressive timeline, we may include an additional pair for a few weeks to help increase feature velocity. Similarly, if there are complex integrations, like a 3rd party billing system or external messaging subsystems, we may include an additional pair for a month.

During an initial scoping we help reveal or tease out high level risks and then prioritize theses risks against constraints like timeline and budget. The more similar the risks we’ve resolved on completed projects, the more confidence we have to estimate risks during a new project scoping. Again, pretty similar to how we estimate features in a backlog. We’re just estimating the size or complexity of risks against similar risks with known durations.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Standup 2010-09-20: Your Weekend Was Short Because of GoGaRuCo Edition

Pivotal Labs
Monday, September 20, 2010

(Title: Standup 11/31/2000: Something Interesting from the post)

Ask for Help

“Storage free/DB-less ActiveRecord (in Rails 2)?”

This seems to be readily available in Rails 3. For those who would not like to upgrade their projects, the following options have been suggested:

  • ActiveHash & ActiveYAML by our very own Jeff Dean.
  • ActiveRecord::Base Without Tables
  • The initial query was for form validations, so the ActiveForm plugin may be of use here.

“Restricting ActiveRecord API?”

Sometimes you want extra assurance Bad Things are not being done by the wrong users. Possible solutions to lock permissions and such:

  • User plugin from our Socialitis project
  • A mysterious plugin known as Alcatraz, link not available at this time.

Interesting Things

  • Rails 3 controllers will run after_filters if you return false in the before_filter. This is deemed to be good behavior, but be aware of it.
  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Mike Gehard

Packaging Cucumber step definitions for reuse

Mike Gehard
Monday, September 20, 2010

So I’ve been doing a bunch of BDD development these days using Cucumber as a starting point.

While working with client, the question came up about how they could share step definitions across multiple teams of developers.

I then remembered that the Aruba gem is just that, a collection of Cucumber step definitions.

So if you are looking for a way to start packaging up those step definitions that you have used on multiple projects and are tired of copying across projects, check out how the Aruba gem does it and go from there.

Thanks to the Cucumber and Aruba folks for sharing some very useful technology that allows us all to raise the bar when it comes to delivering quality software.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Dan Podsedly

New Account Management Features in Pivotal Tracker

Dan Podsedly
Saturday, September 18, 2010

We’re introduced new features in Pivotal Tracker to help with account management. Accounts tend to stay out of the way for most people, but they can be essential for larger companies, especially consulting companies like ours. They allow users to separate their personal, open source, and company projects, for example, and to share administrative abilities and permissions for related groups of projects with other users.

Continue reading for details about these new features.

My Accounts

Accounts can be managed on the My Accounts page, which now separates accounts you own from accounts that you’re helping to manage/administer.

Read more about what accounts are, including the different types of account roles, in this section of the FAQ.

Account Owners and Admins

Accounts now have single owners, and multiple admins. Previously, accounts could have multiple owners. For those accounts, we’ve made the very first owner of that account as the account’s new single owner, and made everyone else an admin.

All account admins have the same access to the account’s projects, and any of the admins can choose to take ownership of the account. Ownership is mostly just a token, it lets everyone know which individual is responsible for the account.

Account Member Management

The Account Members page allows you to see and manage everyone who is a member of a project within your account, as well as people with special account roles, like Admin and Project Creator. For accounts with time functionality enabled, the list will also include Time Keepers and Time Enterers.

By default, the Members page shows everyone involved with the account. Use the role filter buttons to the right of the View label at the top of the page to see account members with specific roles only. You can also search for members by name or email address by using the Filter field at the top right.

The Members page allows you to add members to the account directly, based on email address. These can be people who are already users of Tracker, or people you’d like to invite to participate in projects or administration of the account. Use the Add Member button to add people to the account.

The Actions popup in the list allows you to do a number of things, including:

  • adding an account member to a specific project, or to all projects in the account
  • removing a person from all project in the account
  • changing the roles and permissions of an account member, for example to an Admin or Project Creator
  • giving account members permission to create new projects in the account
  • for accounts with Time enabled, designating account members as “time enterers” or “time keepers”

You can learn more about account roles in the FAQ.

Deleting Accounts

Accounts can now be deleted by account owners or admins, on the Settings tab of the Account page. Deleting an account is permanent, and removes all projects and stories within the account. Be careful, there may be projects in the account that you may not be aware of.

Account Project list

You can now see all of the projects in a given account, on the Projects tab of the Account page. This page also allows you to create new projects within the account, as well as archive projects.

Limit Project Invitations to Account Members

Account owners and admins can now restrict who may be invited to projects by project owners in the account. When this option is enabled (on the Account Settings page), new project invitations are limited to people who are already members of the account, and explicitly listed on the Account Members page. This is useful if you’d like to limit access to company projects to specific employees only. By default, owners of projects in the account can invite anyone to their project.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Building a fast, lightweight REST service with Rails 3

Pivotal Labs
Friday, September 17, 2010

I recently started building a Rails 3 app that will function as an internal REST service. I wanted it to be as lightweight and fast as possible, both to test and to run. Here are a few ways I configured the app to be a bit faster:

  • Defined a limited route set
  • Removed ActiveResource
  • Removed unnecessary middleware
  • Created a custom controller that inherits from Metal

First, I defined the public api for my app in the routes file. I chose not to use resources because

  • I don’t need named routes
  • I wanted the :id parameter for the show action to be named :account_id instead of id (a pet peeve of mine with Rails routing)
  • I only needed 3 of the routes generated by resources

The routes file ended up looking like this:

scope "/api/v1" do
  scope "/accounts" do
    post "/" => "accounts#create"
    get ":account_id" => "accounts#show"
    get ":account_id/transactions" => "accounts#transactions"
    put ":account_id" => "accounts#update"
  end
end

Next, to get rid of ActiveResource, in application.rb I deleted the line the requires rails/all and replaced it with:

# config/appliction.rb
require "rails"

%w(
  active_record
  action_controller
  action_mailer
).each do |framework|
  begin
    require "#{framework}/railtie"
  rescue LoadError
  end
end

Rails has a lot of middleware that I didn’t need for a stateless service like this. This app will be run as a single-threaded app, behind a firewall, with no session or cookies, no views, it will only be accessed via an HTTP library and I’ll likely never open it in a browser even locally. As such, I added this to my application file:

# config/application.rb
[
  Rack::Sendfile,
  ActionDispatch::Flash,
  ActionDispatch::Session::CookieStore,
  ActionDispatch::Cookies,
  ActionDispatch::BestStandardsSupport,
  Rack::MethodOverride,
  ActionDispatch::ShowExceptions,
  ActionDispatch::Static,
  ActionDispatch::RemoteIp,
  ActionDispatch::ParamsParser,
  Rack::Lock,
  ActionDispatch::Head
].each do |klass|
  config.middleware.delete klass
end

# config/environments/production.rb
config.middleware.delete ActiveRecord::ConnectionAdapters::ConnectionManagement

I was surprised by that last one. It’s a rack middleware class sitting in ActiveRecord whose sole purpose is to not close connections in test mode. It seems to me that Rails should just include that class in environments/test.rb, as opposed to having it in every environment. It probably doesn’t matter much, since it’s only going to add a few nanoseconds to each request.

I didn’t need any view rendering at all, so I deleted app/views and app/helpers, then created my own ApplicationController class with just the modules I needed:

class ApplicationController < ActionController::Metal
  include AbstractController::Logger
  include Rails.application.routes.url_helpers
  include ActionController::UrlFor
  include ActionController::Rendering
  include ActionController::Renderers::All
  include ActionController::MimeResponds
end

In my case this was the minimum set of modules necessary to make my tests pass. Unfortunatley, these modules are still very poorly documented, so to figure out which ones I needed I had to:

  • Copy all the code from ActionController::Base into my ApplicationController
  • Delete modules one by one, testing after each one was removed and only leaving in the ones that broke the tests when they were removed

In my controller I just used render :json => object, as opposed to the new respond_to because I don’t really care to check the accept header for every request. For now there will only be json responses, regardless of what you ask for, so I didn’t bother with adding the additional overhead. Here’s what an action looks like:

class AccountsController < ApplicationController
  def show
    render :json => Account.find(params[:account_id])
  end
end

I normally use cucumber for integration testing, but for an app like this I decided to use rspec 2′s new request spec format, which is lighter but still exercises the stack. It looks something like this:

# spec/requests/api_spec.rb
require 'spec_helper'
describe "api" do
  describe "GET /api/v1/accounts/:account_id" do
    it "returns a json hash with the proper data" do
      get "/api/v1/accounts/abc123"
      Yajl::Parser.parse(response.body).should == { "id" => "abc123", "billing_date" => "12/12/2009" }
    end
  end
end

In the end, this has translated to slightly faster load times, faster test runs and faster responses in production without altering the things I like best about Rails.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Dan Podsedly

Tracker maintenance tonight at 8:30pm PDT

Dan Podsedly
Friday, September 17, 2010

We will be performing a maintenance update to Pivotal Tracker tonight (Friday, Sep 17) starting at 8:30pm PDT. Anticipated downtime is under one hour.

This update will include a few performance improvements, bug fixes, and some new account management features.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Topics

  • agile (778)
  • rails (113)
  • testing (86)
  • ruby (83)
  • ruby on rails (70)
  • jobs (62)
  • javascript (54)
  • techtalk (44)
  • rspec (38)
  • activerecord (29)
  • productivity (29)
  • gogaruco (29)
  • ironblogger (29)
  • git (28)
  • nyc (27)
  • rubymine (25)
  • mobile (22)
  • bloggerdome (20)
  • cucumber (20)
  • process (19)
  • pivotal tracker (19)
  • jasmine (19)
  • design (18)
  • ios (18)
  • webos (17)
  • objective-c (17)
  • android (16)
  • palm (16)
  • "soft" ware (16)
  • fun (15)
  • tracker ecosystem (15)
  • ci (15)
  • cedar (15)
  • rails3 (14)
  • performance (14)
  • bdd (14)
  • gem (13)
  • selenium (12)
  • css (12)
  • goruco (12)
  • bundler (12)
  • tdd (12)
  • meetup (11)
  • railsconf (11)
  • nyc-standup (11)
  • capybara (10)
  • mac (10)
  • mojo (10)
  • chef (10)
  • rubygems (9)
Subscribe to Community Feed
  1. ←
  2. 1
  3. 2
  4. 3
  5. 4
  6. →
  • About
  • Case Studies
  • Team
  • Community
  • Careers
  • Contact
  • Labs
  • Events

Contact Us

contact@pivotallabs.com
+1 415-77-PIVOT
TwitterLinkedInFacebook

Pivotal Tracker

Tracker is the award-winning agile project management tool that enables real-time collaboration around a shared, prioritized backlog.
Visit pivotaltracker.com >