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
  • Tools
  • Contact
    • Press Room
    • Press Releases
    • In The News
    • Press Kit
  • All
  • Labs
  • Standup
  • Tracker

Rails and SQL Views – Part 2 – Migrations

Dirk Kelly
Saturday, March 2, 2013

Last week I introduced that my pair and I have started using SQL Views more often in our project. This week I was going to discuss finer points on implementation, thankfully I found Josh Davis’ has_one view post at HashRocket.

The rocket example I discussed covered an activity log of all the rocket’s states RocketActivity, with a custom view being used to return the most recent of these RocketCurrentActivity. One of a few solutions to this in SQL is a sub select on the same activities table.

CREATE VIEW rocket_current_activities AS
  SELECT
    rocket_activities.status     AS status

A few weeks down the way we’re going to have some change in requirements, this is where we would drop the existing view a recreate it with the new SQL.

Getting started with migrations is helped immensely by lomba/schema_plus a gem which alongside index and foreign key improvements, also gives you a method for creating SQL views, which it then stores in you schema.rb.

class RocketActivityViewFixes < ActiveRecord::Migration
  def change
    create_view :rocket_activities, "SELECT * FROM...", force: true
  end

Unfortunately views can get long and in-depth, can change multiple times before hitting any one environment and contain important information about available columns and data types. We needed more than a one line truncation of what a view is at any point in time.

To solve this we started to store copies of our sql and store them under db/views/name_of_view/timestamp_name_of_view.sql, and call them out something like this.

class RocketActivityViewFixes < ActiveRecord::Migration
  def change
    create_view :rocket_activities, view_sql('20130215155853', 'rocket_activities')
  end

The view_sql method is rather simple, and just an example of how you could structure your query files.

ActiveRecord::Migration.class_eval do
  def view_sql(timestamp,view)
    File.read(Rails.root.join("db/views/#{view}/#{timestamp}_#{view}.sql"))
  end

As simple as this is, if you can start to drop your data joining into the dbms without impacting on support for teams and multiple environments, you're going to feel a lot less pain making the move to SQL views.

If this doesn't convince you that views are the bees knees, maybe the next time I get around to posting about how we use views to power our search indexes will be exciting to you. Once again, stay tuned.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

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

What’s Your Snow Trip Bus Count?

Dirk Kelly
Sunday, January 27, 2013

Our project’s bus count was two, until I broke my wrist on a snowboarding trip. I was left needing someone to help me with life’s basic necessities: putting my coat on, opening a bottle of red, and typing on a computer.

I can’t think of any programmers who wouldn’t be frustrated at not being able to physically code, I was certainly no different. My tried and true methods of throwing together some pseudo code, writing a failing spec, or just jumping on Github, weren’t options anymore. I had to turn to talking and expressing my opinions in spoken words, like I was in a play or something.

We got through it and ended up finding a nice rhythm. I learned to communicate more effectively and would spend more time thinking about the long term impact of stories instead of keeping my head in unspoken or unwritten implementation details.

I’ve since regained use of my hand and I’m writing this blog myself (the plan was to have my long suffering pair Meskers do it for me). Even though I’ve started catching myself going for the keyboard when I “know the solution”, I try to stop myself and remember that it can be more effective to talk things through.

I encourage you to give up the keyboard when you next find yourself pairing, see what you learn from it.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Standup 06/08/2012: Awkwardly Unprofessional

Dirk Kelly
Friday, June 8, 2012

Interesting Things

  • ObjectSpace is a class in Ruby which stores information about all instantiated objects. Great stuff for debugging, but don’t go using it in your code.
  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Standup 06/06/2012: Two Strings

Dirk Kelly
Wednesday, June 6, 2012

Ask for Help

“Capistrano is not using our ssh-config correctly, it seems the net-ssh library behaves differently to standard ssh”

Some pivots are going to dive into figuring out whether this is the case and how to get it fixed. Stay tuned!

Interesting Things

  • Ruby sort is not stable, this means that two elements which would have the same sort priority won’t always be returned in the same order. Short of implementing your own merge sort you can get around this with sort_by{ |x| n+=1; [x,n] }.
  • Selenium does not clear all sessions after a suite run, it only clears out the current domain. If you’re driving actions on multiple sites you will need to configure an after run action to visit those domains and clear session information. For what it’s worth one of our pivots has a pull request on capybara-webkit which fixes this behavior by clearing all domain information by default.
  • A couple of pivots are using github‘s KSS library on their project to keep a maintainable styleguide and set of stylesheets. There is a kss-rails gem if that’s your preferred flavor.

ctrl+z

Earlier this week we mentioned to_string and its differences to to_s and to_str. Turns out there is no to_string in Ruby, so it really is only something for you Java developers out there. Grant has explained the differences in a comment on another blog.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Standup 06/04/2012: Six Point on Tap

Dirk Kelly
Monday, June 4, 2012

Events

  • Brown Bag tomorrow at 12:30 with Shane Welch, founder of Six Point Brewery in Brooklyn. He will be joining us to share his stories of bootstrapping his business, creating his brand and engineering his beer. Interested? Sign up to the Meetup!
  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Standup 03/29/2012: Virtual Foreign Keys?

Dirk Kelly
Thursday, March 29, 2012

Interesting

  • Active Record belongs_to will not raise an exception if you haven’t run a migration to create the foreign record column. Instead it will assign a virtual attribute that persists through object reloads, but obviously not a fetch. Watch out!
  • RSpec was not raising an exception when some of our pivots were calling update_attributes with an attribute that didn’t exist. Debugging inline and using the command line will raise exceptions. So again, watch out!
  • The first parameter on an RSpec double is arbitrary in nature, but helps other developers understand what you’re thinking. Keep everyone happy by naming it something useful.
  • Our Pivots dominated at dodgeball last night, with Cathy taking out the other team in a sudden death gladiator round. We’ll be keeping the dream alive Monday next week.

Help

  • Some pivots need after deploy tasks to run on their heroku instances. Suggestions were to check out heroku_san which has support for additional tasks and great hooks (it’s also well tested!)
  • One of the projects is having trouble setting up firesass with the Rails 3.2 asset pipeline and bootstrap-sass gem
  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Standup 03/28/2012: Browser Quest

Dirk Kelly
Wednesday, March 28, 2012

Interesting

  • There’s a new MMO out from Mozilla called Browser Quest, you can grab the source over on github

Help

  • How does git figure out which gitconfig file to use? If we change the environments HOME variable git doesn’t look for the gitconfig in that new location.
  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Standup 03/27/2012: Talk like a boss

Dirk Kelly
Tuesday, March 27, 2012

Help

  • Zabes has noticed that stub_model is not working correctly in rails 3.2, even after applying the rspec fix. The problem is that stubbed objects aren’t returning valid.

Events

  • Brownbag today in the common area, Kris Hicks will be teaching us how to git rebase like a boss, this is an open event so feel free to invite your friends.
  • Dodgeball will be this Wednesday at 9pm on the UES, we’d love to have some fans and anyone signed up is welcome to come join in.
  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Standup 01/30/2012: Assigning IDs

Dirk Kelly
Monday, January 30, 2012

Interesting

  • Assigning a collection with an = operator will not set the id on the parent object, to do this use <<.

Events

  • This weeks brown bag will be on SQL, three of our Australian pivots will be presenting it. You can join our meetup group to find out more information.
  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Dirk Kelly

Dirk Kelly
New York

Subscribe to Dirk's Feed

Author Topics

postgres (1)
  • About
  • Case Studies
  • Team
  • Community
  • Careers
  • Tools
  • 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 >