<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -18,9 +18,14 @@ Rails 2.1+.
   Item.create :name =&gt; 'bar', :value =&gt; 2, :content =&gt; content
   Item.create :name =&gt; 'baz', :value =&gt; 3, :content =&gt; content
 
-  Item.selects(:names).scoped(:order =&gt; 'id').values # =&gt; %w[foo bar baz]
+  Item.selects(:names).values(:order =&gt; 'id').all # =&gt; %w[foo bar baz]
+
+  # use a shortcut with distinct
   Item.select_first :distinct_content # =&gt; content
 
+  # reject named columns in scope :a_named_scope and select only the values
+  Item.a_named_scope.rejects(:content).values.all # =&gt; [[1, 'foo', 1], ...]
+
 See test/column_scope_test.rb for more examples.
 
 Copyright (c) 2008 Florian A&#223;mann, released under the MIT license</diff>
      <filename>README.rdoc</filename>
    </modified>
    <modified>
      <diff>@@ -18,6 +18,6 @@ Rake::RDocTask.new(:rdoc) do |rdoc|
   rdoc.rdoc_dir = 'rdoc'
   rdoc.title    = 'ColumnScope'
   rdoc.options &lt;&lt; '--line-numbers' &lt;&lt; '--inline-source' &lt;&lt; '-c UTF-8'
-  rdoc.rdoc_files.include('README')
+  rdoc.rdoc_files.include('README.rdoc')
   rdoc.rdoc_files.include('lib/**/*.rb')
 end</diff>
      <filename>Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -1,3 +1,10 @@
 require &quot;#{ File.dirname __FILE__ }/lib/column_scope&quot;
-ActiveRecord::NamedScope::Scope.instance_eval { include ColumnScope::ScopeMethods }
-ActiveRecord::Base.instance_eval { extend ColumnScope::ScopeMethods }
+ActiveRecord::NamedScope::Scope.class_eval do
+  include ColumnScope::ScopeMethods
+end
+ActiveRecord::Base.class_eval do
+  extend ColumnScope::ScopeMethods
+  def self.values
+    ColumnScope::ValueExtractor.new self, column_names
+  end
+end</diff>
      <filename>init.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,79 +1,126 @@
+# = ColumnScope
+#
+# To create a column scope invoke either &lt;tt&gt;selects&lt;/tt&gt; or &lt;tt&gt;rejects&lt;/tt&gt;
+# on a scope (which is either a model or a named scope).
+#
+# When you invoke &lt;tt&gt;find&lt;/tt&gt; on a scope that is chained with a column scope
+# only the named columns are selected by SQL.
+# This gives you the instances of your model with the selected attributes
+# assigned.
+#
+# If you only want the plain values invoke &lt;tt&gt;values&lt;/tt&gt; on a scope before
+# you invoke &lt;tt&gt;find&lt;/tt&gt;.
 class ColumnScope &lt; ActiveRecord::NamedScope::Scope
 
   module ScopeMethods
-    # Returns a ColumnScope.
-    def selects(column_names)
-      ColumnScope.new self, column_names
+
+    def self.split_column_names(column_names) #:nodoc:
+      column_names  = &quot;#{ column_names }&quot;
+      column_names  = column_names.split('_and_').map! { |c| c.singularize }
+      first_cn      = column_names.first
+
+      distinct =  if first_cn[0, 9] == 'distinct_'
+        first_cn.slice!(0, 9).gsub!('_', ' ').upcase
+      end
+
+      return distinct, column_names
+    end
+
+    # Returns an instance of ValueExtractor with scope and column names.
+    #
+    # The ValueExtractor invokes a find on the scope and maps the results
+    # to the selected values.
+    #
+    # Note: This method is overwritten for ActiveRecord::Base to invoke
+    # column_names on self.
+    def values
+      ColumnScope::ValueExtractor.new self, proxy_scope.column_names
     end
-    # Returns selected values of all records.
+    # Returns a ColumnScope with named columns.
+    #
+    # To get the selected values invoke values on this scope before you load
+    # the records with :first, :last or :all.
+    def selects(selected_cns)
+      distinct, selected_cns = ScopeMethods.split_column_names selected_cns
+      ColumnScope.new self, selected_cns, distinct
+    end
+    # Returns a ColumnScope w/o named columns.
+    #
+    # To get the remaining values invoke values on this scope before you load
+    # the records with :first, :last or :all.
+    #
+    # Note: The attribute order is the same as in column_names w/o the names
+    # columns.
+    def rejects(rejected_cns)
+      distinct, rejected_cns = ScopeMethods.split_column_names rejected_cns
+      selected_cns = column_names.reject { |cn| rejected_cns.include? cn }
+      ColumnScope.new self, selected_cns, distinct
+    end
+    # This shortcut returns selected values of all records.
     def select_all(column_names, options = {})
       scope = selects column_names
-      scope.all_values scope.all(options)
+      scope.values.all options
     end
-    # Returns selected values of first record.
+    # This shortcut returns selected values of first record.
     def select_first(column_names, options = {})
       scope = selects column_names
-      scope.values scope.first(options)
+      scope.values.first options
     end
-    # Returns selected values of last record.
+    # This shortcut returns selected values of last record.
     def select_last(column_names, options = {})
       scope = selects column_names
-      scope.values scope.last(options)
+      scope.values.last options
     end
-  end
 
-  def initialize(proxy_scope, column_names)
-    initialize_extractor_and_select proxy_scope, column_names
-    super proxy_scope, :select =&gt; @select_sql
   end
 
-  # Extracts values from single record specified in column scope.
-  def values(record)
-    @value_extractor.call record
-  end
-  # Extracts values from multiple records specified in column scope.
-  def all_values(records = all)
-    records.map! { |record| values record }
-  end
-
-  def scopes #:nodoc:
-    # inject scope to allow &lt;tt&gt;selects(:column).named_scope.values&lt;/tt&gt;.
-    cs = self
-
-    super.merge :values =&gt; proc { |ps, *args|
-      case arg = args.first
-      when :first, :last
-        cs.values ps.send(arg)
-      when :all, nil
-        cs.all_values ps.all
-      end
-    }
+  def initialize(proxy_scope, column_names, distinct) #:nodoc:
+    super(proxy_scope, {}) do
+      define_method(:values) { ValueExtractor.new self, column_names }
+    end
+    proxy_options[:select] = select_sql column_names, distinct
   end
 
   protected
-  def initialize_extractor_and_select(proxy_scope, column_names) #:nodoc:
-    column_names = &quot;#{ column_names }&quot;
-    column_names = column_names.split('_and_').map! { |c| c.singularize }
-    first_column_name = column_names.first
+  def select_sql(column_names, distinct) #:nodoc:
+    base_class = proxy_scope
+    while base_class.class == ActiveRecord::NamedScope::Scope
+      base_class = base_class.proxy_scope
+    end
+    con, qtn = base_class.connection, base_class.quoted_table_name
+    sanitized_column_names = column_names.
+        map { |cn| &quot;#{ qtn }.#{ cn }&quot; }
+# Quoting of column names when distinct brakes ARs orm'ing!
+#        map { |cn| &quot;#{ qtn }.#{ con.quote_column_name cn }&quot; }
 
-    @select_sql = first_column_name[0, 9] == 'distinct_' ?
-      first_column_name.slice!(0, 9).gsub!('_', ' ').upcase :
-      ''
+    &quot;#{ distinct }#{ sanitized_column_names * ',' }&quot;
+  end
 
-    @value_extractor = column_names.size == 1 ?
-      lambda { |record| record[first_column_name] } :
-      lambda { |record| record.attributes.values_at(*column_names) }
+  class ValueExtractor
+    def initialize(scope, column_names) #:nodoc:
+      first_column_name = column_names.first
+      @extracting = column_names.size == 1 ?
+        lambda { |record| record[first_column_name] } :
+        lambda { |record| record.attributes.values_at(*column_names) }
 
-    qtn = quoted_table_name_for proxy_scope
-    @select_sql &lt;&lt; column_names.map { |cn| &quot;#{ qtn }.#{ cn }&quot;} * ','
-  end
+      @scope = scope
+    end
 
-  def quoted_table_name_for(object) #:nodoc:
-    while object.class == ActiveRecord::NamedScope::Scope
-      object = object.proxy_scope
+    # Returns selected values of all records (in scope).
+    def all(options = {})
+      @scope.find(:all, options).map! { |record| @extracting[record] }
+    end
+    # Returns selected values of first record (in scope).
+    def first(options = {})
+      record = @scope.first options
+      @extracting[record] if record
+    end
+    # Returns selected values of last record (in scope).
+    def last(options = {})
+      record = @scope.last options
+      @extracting[record] if record
     end
 
-    object.quoted_table_name
   end
 
 end</diff>
      <filename>lib/column_scope.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,74 +2,79 @@ require 'test_helper'
 
 module ColumnScopeTestHelper
 
-  def self.included(base)
-    const_set :Item, Class.new(ActiveRecord::Base)
-  end
-
-  def content
+  def self.content
     'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
   end
-  def with_items
-    Item.create :name =&gt; 'foo', :value =&gt; 1, :content =&gt; content
-    Item.create :name =&gt; 'bar', :value =&gt; 2, :content =&gt; content
-    Item.create :name =&gt; 'baz', :value =&gt; 3, :content =&gt; content
-    yield if block_given?
-  ensure
-    Item.delete_all
+
+  class Item &lt; ActiveRecord::Base
+    named_scope :with_name, proc { |name|
+      { :conditions =&gt; ['name = ?', name] }
+    }
   end
+  Item.create :name =&gt; 'foo', :value =&gt; 1, :content =&gt; content
+  Item.create :name =&gt; 'bar', :value =&gt; 2, :content =&gt; content
+  Item.create :name =&gt; 'baz', :value =&gt; 3, :content =&gt; content
 
 end
 
 class ColumnScopeTest &lt; ActiveSupport::TestCase
   include ColumnScopeTestHelper
 
-  test &quot;verify that items.name column is selected&quot; do
+  test &quot;verify that items name column is selected&quot; do
     assert Item.selects(:names).proxy_options[:select] == '&quot;items&quot;.name'
+# Quoting of column names when distinct brakes ARs orm'ing!
+#    assert Item.selects(:names).proxy_options[:select] == '&quot;items&quot;.&quot;name&quot;'
   end
-  test &quot;verify that items.name column is selected with distinct&quot; do
+  test &quot;verify that items name column is selected with distinct&quot; do
     assert Item.selects(:distinct_name).proxy_options[:select] == 'DISTINCT &quot;items&quot;.name'
+# Quoting of column names when distinct brakes ARs orm'ing!
+#    assert Item.selects(:distinct_name).proxy_options[:select] == 'DISTINCT &quot;items&quot;.&quot;name&quot;'
   end
-  test &quot;verify that items.name and items.value columns are selected&quot; do
+  test &quot;verify that items name and items.value columns are selected&quot; do
     assert Item.selects(:name_and_value).proxy_options[:select] == '&quot;items&quot;.name,&quot;items&quot;.value'
+# Quoting of column names when distinct brakes ARs orm'ing!
+#    assert Item.selects(:name_and_value).proxy_options[:select] == '&quot;items&quot;.&quot;name&quot;,&quot;items&quot;.&quot;value&quot;'
   end
 
   test &quot;verify all names are foo bar and baz&quot; do
-    with_items do
-      expectation = %w[foo bar baz]
-      result1     = Item.select_all :names, :order =&gt; 'id'
-      result2     = Item.selects(:names).scoped(:order =&gt; 'id').values
+    expectation = %w[foo bar baz]
+    result1     = Item.select_all :names, :order =&gt; 'id'
+    result2     = Item.selects(:names).values.all :order =&gt; 'id'
 
-      assert_equal expectation, result1
-      assert_equal expectation, result2
-    end
+    assert_equal expectation, result1
+    assert_equal expectation, result2
   end
   test &quot;verify last value is 3&quot; do
-    with_items do
-      expectation = 3
-      result1     = Item.select_last :value, :order =&gt; 'id'
-      result2     = Item.selects(:value).scoped(:order =&gt; 'id').values(:last)
+    expectation = 3
+    result1     = Item.select_last :value, :order =&gt; 'id'
+    result2     = Item.selects(:values).values.last :order =&gt; 'id'
 
-      assert_equal expectation, result1
-      assert_equal expectation, result2
-    end
+    assert_equal expectation, result1
+    assert_equal expectation, result2
   end
   test &quot;verify first distinct content is the lorem ipsum&quot; do
-    with_items do
-      expectation = content
-      result1     = Item.select_first :distinct_content
+    expectation = ColumnScopeTestHelper.content
+    result      = Item.select_first :distinct_content
 
-      assert_equal expectation, result1
-    end
+    assert_equal expectation, result
   end
   test &quot;verify find returns 3 and baz&quot; do
-    with_items do
-      expectation = [3, 'baz']
-      result1     = Item.select_first :value_and_name, :conditions =&gt; {:name =&gt; 'baz'}
-      result2     = Item.scoped(:conditions =&gt; {:name =&gt; 'baz'}).select_first(:value_and_name)
+    expectation = ['baz', 3]
+    result1     = Item.with_name('baz').selects(:name_and_value).values.first
+    result2     = Item.with_name('baz').rejects(:content_and_id).values.first
+
+    assert_equal expectation, result1
+    assert_equal expectation, result2
+  end
+  test &quot;verify values returns values&quot; do
+    expectation = [
+      ['foo', 1, ColumnScopeTestHelper.content],
+      ['bar', 2, ColumnScopeTestHelper.content],
+      ['baz', 3, ColumnScopeTestHelper.content]
+    ]
+    result = Item.values.all.each { |tuple| tuple.shift }
 
-      assert_equal expectation, result1
-      assert_equal expectation, result2
-    end
+    assert_equal expectation, result
   end
 
 end</diff>
      <filename>test/column_scope_test.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>2ac9729aefda778d9a04333b4a616a34c6374966</id>
    </parent>
  </parents>
  <author>
    <name>Florian A&#223;mann</name>
    <email>florian.assmann@email.de</email>
  </author>
  <url>http://github.com/boof/column_scope/commit/e4e4d7574c0ce201a8ae6fa683a70cd7b2a2aadd</url>
  <id>e4e4d7574c0ce201a8ae6fa683a70cd7b2a2aadd</id>
  <committed-date>2008-12-29T15:14:51-08:00</committed-date>
  <authored-date>2008-12-29T15:14:51-08:00</authored-date>
  <message>Refactored ColumnScope.
 * added ValueExtractor
 * added rejects method, inverse of selects
 * updated documentation
 * found a bug in ActiveRecord::Base :/</message>
  <tree>d0540c25e870608fcf57a1761096657b02e54bcc</tree>
  <committer>
    <name>Florian A&#223;mann</name>
    <email>florian.assmann@email.de</email>
  </committer>
</commit>
