diff --git a/README.rdoc b/README.rdoc
index 6697038..fb29c3f 100644
--- a/README.rdoc
+++ b/README.rdoc
@@ -5,7 +5,7 @@ GroupedScope aims to make two things easier in your ActiveRecord models. First,
easy way to group objects, second, to allow the group to share associated object via existing
has_many relationships. See installation and usage for more details.
-By the way, this plugin has been tested with rails 1.2.6, 2.0.4, and 2.1.1.
+By the way, this plugin has been tested with rails 2.3.2, 2.2.2, and 2.1.1
=== Installation & Usage
diff --git a/Rakefile b/Rakefile
index 316c5ad..7261442 100644
--- a/Rakefile
+++ b/Rakefile
@@ -20,10 +20,10 @@ Rake::TestTask.new(:test) do |t|
t.verbose = true
end
-desc 'Test the GroupedScope plugin with Rails 2.1.1, 2.0.4 & 1.2.6 gems'
+desc 'Test the GroupedScope plugin with Rails 2.3.2, 2.2.2, and 2.1.1 gems'
task :test_rails do
test = Rake::Task['test']
- versions = ['2.2.2','2.1.1','2.0.4','1.2.6']
+ versions = ['2.3.2','2.2.2','2.1.1']
versions.each do |version|
ENV['RAILS_VERSION'] = "#{version}"
test.invoke
diff --git a/grouped_scope.gemspec b/grouped_scope.gemspec
index 50234ef..51360d6 100644
--- a/grouped_scope.gemspec
+++ b/grouped_scope.gemspec
@@ -33,12 +33,6 @@ Gem::Specification.new do |s|
"test/grouped_scope/self_grouping_test.rb",
"test/helper.rb",
"test/lib/boot.rb",
- "test/lib/core_ext.rb",
- "test/lib/named_scope.rb",
- "test/lib/named_scope/core_ext.rb",
- "test/lib/named_scope/named_scope.rb",
- "test/lib/named_scope/named_scope_patch_1.2.rb",
- "test/lib/named_scope/named_scope_patch_2.0.rb",
"test/lib/test_case.rb" ]
s.rdoc_options = ["--main", "README.rdoc"]
s.extra_rdoc_files = ["README.rdoc","CHANGELOG","MIT-LICENSE"]
diff --git a/lib/grouped_scope/has_many_association.rb b/lib/grouped_scope/has_many_association.rb
index af83c2d..6f02b72 100644
--- a/lib/grouped_scope/has_many_association.rb
+++ b/lib/grouped_scope/has_many_association.rb
@@ -9,8 +9,6 @@ def self.included(klass)
def construct_sql_with_group_scope
if @reflection.options[:grouped_scope]
- # CHANGED [Rails 1.2.6] Account for quoted_table_name.
- table_name = @reflection.respond_to?(:quoted_table_name) ? @reflection.quoted_table_name : @reflection.klass.table_name
if @reflection.options[:as]
# TODO: Need to add case for polymorphic :as option.
else
diff --git a/test/grouped_scope/association_reflection_test.rb b/test/grouped_scope/association_reflection_test.rb
index 3c3fa61..bc4227b 100644
--- a/test/grouped_scope/association_reflection_test.rb
+++ b/test/grouped_scope/association_reflection_test.rb
@@ -40,8 +40,6 @@ def setup
should 'delegate instance methods to #ungrouped_reflection' do
methods = [:class_name,:klass,:table_name,:primary_key_name,:active_record,
:association_foreign_key,:counter_cache_column,:source_reflection]
- # CHANGED [Rails 1.2.6] Account for quoted_table_name.
- methods << :quoted_table_name if @ungrouped_reflection.respond_to?(:quoted_table_name)
methods.each do |m|
assert_equal @ungrouped_reflection.send(m), @grouped_reflection.send(m),
"The method #{m.inspect} does not appear to be proxied to the ungrouped reflection."
@@ -54,17 +52,11 @@ def setup
end
should 'derive class name to same as ungrouped reflection' do
- # CHANGED [Rails 1.2.6] Account for quoted_table_name.
- if @ungrouped_reflection.respond_to?(:derive_class_name)
- assert_equal @ungrouped_reflection.send(:derive_class_name), @grouped_reflection.send(:derive_class_name)
- end
+ assert_equal @ungrouped_reflection.send(:derive_class_name), @grouped_reflection.send(:derive_class_name)
end
should 'derive primary key name to same as ungrouped reflection' do
- # CHANGED [Rails 1.2.6] Account for quoted_table_name.
- if @ungrouped_reflection.respond_to?(:derive_primary_key_name)
- assert_equal @ungrouped_reflection.send(:derive_primary_key_name), @grouped_reflection.send(:derive_primary_key_name)
- end
+ assert_equal @ungrouped_reflection.send(:derive_primary_key_name), @grouped_reflection.send(:derive_primary_key_name)
end
should 'honor explicit legacy reports association options like class_name and foreign_key' do
diff --git a/test/lib/boot.rb b/test/lib/boot.rb
index 00c21c8..689ab96 100644
--- a/test/lib/boot.rb
+++ b/test/lib/boot.rb
@@ -28,5 +28,4 @@
gem 'mislav-will_paginate', '2.3.4'
require 'will_paginate'
WillPaginate.enable_activerecord
-require 'named_scope'
diff --git a/test/lib/core_ext.rb b/test/lib/core_ext.rb
deleted file mode 100644
index 8b64ba7..0000000
--- a/test/lib/core_ext.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-
-unless Hash.instance_methods.include? 'except'
-
- Hash.class_eval do
-
- # Returns a new hash without the given keys.
- def except(*keys)
- rejected = Set.new(respond_to?(:convert_key) ? keys.map { |key| convert_key(key) } : keys)
- reject { |key,| rejected.include?(key) }
- end
-
- # Replaces the hash without only the given keys.
- def except!(*keys)
- replace(except(*keys))
- end
-
- end
-
-end
-
diff --git a/test/lib/named_scope.rb b/test/lib/named_scope.rb
deleted file mode 100755
index 589dae3..0000000
--- a/test/lib/named_scope.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-unless defined? ActiveRecord::NamedScope
- require "named_scope/core_ext"
- require "named_scope/named_scope"
- require "named_scope/named_scope_patch_#{ActiveRecord::Base.respond_to?(:find_first) ? '1.2' : '2.0'}"
- ActiveRecord::Base.send :include, ActiveRecord::NamedScope
-end
-
diff --git a/test/lib/named_scope/core_ext.rb b/test/lib/named_scope/core_ext.rb
deleted file mode 100755
index 10b4410..0000000
--- a/test/lib/named_scope/core_ext.rb
+++ /dev/null
@@ -1,82 +0,0 @@
-
-unless Hash.instance_methods.include? 'except'
- Hash.class_eval do
-
- # Returns a new hash without the given keys.
- def except(*keys)
- rejected = Set.new(respond_to?(:convert_key) ? keys.map { |key| convert_key(key) } : keys)
- reject { |key,| rejected.include?(key) }
- end
-
- # Replaces the hash without only the given keys.
- def except!(*keys)
- replace(except(*keys))
- end
-
- end
-end
-
-class ActiveRecord::Base
- class << self
-
- def first(*args)
- find(:first, *args)
- end
-
- def last(*args)
- find(:last, *args)
- end
-
- def all(*args)
- find(:all, *args)
- end
-
- private
-
- def find_last(options)
- order = options[:order]
- if order
- order = reverse_sql_order(order)
- elsif !scoped?(:find, :order)
- order = "#{table_name}.#{primary_key} DESC"
- end
- if scoped?(:find, :order)
- scoped_order = reverse_sql_order(scope(:find, :order))
- scoped_methods.select { |s| s[:find].update(:order => scoped_order) }
- end
- find_initial(options.merge({ :order => order }))
- end
-
- def reverse_sql_order(order_query)
- reversed_query = order_query.split(/,/).each { |s|
- if s.match(/\s(asc|ASC)$/)
- s.gsub!(/\s(asc|ASC)$/, ' DESC')
- elsif s.match(/\s(desc|DESC)$/)
- s.gsub!(/\s(desc|DESC)$/, ' ASC')
- elsif !s.match(/\s(asc|ASC|desc|DESC)$/)
- s.concat(' DESC')
- end
- }.join(',')
- end
-
- end
-end
-
-ActiveRecord::Associations::AssociationCollection.class_eval do
-
- def last(*args)
- if fetch_first_or_last_using_find? args
- find(:last, *args)
- else
- load_target unless loaded?
- @target.last(*args)
- end
- end
-
- private
-
- def fetch_first_or_last_using_find?(args)
- args.first.kind_of?(Hash) || !(loaded? || @owner.new_record? || @reflection.options[:finder_sql] || !@target.blank? || args.first.kind_of?(Integer))
- end
-
-end
diff --git a/test/lib/named_scope/named_scope.rb b/test/lib/named_scope/named_scope.rb
deleted file mode 100755
index b30ef97..0000000
--- a/test/lib/named_scope/named_scope.rb
+++ /dev/null
@@ -1,168 +0,0 @@
-module ActiveRecord
- module NamedScope
- # All subclasses of ActiveRecord::Base have two named_scopes:
- # * all, which is similar to a find(:all) query, and
- # * scoped, which allows for the creation of anonymous scopes, on the fly: Shirt.scoped(:conditions => {:color => 'red'}).scoped(:include => :washing_instructions)
- #
- # These anonymous scopes tend to be useful when procedurally generating complex queries, where passing
- # intermediate values (scopes) around as first-class objects is convenient.
- def self.included(base)
- base.class_eval do
- extend ClassMethods
- named_scope :scoped, lambda { |scope| scope }
- end
- end
-
- module ClassMethods
- def scopes
- read_inheritable_attribute(:scopes) || write_inheritable_attribute(:scopes, {})
- end
-
- # Adds a class method for retrieving and querying objects. A scope represents a narrowing of a database query,
- # such as :conditions => {:color => :red}, :select => 'shirts.*', :include => :washing_instructions.
- #
- # class Shirt < ActiveRecord::Base
- # named_scope :red, :conditions => {:color => 'red'}
- # named_scope :dry_clean_only, :joins => :washing_instructions, :conditions => ['washing_instructions.dry_clean_only = ?', true]
- # end
- #
- # The above calls to named_scope define class methods Shirt.red and Shirt.dry_clean_only. Shirt.red,
- # in effect, represents the query Shirt.find(:all, :conditions => {:color => 'red'}).
- #
- # Unlike Shirt.find(...), however, the object returned by Shirt.red is not an Array; it resembles the association object
- # constructed by a has_many declaration. For instance, you can invoke Shirt.red.find(:first), Shirt.red.count,
- # Shirt.red.find(:all, :conditions => {:size => 'small'}). Also, just
- # as with the association objects, name scopes acts like an Array, implementing Enumerable; Shirt.red.each(&block),
- # Shirt.red.first, and Shirt.red.inject(memo, &block) all behave as if Shirt.red really were an Array.
- #
- # These named scopes are composable. For instance, Shirt.red.dry_clean_only will produce all shirts that are both red and dry clean only.
- # Nested finds and calculations also work with these compositions: Shirt.red.dry_clean_only.count returns the number of garments
- # for which these criteria obtain. Similarly with Shirt.red.dry_clean_only.average(:thread_count).
- #
- # All scopes are available as class methods on the ActiveRecord::Base descendent upon which the scopes were defined. But they are also available to
- # has_many associations. If,
- #
- # class Person < ActiveRecord::Base
- # has_many :shirts
- # end
- #
- # then elton.shirts.red.dry_clean_only will return all of Elton's red, dry clean
- # only shirts.
- #
- # Named scopes can also be procedural.
- #
- # class Shirt < ActiveRecord::Base
- # named_scope :colored, lambda { |color|
- # { :conditions => { :color => color } }
- # }
- # end
- #
- # In this example, Shirt.colored('puce') finds all puce shirts.
- #
- # Named scopes can also have extensions, just as with has_many declarations:
- #
- # class Shirt < ActiveRecord::Base
- # named_scope :red, :conditions => {:color => 'red'} do
- # def dom_id
- # 'red_shirts'
- # end
- # end
- # end
- #
- #
- # For testing complex named scopes, you can examine the scoping options using the
- # proxy_options method on the proxy itself.
- #
- # class Shirt < ActiveRecord::Base
- # named_scope :colored, lambda { |color|
- # { :conditions => { :color => color } }
- # }
- # end
- #
- # expected_options = { :conditions => { :colored => 'red' } }
- # assert_equal expected_options, Shirt.colored('red').proxy_options
- def named_scope(name, options = {}, &block)
- name = name.to_sym
- scopes[name] = lambda do |parent_scope, *args|
- Scope.new(parent_scope, case options
- when Hash
- options
- when Proc
- options.call(*args)
- end, &block)
- end
- (class << self; self end).instance_eval do
- define_method name do |*args|
- scopes[name].call(self, *args)
- end
- end
- end
- end
-
- class Scope
- attr_reader :proxy_scope, :proxy_options
-
- [].methods.each do |m|
- unless m =~ /(^__|^nil\?|^send|^object_id$|class|extend|^find$|count|sum|average|maximum|minimum|paginate|first|last|empty\?|respond_to\?)/
- delegate m, :to => :proxy_found
- end
- end
-
- delegate :scopes, :with_scope, :to => :proxy_scope
-
- def initialize(proxy_scope, options, &block)
- [options[:extend]].flatten.each { |extension| extend extension } if options[:extend]
- extend Module.new(&block) if block_given?
- @proxy_scope, @proxy_options = proxy_scope, options.except(:extend)
- end
-
- def reload
- load_found; self
- end
-
- def first(*args)
- if args.first.kind_of?(Integer) || (@found && !args.first.kind_of?(Hash))
- proxy_found.first(*args)
- else
- find(:first, *args)
- end
- end
-
- def last(*args)
- if args.first.kind_of?(Integer) || (@found && !args.first.kind_of?(Hash))
- proxy_found.last(*args)
- else
- find(:last, *args)
- end
- end
-
- def empty?
- @found ? @found.empty? : count.zero?
- end
-
- def respond_to?(method, include_private = false)
- super || @proxy_scope.respond_to?(method, include_private)
- end
-
- protected
- def proxy_found
- @found || load_found
- end
-
- private
- def method_missing(method, *args, &block)
- if scopes.include?(method)
- scopes[method].call(self, *args)
- else
- with_scope :find => proxy_options do
- proxy_scope.send(method, *args, &block)
- end
- end
- end
-
- def load_found
- @found = find(:all)
- end
- end
- end
-end
diff --git a/test/lib/named_scope/named_scope_patch_1.2.rb b/test/lib/named_scope/named_scope_patch_1.2.rb
deleted file mode 100755
index 01fc507..0000000
--- a/test/lib/named_scope/named_scope_patch_1.2.rb
+++ /dev/null
@@ -1,85 +0,0 @@
-
-ActiveRecord::Associations::AssociationProxy.class_eval do
- protected
- def with_scope(*args, &block)
- @reflection.klass.send :with_scope, *args, &block
- end
-end
-
-class ActiveRecord::Base
- class << self
- def find(*args)
- options = extract_options_from_args!(args)
- validate_find_options(options)
- set_readonly_option!(options)
- case args.first
- when :first then find_initial(options)
- when :last then find_last(options)
- when :all then find_every(options)
- else find_from_ids(args, options)
- end
- end
- private
- def attribute_condition_with_named_scope(argument)
- case argument
- when ActiveRecord::Associations::AssociationCollection, ActiveRecord::NamedScope::Scope then "IN (?)"
- else attribute_condition_without_named_scope(argument)
- end
- end
- alias_method_chain :attribute_condition, :named_scope
- end
-end
-
-ActiveRecord::Associations::HasManyAssociation.class_eval do
- protected
- def method_missing(method, *args, &block)
- if @target.respond_to?(method) || (!@reflection.klass.respond_to?(method) && Class.respond_to?(method))
- super
- elsif @reflection.klass.scopes.include?(method)
- @reflection.klass.scopes[method].call(self, *args)
- else
- create_scoping = {}
- set_belongs_to_association_for(create_scoping)
-
- @reflection.klass.with_scope(
- :create => create_scoping,
- :find => {
- :conditions => @finder_sql,
- :joins => @join_sql,
- :readonly => false
- }
- ) do
- @reflection.klass.send(method, *args, &block)
- end
- end
- end
-end
-
-ActiveRecord::Associations::HasManyThroughAssociation.class_eval do
- protected
- def method_missing(method, *args, &block)
- if @target.respond_to?(method) || (!@reflection.klass.respond_to?(method) && Class.respond_to?(method))
- super
- elsif @reflection.klass.scopes.include?(method)
- @reflection.klass.scopes[method].call(self, *args)
- else
- @reflection.klass.with_scope(construct_scope) { @reflection.klass.send(method, *args, &block) }
- end
- end
-end
-
-ActiveRecord::Associations::HasAndBelongsToManyAssociation.class_eval do
- protected
- def method_missing(method, *args, &block)
- if @target.respond_to?(method) || (!@reflection.klass.respond_to?(method) && Class.respond_to?(method))
- super
- elsif @reflection.klass.scopes.include?(method)
- @reflection.klass.scopes[method].call(self, *args)
- else
- @reflection.klass.with_scope(:find => { :conditions => @finder_sql, :joins => @join_sql, :readonly => false }) do
- @reflection.klass.send(method, *args, &block)
- end
- end
- end
-end
-
diff --git a/test/lib/named_scope/named_scope_patch_2.0.rb b/test/lib/named_scope/named_scope_patch_2.0.rb
deleted file mode 100755
index ae780c2..0000000
--- a/test/lib/named_scope/named_scope_patch_2.0.rb
+++ /dev/null
@@ -1,55 +0,0 @@
-
-ActiveRecord::Associations::AssociationProxy.class_eval do
- protected
- def with_scope(*args, &block)
- @reflection.klass.send :with_scope, *args, &block
- end
-end
-
-class ActiveRecord::Base
- class << self
- def find(*args)
- options = args.extract_options!
- validate_find_options(options)
- set_readonly_option!(options)
- case args.first
- when :first then find_initial(options)
- when :last then find_last(options)
- when :all then find_every(options)
- else find_from_ids(args, options)
- end
- end
- private
- def attribute_condition_with_named_scope(argument)
- case argument
- when ActiveRecord::NamedScope::Scope then "IN (?)"
- else attribute_condition_without_named_scope(argument)
- end
- end
- alias_method_chain :attribute_condition, :named_scope
- end
-end
-
-ActiveRecord::Associations::AssociationCollection.class_eval do
- protected
- def method_missing(method, *args)
- if @target.respond_to?(method) || (!@reflection.klass.respond_to?(method) && Class.respond_to?(method))
- if block_given?
- super { |*block_args| yield(*block_args) }
- else
- super
- end
- elsif @reflection.klass.scopes.include?(method)
- @reflection.klass.scopes[method].call(self, *args)
- else
- with_scope(construct_scope) do
- if block_given?
- @reflection.klass.send(method, *args) { |*block_args| yield(*block_args) }
- else
- @reflection.klass.send(method, *args)
- end
- end
- end
- end
-end
-