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
Pivotal Labs

"Missing host to link to!" Rails 2.3 Upgrade Issue

Pivotal Labs
Monday, August 3, 2009

During the process of upgrading a project from Rails 2.2.2 to Rails 2.3.2 several of our tests were breaking with the error:

Missing host to link to! Please provide :host parameter or set default_url_options[:host]

This error was most commonly occurring in model specs where we had mixed in ActionController::UrlWriter in order to get access the named routes (e.g. invitation_path) inside of the model class. I believe this change in a behavior is the result of this patch to Rails but I am not certain. Interestingly the code falls apart in the tests but it still works fine within the browser.

With the assistance of Adam Milligan we were able to find an acceptable way to handle setting the default_url_options in the test environment.

# app/models/invitation.rb
class Invitation < ActiveRecord::Base
  include ActionController::UrlWriter

  ...
end

# spec/models/invitation_spec.rb
describe "Invitation" do
  before(:all) do
    Invitation.default_url_options[:host] = 'localhost'
  end
  after(:all) do
    Invitation.default_url_options[:host] = nil
  end
  ...
end

As I wrap up I want take a moment a properly shame myself for generating urls in the model. There is definitely a good argument that you should not be using named_routes in your models and I am eager to agree. Rails makes it hard to do for a reason and if you find yourself ever explicitly including UrlWriter take a step back and think the problem over. You may find yourself needlessly going down the wrong path and a different approach is in order.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Joseph Palermo

How do you use named_scopes?

Joseph Palermo
Wednesday, July 29, 2009

You may have heard of some problems we’ve had with changes to named_scope in Rails 2.3.

The basic change is that when chaining named scopes together, their scoping does not apply only to the finder class, but also to any lambdas evaluated farther along the named scope chain.

So given a User class with a friends association (pointing at other Users) with the following named_scopes:

named_scope :named_bob, {
  :conditions => {:name => 'bob'}
}

named_scope :second_degree_friends, lambda{|user|
  user_friends = user.friends
  second_degree_friend_ids = user_friends.collect{|u| u.friend_ids}
  {
    :conditions => {:id => second_degree_friend_ids.flatten}
  }
}

These two calls are no longer the same.

User.second_degree_friends(user_sam).named_bob

User.named_bob.second_degree_friends(user_sam)

The first call does what we expect (giving us all of user_sam’s second degree friends who are named bob. But the second call actually gives us something different. Because the named_bob scope comes first in the chain, when it evaluates the lambda for second_degree_friends, it applies it in the scope of all previous named scopes. So our call to the user.friends association is actually scoped with the additional condition of :name => 'bob', which is probably not what we want in this case.

You can see the lighthouse ticket where I claim this should not be the default behavior of named scopes. But my question right now is, “How do you use named scopes?”

I tend to use them in a composable manner, especially in search objects. I take a base finder such as User or User.friends and then I pass it down to a add_conditions or add_sort method. Inside those methods, they add on any other named scopes they need to and return the new finder object. So inside of this chain, you never really know what finders have been applied already, but in the past, you didn’t need to know because the same named_scope with the same parameters always gave you the same conditions.

Often there will be one search object that inherits from another, say for instance LocationUserSearch < UserSearch that adds geo targeted searching on top of UserSearch. In these cases, we can just create our own add_conditions method, call super and tack on any new conditions that we need. Since conditions and joins are merged in scopes, this normally works out great.

Do you use named scopes in a composable way such as this? Or do you only combine them in a known way and might benefit from having the accumulated scope applied to the lambda?

Feel free to add your comments to the lighthouse ticket too.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Chad Woolley

The Great Ruby IDE Smackdown of '09

Chad Woolley
Thursday, July 16, 2009

In a recent thread on the East Bay Ruby Meetup list, several people chimed in with Ruby IDE suggestions. I suggested RubyMine, which we use at Pivotal. Several people mentioned NetBeans and Aptana RadRails, so I decided to have a little contest.

Now, if I am going to work in an IDE and sacrifice the speed of a text editor, I want to see it work for me (’cuz RubyMine can chew through all your CPU and RAM and then some faster than you can say Moore’s Law). That means understanding Ruby, and using that information to save me some significant thinking and work.

I don’t mean code-generation macros or dumb context-aware keyword-completion, I mean something useful like knowing where my classes and methods are. In my book, that leaves out Emacs, Vi, and even TextMate, regardless of their other merits (sorry people, I like text editors too, but I’m making up this test – flame away, the comments section is below).

So, here’s the smackdown scenario:

  • Download the latest NetBeans, RadRails and RubyMine.
  • Open a Ruby project, this example is one of mine (I wrote this three years ago to learn Ruby, so don’t make fun of me for doing dumb stuff…)
  • Test the ability of the IDE to navigate through Ruby language constructs. This should be easy, it is a command-line app using a Dependency Injection architecture, no metaprogramming curveballs!
    • Open the root Ruby class for the project (lib/geminstaller.rb)
    • Pick a variable (app in self.install)
    • Try to work back to the class declaration (GemInstaller::Application) using IDE navigation (Command-click in all the IDEs, although sometimes they ignore you)

Result? RubyMine succeeded, NetBeans and RadRails failed miserably. Here’s what happened in each:

NetBeans

  1. Click create_application class method reference in app = create_application. NetBeans takes me to the method declaration in same class.
  2. Click the app method in registry.app.

FAIL! ANGRY BEEP! app is an attr_accessor on another class, NetBeans can’t find it.

RadRails

  1. Click create_application class method reference in app = create_application. RadRails takes me to the method declaration in same class.
  2. Click app method in registry.app. RadRails takes me to the attr_accessor on the Registry class (without a prompt, and highlighting the symbol, which is even better than RubyMine).
  3. Click (and F3) on the :app symbol argument to attr_accessor.

FAIL! ANGRY BEEP! RadRails can’t figure out the symbol parameter to attr_accessor. It says “Current text selection does not resolve to a Ruby element”.

RubyMine

  1. Click create_application class method reference in app = create_application. RubyMine takes me to the method declaration in same class.
  2. Click app method in registry.app. RubyMine pops up a dialog asking if I mean the attr_accessor on the Registry class, or the local variable I’m declaring. That’s rather silly, I admit, but the point is it followed the reference to another class.
  3. Click on the attr_accessor choice. RubyMine takes me to the attr_accessor line in Registry.
  4. Click on the :app symbol argument to attr_accessor. RubyMine takes me to the point where the @app instance variable is initialized.
  5. Click on the Application class name in the GemInstaller::Application.new constructor invocation. RubyMine pops up a dialog asking if I mean the Application class in my application, or two other Application classes that happen to be in my Ruby installation. This is also a silly question – it should have known the correct choice because of my namespacing, but it still found the class.
  6. Click on the GemInstaller:Application choice. RubyMine takes me to the class declaration.

SUCCESS! RubyMine drilled all the way to the class declaration, even through an attr_accessor, albeit with a couple of stupid questions.

Summary

I personally think this is a Big Deal. In the past, I’ve mocked Ruby IDE functionality as a poor simulacrum of the vast power in Java IDEs. When using Eclipse in Java, I could perform epic refactorings, extracting superclasses and adding parameters to method signatures; refactoring scores of classes across multiple projects in a few mighty keystrokes. Yes, I’m fully aware that this is because Ruby is a dynamic language, but that doesn’t make me miss a real refactoring IDE any less, and others have long lamented these shortcomings, as well.

So, for years, even though I’d always indulge my pairs if they wanted to use an IDE, I’ve done all my personal hacking with a fast, lightweight text editor and command line tools. To me, the benefits of a memory- and processor-sucking IDE with tons of unnecessary, unconfigurable, resource-eating tiny-ass-fonts and chrome did not justify giving up the speed and responsiveness of a great text editor.

However, RubyMine can now navigate code for me. I don’t have to think and manually find that class, RubyMine knows where it is. Granted, that ain’t no Extract Superclass, but it saves me a lot of thought and time, both of which are increasingly rare commodities for me.

To be fair, this is really just a problem related to parsing and interpreting attr_accessor declarations, and I expect that NetBeans and RadRails will pass this test as well in another release or two. That’s all great news, because it means that Ruby IDEs are finally, slowly, coming of age. I think I’ll still be waiting a long time for an automated Modify Method Signature refactoring, though…

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Joe Moore

Standup 06/25/2009: return vs. next vs. break vs. yslow vs. cap

Joe Moore
Thursday, June 25, 2009

Interesting Things

  • You can never return: … except when you can. From a block, that is. Returning from a block rarely works:

    result = ['one', 'two'].each do |x|
     return x
    end
    => LocalJumpError: unexpected return
    

    But, you can pass next and break arguments, which will allow you to assign return values from the block:

    result = ['one', 'two'].each do |x|
      break(x)
    end
    => "one"
    
    
    result = ['one', 'two'].each do |x|
      next(x)
    end
    => ["one", "two"]
    

You can return from a lambda, though.

  • Check out Google Page Speed, which is like Yahoo’s YSlow, only “better.”

    Page Speed is an open-source Firefox/Firebug Add-on. Webmasters and web developers can use Page Speed to evaluate the performance of their web pages and to get suggestions on how to improve them.

  • Like chef? Love capistrano? Check out chef-deploy, which “… Uses the same directory layout as capistrano and steals the git remote cached deploy strategy from cap and adapts it to work without cap and under chef.”

  • SFTUG FTW! Another successful SF Tracker User Group Meetup on 06/24. Watch for future events on the Meetup site.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Joe Moore

Standup 06/23/2009: Multi-table Inheritance?

Joe Moore
Tuesday, June 23, 2009

Ask for Help

“Has anyone implemented mutli-table (class table) inheritance in Rails, as apposed to single table inheritance (STI)?”

  • There are some plugins that nobody has tried, such as inherits_from
  • What about a view to represent the super set of tables and rows?

“We’re looking for a dead-simple, drop-in JS rating or ‘starting’ plugin.”

Check out the start-rating jQuery plugin. Any other suggestions?

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

Great Erector intro

Pivotal Labs
Monday, June 15, 2009

by Russell Edens. He has a great take on why Erector is interesting, complete with code examples:

With erector [views] are first class plain old ruby objects. Why is this good? It gives you all the tools of inheritance and mixin’s for your views. That is cool. Especially for an application with multiple views of the same underlying models. You can refactor your views into base classes that derive and render the same data in different ways. This is object oriented design for views. Nice.

I’ve seen object oriented view code in other languages and it leads to some very powerful re-use that all OO programmers can understand. The most ambitious of these attemps was by an HR company …[that] created their own markup language that was object oriented. The nature of HR data is that it has very complicated rules regarding who can see what data and when. The OO design of the language allowed that to be abstracted to the base classes and a functional programmer simply focused on the problem at hand. They took it further, as all commercial enterprise applications do, and they allowed the customer to define new models and views. Those views were very easy to write with this advanced data access logic abstracted out. Their customers loved it. They wrote very advanced business applications on top of this abstraction.

Views as simple classes, methods, and objects in Ruby – perfect!

Erector Hello World:

class Hello < Erector::Widget
  def content
    html do
      head do
        title "Hello"
      end
      body do
        text "Hello, "
        b "world!"
      end
    end
  end
end

For more see the Erector user guide.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Monkey Patch Du Jour

Alex Chaffee
Sunday, May 24, 2009

The following monkey patch gives a bit more information in the ActiveRecord SQL logs. Instead of just saying “User Load” it also says the file and line number in your code that asked AR to perform the operation. That way you can have a hope of tracking it down and optimizing it away if at all possible.

  User Load (0.2ms) views/main_page.rb:107:in `filters_box'   SELECT * FROM `users`

Code after the jump. I guess you put it in environment.rb with all the other monkeys.

    module ActiveRecord
      module ConnectionAdapters
        class AbstractAdapter
          def log_info(sql, name, ms)
            if @logger && @logger.debug?
              c = caller.detect{|line| line !~ /(activerecord|active_support|__DELEGATION__)/i}
              c.gsub!("#{File.expand_path(File.dirname(RAILS_ROOT))}/", '') if defined?(RAILS_ROOT)
              name = '%s (%.1fms) %s' % [name || 'SQL', ms, c]
              @logger.debug(format_log_entry(name, sql.squeeze(' ')))
            end
          end
        end
      end
    end
  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Capturing Standard Out In Unit Tests

Alex Chaffee
Monday, May 11, 2009
    def capturing_output
      output = StringIO.new
      $stdout = output
      yield
      output.string
    ensure
      $stdout = STDOUT
    end

then…

    it "exits immediately from --version" do
      output = capturing_output do
        lambda {
          Erector.new(["--version"])
        }.should raise_error(SystemExit)
      end
      output.should == Erector::VERSION + "n"
    end
  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Erector 0.6.3 – Now Ready to Conquer The World

Alex Chaffee
Wednesday, May 6, 2009

[Updated: added instructions "If you are using a widget in rails, you now need to inherit from RailsWidget"]

Erector has been around for almost 2 years now, but we’ve always been a little reluctant to market it heavily. One reason has been that the API was a little inelegant. Another is that Rails integration wasn’t as seamless as we’d like.

With today’s release of version 0.6.3, we have hopefully fixed both of those problems. With the new RailsWidget we’ve got a clean separation between core Erector functionality and the magic we need to make it work with Rails. We’ve renamed “render” to “content” so we don’t conflict with the standard Rails render method. And we’ve changed the API for smoother lifecycle management — the constructor is about initializing the widget, and the refurbished “widget” method is about setting it up to emit its HTML.

The bad news is that you’ll have to change your existing code. The good news is there’s an update guide, which you’ll find below the fold in this blog post.

Please visit our Google Group to register comments or complaints, our project web site for full documentation and FAQs, and feel free to clone or fork our GitHub repo.

(Why 0.6.3 and not 0.6.0? Because we had to work through some glitches in the new deploy process with GitHub and Jeweler and whatnot. We’re only human…)

Erector 0.6.0 Announcement

This release is the first major API change to Erector. It will definitely break
existing code. Sorry about that, but we promise it’ll be cleaner afterwards.

Quick Update Guide

  • Rename ‘def render’ to ‘def content’ in all your widgets

  • If you are using a widget in rails, you now need to inherit from
    RailsWidget to get helper goodness

  • Change MyWidget.new(helpers, assigns, output) to just
    MyWidget.new(assigns)

  • To render a widget from inside another widget, use

    widget MyWidget, :foo=>2
    

    or

    widget MyWidget.new(:foo => 2)
    
  • If you want your variables to have attr_readers, use ‘needs’

  • If you want your widgets to be more self-documenting, use ‘needs’

Major API changes

  • “new” and “to_s” have been changed to clarify the lifecycle of a widget,
    so “new” accepts permanent state (”assigns” variables) and “to_s” accepts
    temporary, rendering state (output stream, helpers, and prettyprinting).
    This lets you do things like make collections of widgets in once place in
    your code and render them in another place.

  • Renamed “render” to “content”, which removes confusion/ambiguity with
    Rails’ “render” method and concept, and also allows “render :partial” to
    be made to work (though we’re not sure if that totally works yet).

  • To render a widget from outside code, the pattern is:

    w = DateWidget.new(:when => Time.now, :title => "Nap Time")
    puts w.to_s(:helpers => some_rails_view)
    
  • To render a widget from inside another widget:

    def content
      # first way... pass class and assigns
      widget DateWidget, :when => Time.now, :title => "Nap Time"
      # second way... pass instance
      widget DateWidget.new(:when => Time.now, :title => "Nap Time")
    end
    

    Using “widget” will improve performance over calling “raw foo.to_s” or
    whatever since it reuses the same output stream.

  • To declare variables — and raise an exception when one is not provided:

    class JohnLennon < Erector::Widget
      needs :love
    end
    
  • Formerly, every ‘assigns’ variable had an attr_reader defined for it. Now,
    only variables declared with ‘needs’ get attr_readers.

Other changes:

  • Removed Widget#to_s caching, which fixed indentation issues.

  • BUGFIX: Indentation level is now correctly propagated to nested widgets.

  • Erector’s Rails support strategy has changed. The released version of
    Erector only supports the latest stable Rails version (currently 2.3.2).
    If you need support for earlier versions of Rails, there are separate Git
    branches for each one, but we will not be in the habit of keeping these up
    to date with the latest features and patches. If someone wants to do a
    merge to a prior Rails branch, Brian will be happy to help :-)

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

Inspect running ruby processes using xray and kill -3

Pivotal Labs
Friday, March 20, 2009

We made a code change and deployed to demo, and all the sudden some of our ruby processes were eating a ton of CPU against our full dataset.

In the java world you can send a SIGQUIT to any running java process and get a thread dump. Go ahead, run a java process and kill -3 it.

You can get this in the ruby world by using xray:

sudo gem install xray

Drop this into your code:

require "xray/thread_dump_signal_handler"

Now:

kill -3 <ruby pid>

Look in the log file where you’re sending stdout. You’ll see something like:

=============== XRay - Done ===============
/usr/lib64/ruby/gems/1.8/gems/eventmachine-0.12.0/lib/eventmachine.rb:224:in `call'
    _ /usr/lib64/ruby/gems/1.8/gems/eventmachine-0.12.0/lib/eventmachine.rb:224:in `run_machine'
    _ /usr/lib64/ruby/gems/1.8/gems/eventmachine-0.12.0/lib/eventmachine.rb:224:in `run'
    _ /usr/lib64/ruby/gems/1.8/gems/thin-1.0.0/lib/thin/backends/base.rb:57:in `start'
    _ /usr/lib64/ruby/gems/1.8/gems/thin-1.0.0/lib/thin/server.rb:150:in `start'
    _ /usr/lib64/ruby/gems/1.8/gems/thin-1.0.0/lib/thin/controllers/controller.rb:80:in `start'
    _ /usr/lib64/ruby/gems/1.8/gems/thin-1.0.0/lib/thin/runner.rb:173:in `send'
    _ /usr/lib64/ruby/gems/1.8/gems/thin-1.0.0/lib/thin/runner.rb:173:in `run_command'
    _ /usr/lib64/ruby/gems/1.8/gems/thin-1.0.0/lib/thin/runner.rb:139:in `run!'
    _ /usr/lib64/ruby/gems/1.8/gems/thin-1.0.0/bin/thin:6
    _ /usr/bin/thin:19:in `load'
    _ /usr/bin/thin:19

(that’s thin patiently waiting to service the next request)

A one-line code drop-in results in a powerful new inspection tool. Pretty neat.

For bonus points:

ps ax | grep "thin server" | grep -v grep | awk '{print $1}' | xargs kill -3

For more bonus points, stick this in a capistrano task and grab the thread dumps from your logs, and you’ll have a cluster-wide snapshotting tool.

We kill -3′d our CPU-eating thins and discovered a directory scan problem introduced by a recent code change – totally obvious from the thread dump. Now we’re nailing it down with a failing perf unit test and fixing the problem.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Topics

  • agile (781)
  • rails (113)
  • testing (88)
  • ruby (83)
  • ruby on rails (70)
  • jobs (62)
  • javascript (55)
  • techtalk (44)
  • rspec (38)
  • ironblogger (32)
  • productivity (30)
  • activerecord (29)
  • gogaruco (29)
  • git (28)
  • nyc (27)
  • rubymine (26)
  • bloggerdome (23)
  • mobile (22)
  • process (21)
  • pivotal tracker (21)
  • cucumber (20)
  • design (19)
  • jasmine (19)
  • ios (18)
  • webos (17)
  • objective-c (17)
  • android (16)
  • tracker ecosystem (16)
  • palm (16)
  • "soft" ware (16)
  • fun (15)
  • ci (15)
  • cedar (15)
  • rails3 (14)
  • performance (14)
  • bdd (14)
  • gem (13)
  • css (13)
  • tdd (13)
  • selenium (12)
  • goruco (12)
  • bundler (12)
  • meetup (11)
  • railsconf (11)
  • nyc-standup (11)
  • capybara (10)
  • mac (10)
  • mojo (10)
  • chef (10)
  • api (10)
Subscribe to ruby on rails Feed
  1. ←
  2. 1
  3. 2
  4. 3
  5. 4
  6. 5
  7. 6
  8. 7
  9. →
  • 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 >