diff --git a/README.rdoc b/README.rdoc index 58ba956..824542a 100644 --- a/README.rdoc +++ b/README.rdoc @@ -5,6 +5,8 @@ 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 and 2.1.1. + === Installation & Usage @@ -73,6 +75,23 @@ extensions defined on the original has_many. For instance: * Add a user definable group_id schema. +=== Helping Our & Running Tests + +Running the test suite is easy to do. Just make sure you have the following gems installed. + +* shoulda +* quitebacktrace +* mocha +* factory_girl + +If you want to run the tests for a specific version of rails in gems (other than the latest), +then you can set the RAILS_VERSION environment variable. For example `env RAILS_VERSION=1.2.6 autotest`. +When doing this you also need to make sure that you download version 4.1 of shoulda (not the gem) +and place its lib contents into `test/lib/shoulda` and `test/lib/shoulda.rb`. The reason is that +the latest should gem require ActiveSupport greater than 2.0. + + + Copyright (c) 2008 Ken Collins, Decisiv Inc. Released under the MIT license. diff --git a/lib/grouped_scope/association_reflection.rb b/lib/grouped_scope/association_reflection.rb index 53a9ba1..a8b43e1 100644 --- a/lib/grouped_scope/association_reflection.rb +++ b/lib/grouped_scope/association_reflection.rb @@ -21,6 +21,10 @@ def ungrouped_reflection @active_record.reflections[@ungrouped_name] end + def respond_to?(method, include_private=false) + super || ungrouped_reflection.respond_to?(method,include_private) + end + private diff --git a/lib/grouped_scope/has_many_association.rb b/lib/grouped_scope/has_many_association.rb index 82785d0..af83c2d 100644 --- a/lib/grouped_scope/has_many_association.rb +++ b/lib/grouped_scope/has_many_association.rb @@ -9,10 +9,12 @@ 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 - @finder_sql = "#{@reflection.quoted_table_name}.#{@reflection.primary_key_name} IN (#{@owner.group.quoted_ids})" + @finder_sql = "#{table_name}.#{@reflection.primary_key_name} IN (#{@owner.group.quoted_ids})" @finder_sql << " AND (#{conditions})" if conditions end @counter_sql = @finder_sql diff --git a/test/grouped_scope/association_reflection_test.rb b/test/grouped_scope/association_reflection_test.rb index 50d36ce..3c3fa61 100644 --- a/test/grouped_scope/association_reflection_test.rb +++ b/test/grouped_scope/association_reflection_test.rb @@ -1,6 +1,6 @@ require File.dirname(__FILE__) + '/../helper' -class AssociationReflectionTest < GroupedScope::TestCase +class GroupedScope::AssociationReflectionTest < GroupedScope::TestCase def setup setup_environment @@ -38,8 +38,11 @@ def setup end should 'delegate instance methods to #ungrouped_reflection' do - [:class_name,:klass,:table_name,:quoted_table_name,:primary_key_name,:active_record, - :association_foreign_key,:counter_cache_column,:source_reflection].each do |m| + 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." end @@ -51,11 +54,17 @@ def setup end should 'derive class name to same as ungrouped reflection' do - assert_equal @ungrouped_reflection.send(:derive_class_name), @grouped_reflection.send(:derive_class_name) + # 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 end should 'derive primary key name to same as ungrouped reflection' do - assert_equal @ungrouped_reflection.send(:derive_primary_key_name), @grouped_reflection.send(:derive_primary_key_name) + # 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 end should 'honor explicit legacy reports association options like class_name and foreign_key' do diff --git a/test/grouped_scope/class_methods_test.rb b/test/grouped_scope/class_methods_test.rb index 9a043ef..b1b59b7 100644 --- a/test/grouped_scope/class_methods_test.rb +++ b/test/grouped_scope/class_methods_test.rb @@ -1,6 +1,6 @@ require File.dirname(__FILE__) + '/../helper' -class ClassMethodsTest < GroupedScope::TestCase +class GroupedScope::ClassMethodsTest < GroupedScope::TestCase def setup setup_environment diff --git a/test/grouped_scope/has_many_association_test.rb b/test/grouped_scope/has_many_association_test.rb index f415292..29991f9 100644 --- a/test/grouped_scope/has_many_association_test.rb +++ b/test/grouped_scope/has_many_association_test.rb @@ -1,6 +1,6 @@ require File.dirname(__FILE__) + '/../helper' -class HasManyAssociationTest < GroupedScope::TestCase +class GroupedScope::HasManyAssociationTest < GroupedScope::TestCase def setup setup_environment @@ -67,7 +67,7 @@ def setup end should 'use assoc extension SQL along with group reflection' do - assert_sql(/'URGENT'/,/"reports".employee_id IN/) do + assert_sql(/'URGENT'/,/"?reports"?.employee_id IN/) do @e2.group.reports(true).urgent end end @@ -98,7 +98,7 @@ def setup @e2.group.reports(true).with_urgent_title.with_urgent_body.inspect end end - + end end @@ -110,13 +110,13 @@ def setup end should 'scope existing association to owner' do - assert_sql(/"legacy_reports".email = '#{@employee.id}'/) do + assert_sql(/"?legacy_reports"?.email = '#{@employee.id}'/) do @employee.reports(true) end end should 'scope group association to group' do - assert_sql(/"legacy_reports".email IN \('#{@employee.id}'\)/) do + assert_sql(/"?legacy_reports"?.email IN \('#{@employee.id}'\)/) do @employee.group.reports(true) end end diff --git a/test/grouped_scope/has_many_through_association_test.rb b/test/grouped_scope/has_many_through_association_test.rb index 513efbe..1e1cb1b 100644 --- a/test/grouped_scope/has_many_through_association_test.rb +++ b/test/grouped_scope/has_many_through_association_test.rb @@ -1,6 +1,6 @@ require File.dirname(__FILE__) + '/../helper' -class HasManyThroughAssociationTest < GroupedScope::TestCase +class GroupedScope::HasManyThroughAssociationTest < GroupedScope::TestCase def setup setup_environment @@ -42,6 +42,10 @@ def setup end end + should 'have a group count equal to sum of seperate owner counts' do + assert_equal @e1.departments(true).count + @e2.departments(true).count, @e2.group.departments(true).count + end + end diff --git a/test/grouped_scope/self_grouping_test.rb b/test/grouped_scope/self_grouping_test.rb index fbcc426..924988a 100644 --- a/test/grouped_scope/self_grouping_test.rb +++ b/test/grouped_scope/self_grouping_test.rb @@ -1,6 +1,6 @@ require File.dirname(__FILE__) + '/../helper' -class SelfGrouppingTest < GroupedScope::TestCase +class GroupedScope::SelfGrouppingTest < GroupedScope::TestCase def setup setup_environment diff --git a/test/grouped_scope_test.rb b/test/grouped_scope_test.rb deleted file mode 100644 index c15cc48..0000000 --- a/test/grouped_scope_test.rb +++ /dev/null @@ -1,24 +0,0 @@ -require 'helper' - -class GroupedScopeTest < GroupedScope::TestCase - - def setup - setup_environment - end - - context 'The basics' do - - setup do - - end - - should 'description' do - assert true - end - - end - - - - -end diff --git a/test/helper.rb b/test/helper.rb index ef3ba24..c21638f 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -61,7 +61,7 @@ def setup_database(options) end class Employee < ActiveRecord::Base - has_many :reports do ; def urgent ; all(:conditions => {:title => 'URGENT'}) ; end ; end + has_many :reports do ; def urgent ; find(:all,:conditions => {:title => 'URGENT'}) ; end ; end has_many :taxonomies, :as => :classable has_many :department_memberships has_many :departments, :through => :department_memberships @@ -93,6 +93,7 @@ class LegacyEmployee < ActiveRecord::Base set_primary_key :email has_many :reports, :class_name => 'LegacyReport', :foreign_key => 'email' grouped_scope :reports + alias_method :email=, :id= end class LegacyReport < ActiveRecord::Base diff --git a/test/lib/boot.rb b/test/lib/boot.rb index 4110b74..2bf8410 100644 --- a/test/lib/boot.rb +++ b/test/lib/boot.rb @@ -25,13 +25,9 @@ require 'active_record' require 'active_support' -def enable_named_scope - return if defined? ActiveRecord::NamedScope +unless defined? ActiveRecord::NamedScope require 'named_scope' require 'named_scope_patch' - ActiveRecord::Base.class_eval do - include GroupedScope::NamedScope - end + ActiveRecord::Base.send :include, GroupedScope::NamedScope end -enable_named_scope diff --git a/test/lib/named_scope_patch.rb b/test/lib/named_scope_patch.rb index 4bcaa34..a438834 100644 --- a/test/lib/named_scope_patch.rb +++ b/test/lib/named_scope_patch.rb @@ -9,6 +9,7 @@ def with_scope(*args, &block) # Rails 1.2.6 + ActiveRecord::Associations::HasAndBelongsToManyAssociation.class_eval do protected def method_missing(method, *args, &block) @@ -23,3 +24,18 @@ def method_missing(method, *args, &block) end end end if ActiveRecord::Base.respond_to? :find_first + +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