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

Rails and SQL Views – Part 1

Dirk Kelly
Monday, February 11, 2013

The project we’re currently working on has a fairly system wide requirement to have objects in different “states” as a result of user actions.

The client wanted to be able to see both the current status, and a history of all the statuses each object has been in.

These two requirements felt very closely tied, to the point where really the status is just the most recent action.

This could be fairly easily modelled in a Rails application as such.

class Rocket < ActiveRecord::Base
  has_many :activities, class_name: "RocketActivity"

  def current_activity
    activities.order("created_at DESC").first
  end
end
rocket.activities.map(&:status) # [landed, landing, cruising, launch, landed]
rocket.current_activity.status # landed

This seems like a fairly typical solution, and would provide you with a fairly easy to use accessor.

rocket.current_activity.status

But what if you wanted to view all the current activities of all the rockets you have in your fleet.

@rockets.each do |rocket|
  rocket.current_activity.status
end

Works great, but creates an n+1 problem, where every line is executing a query to find all the activities and return the latest.

A solution to this is to use includes, you could define rockets as

@rockets = Rocket.scope.includes(:activities)

Still, your custom logic inside the #current_activity method is then going to have to perform more sql on that collection.

Also it shouldn’t be the Rocket’s responsibility to know how to find it’s most recent activity, that’s more of a class concern.

Given that, in Rails land as long as you had a class to take care of it, you could define that relationship as.

class Rocket < ActiveRecord::Base
  has_many :activities, class_name: "RocketActivity"
  has_one :current_activity, class_name: "RocketCurrentActivity"
end

Leaving us to include the current_activity and output more efficiently.

@rockets = Rocket.scope.includes(:current_activity)

And keep our view the same.

@rockets.each do |rocket|
  rocket.current_activity.status
end

We solved this with SQL views (Wikipedia), and next week I’m going to show you how.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Add New Comment Cancel reply

Your email address will not be published.

Dirk Kelly

Dirk Kelly
New York

Recent Posts

  • Rails and SQL Views – Part 2 – Migrations
  • What’s Your Snow Trip Bus Count?
  • Standup 06/08/2012: Awkwardly Unprofessional
Subscribe to Dirk's Feed

Author Topics

postgres (1)
  • 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 >