<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>TODO.textile</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -13,7 +13,7 @@ module SortableTable
         module ClassMethods
           def sortable_attributes(*args)
             mappings           = pop_hash_from_list(args)
-            acceptable_columns = join_array_and_hash_keys(args, mappings)
+            acceptable_columns = join_array_and_hash_values(args, mappings)
             define_sort_order(acceptable_columns, mappings)
           end
           
@@ -25,9 +25,9 @@ module SortableTable
             end
           end
           
-          def join_array_and_hash_keys(array, hash)
+          def join_array_and_hash_values(array, hash)
             array.collect { |each| each.to_s } + 
-              hash.keys.collect { |each| each.to_s }
+              hash.values.collect { |each| each.to_s }
           end
           
           def define_sort_order(acceptable_columns, mappings)
@@ -36,11 +36,7 @@ module SortableTable
               column    = params[:sort] || 'created_on'
               if params[:sort] &amp;&amp; acceptable_columns.include?(column)
                 column = mappings[column.to_sym] || column
-                if column.is_a?(Array)
-                  column.map{ |col| &quot;#{col} #{direction}&quot; }.join(',')
-                else
-                  &quot;#{column} #{direction}&quot;
-                end
+                handle_compound_sorting(column, direction)
               else
                 &quot;#{acceptable_columns.first} #{default_sort_direction(default)}&quot;
               end
@@ -56,7 +52,7 @@ module SortableTable
               when &quot;descending&quot;, &quot;asc&quot; then &quot;desc&quot;
               else
                 raise RuntimeError, 
-                  &quot;valid sort orders are 'ascending' &amp; 'descending'&quot;
+                  &quot;valid :default sort orders are 'ascending' &amp; 'descending'&quot;
               end
             else
               &quot;desc&quot;  
@@ -68,6 +64,14 @@ module SortableTable
               object.first.is_a?(Hash) &amp;&amp; 
               object.first.has_key?(:default)
           end
+          
+          def handle_compound_sorting(column, direction)
+            if column.is_a?(Array)
+              column.collect { |each| &quot;#{each} #{direction}&quot; }.join(',')
+            else
+              &quot;#{column} #{direction}&quot;
+            end
+          end
         end
 
       end</diff>
      <filename>lib/sortable_table/app/controllers/application_controller.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,18 +2,21 @@ module SortableTable
   module Shoulda
 
     def should_sort_by(attribute, options = {}, &amp;block)
-      collection       = get_collection_name_from_test_name(options[:collection])
-      model_under_test = get_model_under_test_from_test_name(options[:model_name])
+      collection       = get_collection_name(options[:collection])
+      model_under_test = get_model_under_test(attribute, options[:model_name])
 
       block  = block || default_sorting_block(model_under_test, attribute)
       action = options[:action] || default_sorting_action
 
       %w(ascending descending).each do |direction|
         should &quot;sort by #{attribute.to_s} #{direction}&quot; do
-          assert_db_records_exist_for(model_under_test)
-          action.bind(self).call(attribute.to_s, direction)
-          assert_collection_can_be_tested_for_sorting(collection)
-          assert_collection_is_sorted(collection, direction, &amp;block)
+          assert_db_records_exist_for(model_under_test) # sanity check
+          
+          action.bind(self).call(attribute.to_s, direction) # controller action
+          
+          assert_collection_can_be_tested_for_sorting(collection) # sanity check
+          
+          assert_collection_is_sorted(collection, direction, &amp;block) # test
         end
       end
     end
@@ -48,15 +51,39 @@ module SortableTable
     
     protected
     
-    def get_collection_name_from_test_name(override)
+    def get_collection_name(override)
+      collection = get_collection_name_from_test_name
+      (override || collection).to_sym
+    end
+    
+    def get_collection_name_from_test_name
       collection = self.name.underscore.gsub(/_controller_test/, '')
       collection = remove_namespacing(collection)
-      (override || collection).to_sym
     end
 
-    def get_model_under_test_from_test_name(override)
+    def get_model_under_test(attribute, override)
+      if override
+        model_name = override
+      else
+        model_name = if attribute_includes_table?(attribute) 
+          get_model_from_sql_string(attribute)
+        else
+          get_model_under_test_from_test_name
+        end
+      end
+      model_name.singularize.camelize.constantize
+    end
+    
+    def get_model_under_test_from_test_name
       model_name = self.name.gsub(/ControllerTest/, '')
-      (override || model_name).singularize.camelize.constantize
+    end
+    
+    def attribute_includes_table?(attribute)
+      attribute.to_s.include?(&quot;.&quot;)
+    end
+    
+    def get_model_from_sql_string(string)
+      string.split(&quot;.&quot;).first
     end
 
     def remove_namespacing(string)
@@ -66,7 +93,7 @@ module SortableTable
     
     def default_sorting_block(model_under_test, attribute)
       block = handle_boolean_attribute(model_under_test, attribute)
-      block ||= attribute
+      block ||= lambda { attribute.to_s }
     end
     
     def handle_boolean_attribute(model_under_test, attribute)
@@ -76,9 +103,7 @@ module SortableTable
     end
     
     def attribute_is_boolean?(model_under_test, attribute)
-      db_column = model_under_test.columns.select { |each| 
-        each.name == attribute.to_s 
-      }.first
+      db_column = model_under_test.columns.select { |each| each.name == attribute.to_s }.first
       db_column.type == :boolean
     end
     </diff>
      <filename>shoulda_macros/sortable_table.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2935,3 +2935,24 @@ Migrating to UserBelongsToGroup (20081229222354)
   *[4;35;1mSQL (1.0ms)*[0m   *[0mINSERT INTO &quot;schema_migrations&quot; (version) VALUES ('20081229222354')*[0m
   *[4;36;1mSQL (1.1ms)*[0m   *[0;1mINSERT INTO &quot;schema_migrations&quot; (version) VALUES ('20080819225020')*[0m
   *[4;35;1mSQL (1.0ms)*[0m   *[0mINSERT INTO &quot;schema_migrations&quot; (version) VALUES ('20081229222312')*[0m
+  *[4;36;1mSQL (1.2ms)*[0m   *[0;1m SELECT name
+ FROM sqlite_master
+ WHERE type = 'table' AND NOT name = 'sqlite_sequence'
+*[0m
+  *[4;35;1mSQL (0.7ms)*[0m   *[0mSELECT version FROM schema_migrations*[0m
+Migrating to CreateUsers (20080819225020)
+Migrating to CreateGroups (20081229222312)
+Migrating to UserBelongsToGroup (20081229222354)
+  *[4;36;1mSQL (14.0ms)*[0m   *[0;1mselect sqlite_version(*)*[0m
+  *[4;35;1mSQL (0.7ms)*[0m   *[0m SELECT name
+ FROM sqlite_master
+ WHERE type = 'table' AND NOT name = 'sqlite_sequence'
+*[0m
+  *[4;36;1mSQL (0.4ms)*[0m   *[0;1mSELECT version FROM schema_migrations*[0m
+  *[4;35;1mSQL (0.4ms)*[0m   *[0m SELECT name
+ FROM sqlite_master
+ WHERE type = 'table' AND NOT name = 'sqlite_sequence'
+*[0m
+  *[4;36;1mSQL (0.1ms)*[0m   *[0;1mPRAGMA index_list(&quot;groups&quot;)*[0m
+  *[4;35;1mSQL (0.2ms)*[0m   *[0mPRAGMA index_list(&quot;users&quot;)*[0m
+  *[4;36;1mSQL (0.2ms)*[0m   *[0;1mPRAGMA index_info('index_users_on_group_id')*[0m</diff>
      <filename>test/rails_root/log/development.log</filename>
    </modified>
    <modified>
      <diff>@@ -12,13 +12,18 @@ class UsersControllerTest &lt; ActionController::TestCase
       Factory(:user, :age =&gt; 30)
     end
 
-    should_sort_by_attributes :name, :email, :age do |sort, order|
-      get :index, :sort =&gt; sort, :order =&gt; order
-    end
+    should_sort_by_attributes :name, :email, :age
 
-    should_sort_by :name_and_email, {} do |user|
-      &quot;#{user.name} #{user.email}&quot;
-    end
+    should_sort_by &quot;groups.name&quot;
+
+    # test block form    
+    # should_sort_by_attributes :age do |sort, order|
+    #   get :index, :sort =&gt; sort, :order =&gt; order
+    # end
+
+    # should_sort_by :name_and_email, {} do |user|
+    #   &quot;#{user.name} #{user.email}&quot;
+    # end
 
     context 'with a non-standard instance variable name' do
       should_sort_by :name, { :collection =&gt; 'users_dupe', :model_name =&gt; 'user' } do |user|</diff>
      <filename>test/rails_root/test/functional/users_controller_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -21,7 +21,9 @@ class ApplicationHelperTest &lt; HelperTestCase
 
     context 'with no params[:sort] or params[:order]' do
       setup do
-        @html = sortable_table_header(:name =&gt; 'Title', :sort =&gt; 'title', :title =&gt; 'Sort by title')
+        @html = sortable_table_header(:name  =&gt; 'Title', 
+                                      :sort  =&gt; 'title', 
+                                      :title =&gt; 'Sort by title')
       end
 
       should 'return a table header without a class attribute' do
@@ -31,7 +33,10 @@ class ApplicationHelperTest &lt; HelperTestCase
     
     context 'with params[:class]' do
       setup do
-        @html = sortable_table_header(:name =&gt; 'Title', :sort =&gt; 'title', :title =&gt; 'Sort by title', :class =&gt; &quot;hr_class&quot;)
+        @html = sortable_table_header(:name  =&gt; 'Title', 
+                                      :sort  =&gt; 'title', 
+                                      :title =&gt; 'Sort by title', 
+                                      :class =&gt; &quot;hr_class&quot;)
       end
       
       should 'return a table header with a class attribute equal to the passed in class' do
@@ -41,7 +46,9 @@ class ApplicationHelperTest &lt; HelperTestCase
 
     context &quot;without an :anchor&quot; do
       setup do
-        @html = sortable_table_header(:name =&gt; 'Title', :sort =&gt; 'title', :title =&gt; 'Sort by title')
+        @html = sortable_table_header(:name  =&gt; 'Title', 
+                                      :sort  =&gt; 'title', 
+                                      :title =&gt; 'Sort by title')
       end
 
       should 'return a link that contains a url with no anchor' do
@@ -51,7 +58,10 @@ class ApplicationHelperTest &lt; HelperTestCase
 
     context &quot;with an :anchor&quot; do
       setup do
-        @html = sortable_table_header(:name =&gt; 'Title', :sort =&gt; 'title', :title =&gt; 'Sort by title', :anchor =&gt; 'search-results')
+        @html = sortable_table_header(:name   =&gt; 'Title', 
+                                      :sort   =&gt; 'title', 
+                                      :title  =&gt; 'Sort by title', 
+                                      :anchor =&gt; 'search-results')
       end
 
       should 'return a link that contains a url with that anchor' do</diff>
      <filename>test/rails_root/test/unit/helpers/application_helper_test.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>367f4276b42be13edb4aaf3c1d364bcfa173cb0b</id>
    </parent>
  </parents>
  <author>
    <name>Dan Croak</name>
    <email>dcroak@thoughtbot.com</email>
  </author>
  <url>http://github.com/thoughtbot/sortable_table/commit/d044feb600ab3fa77463ef5602fe9b2be2fcffec</url>
  <id>d044feb600ab3fa77463ef5602fe9b2be2fcffec</id>
  <committed-date>2009-01-02T13:35:07-08:00</committed-date>
  <authored-date>2009-01-02T13:35:07-08:00</authored-date>
  <message>refactoring so shoulda macro handles :email =&gt; groups.email option</message>
  <tree>a99a2fd120c9c017a7e7985f53c438965efc2cc5</tree>
  <committer>
    <name>Dan Croak</name>
    <email>dcroak@thoughtbot.com</email>
  </committer>
</commit>
