Adventures in patch-land

10 Aug 2007

Dr. Nic threw down the guantlet about submitting a patch to the scope_out plugin to allow the use of the ActiveRecord::Base#count() method within a scope.

I’m just not sure why it hadn’t occurred to me to submit a patch before extending the plugin. Perhaps I was trying to show off my Ruby-fu, perhaps I didn’t realize GoogleCode allowed patch submissions, or perhaps I’m just trying to artificially raise my post count by doing them separately.

Patching a plugin is dead easy. Knowing which tools to use is about the only tough part.

Check out the plugin (svn checkout http://scope-out-rails.googlecode.com/svn/trunk/ scope-out-rails)

# in your shell change the current working directory to the root of the plugin (cd scope-out-rails) # Edit the file that you want changed. For this job it’s ./lib/scope_out.rb # type svn diff and take a look at what shows up. Does that look about right? # type svn diff > my_clearly_named_patch.diff to create a patch file from your changes. # upload your patch to the project (http://code.google.com/p/scope-out-rails/issues/detail?id=10)

It’s far less work to make a patch than work around the problem:

    Index: lib/scope_out.rb
    ===================================================================
    --- lib/scope_out.rb    (revision 29)
    +++ lib/scope_out.rb    (working copy)
    @@ -112,6 +112,10 @@
             def find_#{name}(*args)
               with_#{name} {find(*args)}
             end
    +        
    +        def count_#{name}(*args)
    +          with_#{name} {count(*args)}
    +        end

             def calculate_#{name}(*args)
               with_#{name} {calculate(*args)}

Update: For shame! Here I go spewing out a patch without any tests! Many thanks to Duncan for pointing this out.

The new patch (uploaded to the scope_out project):

    Index: test/scope_out_test.rb
    ===================================================================
    --- test/scope_out_test.rb      (revision 29)
    +++ test/scope_out_test.rb      (working copy)
    @@ -173,6 +173,17 @@
                      Student.calculate_freshmen_active(:count, :all))
       end

    +  def test_count_methods
    +    assert_equal(Student.count(:conditions => "level = 'Freshman'"),
    +                 Student.count_freshmen)
    +    assert_equal(Student.count(:conditions => "age = 18"),
    +                 Student.count_eighteen_year_olds)
    +    assert_equal(Student.count(:conditions => ["active = ?", true]),
    +                 Student.count_active)
    +    assert_equal(Student.count(:conditions => ["active = ? and level = ?", true, 'Freshman']),
    +                 Student.count_freshmen_active)
    +  end
    +  
       def test_passes_limit_option_to_with_scope
         assert_equal(Student.find_all_by_active(true, :limit => 1), Student.find_one_active(:all))
       end
    Index: lib/scope_out.rb
    ===================================================================
    --- lib/scope_out.rb    (revision 29)
    +++ lib/scope_out.rb    (working copy)
    @@ -112,6 +112,10 @@
             def find_#{name}(*args)
               with_#{name} {find(*args)}
             end
    +        
    +        def count_#{name}(*args)
    +          with_#{name} {count(*args)}
    +        end

             def calculate_#{name}(*args)
               with_#{name} {calculate(*args)}
  • Duncan Beevers said: Don't forget the important step of writing and submitting tests for your patch!
  • Dr Nic said:
    or perhaps I’m just trying to artificially raise my post count by doing them separately
    FTW!

Please if you found this post helpful or have questions.