From 8e6a18d8672f7efe6ef79b49185e4a6a23e4e547 Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Sat, 16 May 2009 12:09:25 -0700 Subject: Get AR CI passing again by requiring the entire core_ext Note that this includes Time and Date; we should really figure out what parts of core_ext are really required for AR and require just those. --- activerecord/lib/active_record.rb | 3 +++ 1 file changed, 3 insertions(+) (limited to 'activerecord') diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb index 2d98239052..b5c17cb23b 100644 --- a/activerecord/lib/active_record.rb +++ b/activerecord/lib/active_record.rb @@ -25,6 +25,9 @@ activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib" $:.unshift(activesupport_path) if File.directory?(activesupport_path) require 'active_support' +# TODO: Figure out what parts of AS are *actually* required and use those +require 'active_support/core_ext' + module ActiveRecord # TODO: Review explicit loads to see if they will automatically be handled by the initilizer. def self.load_all! -- cgit v1.2.3 From 25724eede9b5a62c74b3b78245944638f1cfcef4 Mon Sep 17 00:00:00 2001 From: Daniel Guettler Date: Sun, 17 May 2009 14:48:20 +0200 Subject: has_one :through should not create a new association when assigned nil [#698 state:resolved] Signed-off-by: Pratik Naik --- .../associations/has_one_through_association.rb | 16 ++++++++-------- .../associations/has_one_through_associations_test.rb | 9 ++++++++- 2 files changed, 16 insertions(+), 9 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/associations/has_one_through_association.rb b/activerecord/lib/active_record/associations/has_one_through_association.rb index 8073ebaf9f..d93c8e7852 100644 --- a/activerecord/lib/active_record/associations/has_one_through_association.rb +++ b/activerecord/lib/active_record/associations/has_one_through_association.rb @@ -1,31 +1,31 @@ module ActiveRecord module Associations class HasOneThroughAssociation < HasManyThroughAssociation - + def create_through_record(new_value) #nodoc: klass = @reflection.through_reflection.klass current_object = @owner.send(@reflection.through_reflection.name) - + if current_object - current_object.update_attributes(construct_join_attributes(new_value)) + new_value ? current_object.update_attributes(construct_join_attributes(new_value)) : current_object.destroy else - @owner.send(@reflection.through_reflection.name, klass.send(:create, construct_join_attributes(new_value))) + @owner.send(@reflection.through_reflection.name, klass.send(:create, construct_join_attributes(new_value))) if new_value end end - + private def find(*args) super(args.merge(:limit => 1)) end - + def find_target super.first end def reset_target! @target = nil - end - end + end + end end end diff --git a/activerecord/test/cases/associations/has_one_through_associations_test.rb b/activerecord/test/cases/associations/has_one_through_associations_test.rb index 12c598751b..ab6e6d20fc 100644 --- a/activerecord/test/cases/associations/has_one_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_one_through_associations_test.rb @@ -43,7 +43,14 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase @member.reload end end - + + def test_set_record_to_nil_should_delete_association + @member.club = nil + @member.reload + assert_equal nil, @member.current_membership + assert_nil @member.club + end + def test_has_one_through_polymorphic assert_equal clubs(:moustache_club), @member.sponsor_club end -- cgit v1.2.3 From 4e8c36a7417e5d447c9b15d5c61df0c014ee6d3b Mon Sep 17 00:00:00 2001 From: Chris Kampmeier Date: Mon, 16 Mar 2009 05:56:32 -0700 Subject: Implement #many? for NamedScope and AssociationCollection using #size [#1500 state:resolved] Signed-off-by: Pratik Naik --- activerecord/CHANGELOG | 2 ++ .../associations/association_collection.rb | 9 +++++ activerecord/lib/active_record/named_scope.rb | 11 +++++- .../associations/has_many_associations_test.rb | 39 ++++++++++++++++++++++ activerecord/test/cases/named_scope_test.rb | 34 +++++++++++++++++++ 5 files changed, 94 insertions(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index d58b44144b..411b640c9e 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -1,5 +1,7 @@ *Edge* +* Implement #many? for NamedScope and AssociationCollection using #size. #1500 [Chris Kampmeier] + * Added :touch option to belongs_to associations that will touch the parent record when the current record is saved or destroyed [DHH] * Added ActiveRecord::Base#touch to update the updated_at/on attributes (or another specified timestamp) with the current time [DHH] diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index 26987dde97..e12f6be35d 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -302,6 +302,15 @@ module ActiveRecord end end + # Returns true if the collection has more than 1 record. Equivalent to collection.size > 1. + def many? + if block_given? + method_missing(:many?) { |*block_args| yield(*block_args) } + else + size > 1 + end + end + def uniq(collection = self) seen = Set.new collection.inject([]) do |kept, record| diff --git a/activerecord/lib/active_record/named_scope.rb b/activerecord/lib/active_record/named_scope.rb index 07f98dc743..e7151a3d47 100644 --- a/activerecord/lib/active_record/named_scope.rb +++ b/activerecord/lib/active_record/named_scope.rb @@ -109,7 +109,7 @@ module ActiveRecord class Scope attr_reader :proxy_scope, :proxy_options, :current_scoped_methods_when_defined - NON_DELEGATE_METHODS = %w(nil? send object_id class extend find size count sum average maximum minimum paginate first last empty? any? respond_to?).to_set + NON_DELEGATE_METHODS = %w(nil? send object_id class extend find size count sum average maximum minimum paginate first last empty? any? many? respond_to?).to_set [].methods.each do |m| unless m =~ /^__/ || NON_DELEGATE_METHODS.include?(m.to_s) delegate m, :to => :proxy_found @@ -168,6 +168,15 @@ module ActiveRecord end end + # Returns true if the named scope has more than 1 matching record. + def many? + if block_given? + proxy_found.many? { |*block_args| yield(*block_args) } + else + size > 1 + end + end + protected def proxy_found @found || load_found diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb index 5df74fcdcd..d99424f9cd 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -1023,6 +1023,45 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert firm.clients.loaded? end + def test_calling_many_should_count_instead_of_loading_association + firm = companies(:first_firm) + assert_queries(1) do + firm.clients.many? # use count query + end + assert !firm.clients.loaded? + end + + def test_calling_many_on_loaded_association_should_not_use_query + firm = companies(:first_firm) + firm.clients.collect # force load + assert_no_queries { assert firm.clients.many? } + end + + def test_calling_many_should_defer_to_collection_if_using_a_block + firm = companies(:first_firm) + assert_queries(1) do + firm.clients.expects(:size).never + firm.clients.many? { true } + end + assert firm.clients.loaded? + end + + def test_calling_many_should_return_false_if_none_or_one + firm = companies(:another_firm) + assert !firm.clients_like_ms.many? + assert_equal 0, firm.clients_like_ms.size + + firm = companies(:first_firm) + assert !firm.limited_clients.many? + assert_equal 1, firm.limited_clients.size + end + + def test_calling_many_should_return_true_if_more_than_one + firm = companies(:first_firm) + assert firm.clients.many? + assert_equal 2, firm.clients.size + end + def test_joins_with_namespaced_model_should_use_correct_type old = ActiveRecord::Base.store_full_sti_class ActiveRecord::Base.store_full_sti_class = true diff --git a/activerecord/test/cases/named_scope_test.rb b/activerecord/test/cases/named_scope_test.rb index 7dcea6d42e..69d01d5c2a 100644 --- a/activerecord/test/cases/named_scope_test.rb +++ b/activerecord/test/cases/named_scope_test.rb @@ -235,6 +235,40 @@ class NamedScopeTest < ActiveRecord::TestCase assert_no_queries { assert topics.any? } end + def test_many_should_not_load_results + topics = Topic.base + assert_queries(2) do + topics.many? # use count query + topics.collect # force load + topics.many? # use loaded (no query) + end + end + + def test_many_should_call_proxy_found_if_using_a_block + topics = Topic.base + assert_queries(1) do + topics.expects(:size).never + topics.many? { true } + end + end + + def test_many_should_not_fire_query_if_named_scope_loaded + topics = Topic.base + topics.collect # force load + assert_no_queries { assert topics.many? } + end + + def test_many_should_return_false_if_none_or_one + topics = Topic.base.scoped(:conditions => {:id => 0}) + assert !topics.many? + topics = Topic.base.scoped(:conditions => {:id => 1}) + assert !topics.many? + end + + def test_many_should_return_true_if_more_than_one + assert Topic.base.many? + end + def test_should_build_with_proxy_options topic = Topic.approved.build({}) assert topic.approved -- cgit v1.2.3 From b33c0d98329b97f8f540ba455d419d5046e6bb39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Sun, 17 May 2009 13:51:35 -0500 Subject: replace the aaa_create_tables_test hack with loading test database schema in the test helper [#2663 state:resolved] Signed-off-by: Joshua Peek --- activerecord/test/cases/aaa_create_tables_test.rb | 24 ----------------------- activerecord/test/cases/helper.rb | 18 +++++++++++++++++ activerecord/test/schema/schema.rb | 5 ++++- activerecord/test/schema/schema2.rb | 6 ------ 4 files changed, 22 insertions(+), 31 deletions(-) delete mode 100644 activerecord/test/cases/aaa_create_tables_test.rb delete mode 100644 activerecord/test/schema/schema2.rb (limited to 'activerecord') diff --git a/activerecord/test/cases/aaa_create_tables_test.rb b/activerecord/test/cases/aaa_create_tables_test.rb deleted file mode 100644 index 3911afac49..0000000000 --- a/activerecord/test/cases/aaa_create_tables_test.rb +++ /dev/null @@ -1,24 +0,0 @@ -# The filename begins with "aaa" to ensure this is the first test. -require "cases/helper" - -class AAACreateTablesTest < ActiveRecord::TestCase - self.use_transactional_fixtures = false - - def test_load_schema - eval(File.read(SCHEMA_ROOT + "/schema.rb")) - if File.exists?(adapter_specific_schema_file) - eval(File.read(adapter_specific_schema_file)) - end - assert true - end - - def test_drop_and_create_courses_table - eval(File.read(SCHEMA_ROOT + "/schema2.rb")) - assert true - end - - private - def adapter_specific_schema_file - SCHEMA_ROOT + '/' + ActiveRecord::Base.connection.adapter_name.downcase + '_specific_schema.rb' - end -end diff --git a/activerecord/test/cases/helper.rb b/activerecord/test/cases/helper.rb index 05e92433cd..f82784836e 100644 --- a/activerecord/test/cases/helper.rb +++ b/activerecord/test/cases/helper.rb @@ -5,6 +5,7 @@ require 'config' require 'rubygems' require 'test/unit' +require 'stringio' gem 'mocha', '>= 0.9.5' require 'mocha' @@ -72,3 +73,20 @@ class ActiveSupport::TestCase Fixtures.create_fixtures(ActiveSupport::TestCase.fixture_path, table_names, {}, &block) end end + +# silence verbose schema loading +original_stdout = $stdout +$stdout = StringIO.new + +begin + adapter_name = ActiveRecord::Base.connection.adapter_name.downcase + adapter_specific_schema_file = SCHEMA_ROOT + "/#{adapter_name}_specific_schema.rb" + + load SCHEMA_ROOT + "/schema.rb" + + if File.exists?(adapter_specific_schema_file) + load adapter_specific_schema_file + end +ensure + $stdout = original_stdout +end diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index a776cd974b..4ee0ffe132 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -1,4 +1,3 @@ - ActiveRecord::Schema.define do def except(adapter_names_to_exclude) unless [adapter_names_to_exclude].flatten.include?(adapter_name) @@ -500,3 +499,7 @@ ActiveRecord::Schema.define do execute "ALTER TABLE fk_test_has_fk ADD CONSTRAINT fk_name FOREIGN KEY (#{quote_column_name 'fk_id'}) REFERENCES #{quote_table_name 'fk_test_has_pk'} (#{quote_column_name 'id'})" end end + +Course.connection.create_table :courses, :force => true do |t| + t.column :name, :string, :null => false +end diff --git a/activerecord/test/schema/schema2.rb b/activerecord/test/schema/schema2.rb deleted file mode 100644 index 8527f7ba8f..0000000000 --- a/activerecord/test/schema/schema2.rb +++ /dev/null @@ -1,6 +0,0 @@ -ActiveRecord::Schema.define do - - Course.connection.create_table :courses, :force => true do |t| - t.column :name, :string, :null => false - end -end -- cgit v1.2.3 From 01d7acd11d631d980497870aad1af42a0c66115c Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sun, 17 May 2009 14:42:36 -0500 Subject: Fix reset_session with ActiveRecord store [#2200 state:resolved] --- activerecord/lib/active_record/session_store.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/session_store.rb b/activerecord/lib/active_record/session_store.rb index 21471da419..9dda3361d8 100644 --- a/activerecord/lib/active_record/session_store.rb +++ b/activerecord/lib/active_record/session_store.rb @@ -295,7 +295,7 @@ module ActiveRecord def set_session(env, sid, session_data) Base.silence do - record = env[SESSION_RECORD_KEY] ||= find_session(sid) + record = get_session_model(env, sid) record.data = session_data return false unless record.save @@ -309,6 +309,14 @@ module ActiveRecord return true end + + def get_session_model(env, sid) + if env[ENV_SESSION_OPTIONS_KEY][:id].nil? + env[SESSION_RECORD_KEY] = find_session(sid) + else + env[SESSION_RECORD_KEY] ||= find_session(sid) + end + end def find_session(id) @@session_class.find_by_session_id(id) || -- cgit v1.2.3 From 27de7f150b57a18d4ccdd274f6f8b621b58108c6 Mon Sep 17 00:00:00 2001 From: Benjamin Floering Date: Sun, 17 May 2009 23:35:47 -0700 Subject: Fixed limited eager loading associations with numbers in the name [#2668 state:resolved] Signed-off-by: Pratik Naik --- activerecord/lib/active_record/associations.rb | 2 +- activerecord/test/cases/associations/eager_test.rb | 4 ++++ activerecord/test/fixtures/people.yml | 5 ++++- activerecord/test/models/person.rb | 1 + activerecord/test/schema/schema.rb | 1 + 5 files changed, 11 insertions(+), 2 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index c5e4df4950..76726b7845 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1668,7 +1668,7 @@ module ActiveRecord def tables_in_string(string) return [] if string.blank? - string.scan(/([\.a-zA-Z_]+).?\./).flatten + string.scan(/([a-zA-Z_][\.\w]+).?\./).flatten end def tables_in_hash(hash) diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index d23f86b700..65049c4f87 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -589,6 +589,10 @@ class EagerAssociationTest < ActiveRecord::TestCase assert_equal posts(:sti_post_and_comments, :sti_comments), Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title) DESC, posts.id', :limit => 2, :offset => 1) end + def test_limited_eager_with_numeric_in_association + assert_equal people(:david, :susan), Person.find(:all, :include => [:readers, :primary_contact, :number1_fan], :conditions => "number1_fans_people.first_name like 'M%'", :order => 'readers.id', :limit => 2, :offset => 0) + end + def test_preload_with_interpolation assert_equal [comments(:greetings)], Post.find(posts(:welcome).id, :include => :comments_with_interpolated_conditions).comments_with_interpolated_conditions end diff --git a/activerecord/test/fixtures/people.yml b/activerecord/test/fixtures/people.yml index 3babb1fe59..123673a2af 100644 --- a/activerecord/test/fixtures/people.yml +++ b/activerecord/test/fixtures/people.yml @@ -2,14 +2,17 @@ michael: id: 1 first_name: Michael primary_contact_id: 2 + number1_fan_id: 3 gender: M david: id: 2 first_name: David primary_contact_id: 3 + number1_fan_id: 1 gender: M susan: id: 3 first_name: Susan primary_contact_id: 2 - gender: F \ No newline at end of file + number1_fan_id: 1 + gender: F diff --git a/activerecord/test/models/person.rb b/activerecord/test/models/person.rb index ec2f684a6e..57fa6418f1 100644 --- a/activerecord/test/models/person.rb +++ b/activerecord/test/models/person.rb @@ -10,6 +10,7 @@ class Person < ActiveRecord::Base belongs_to :primary_contact, :class_name => 'Person' has_many :agents, :class_name => 'Person', :foreign_key => 'primary_contact_id' + belongs_to :number1_fan, :class_name => 'Person' named_scope :males, :conditions => { :gender => 'M' } named_scope :females, :conditions => { :gender => 'F' } diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index 4ee0ffe132..6e8813d8ab 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -324,6 +324,7 @@ ActiveRecord::Schema.define do t.string :first_name, :null => false t.references :primary_contact t.string :gender, :limit => 1 + t.references :number1_fan t.integer :lock_version, :null => false, :default => 0 end -- cgit v1.2.3 From 28f5cfe066dfa901d71c02987e390937a74517c8 Mon Sep 17 00:00:00 2001 From: Emilio Tagua Date: Mon, 18 May 2009 10:43:18 -0300 Subject: Add missing model and fixtures to finder_test [#2671 state:resolved] Signed-off-by: Pratik Naik --- activerecord/test/cases/finder_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activerecord') diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index d0d7094e30..037b67ec84 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -7,10 +7,10 @@ require 'models/company' require 'models/topic' require 'models/reply' require 'models/entrant' +require 'models/project' require 'models/developer' require 'models/customer' require 'models/job' -require 'models/categorization' class DynamicFinderMatchTest < ActiveRecord::TestCase def test_find_no_match @@ -64,7 +64,7 @@ class DynamicFinderMatchTest < ActiveRecord::TestCase end class FinderTest < ActiveRecord::TestCase - fixtures :companies, :topics, :entrants, :developers, :developers_projects, :posts, :comments, :accounts, :authors, :customers + fixtures :companies, :topics, :entrants, :developers, :developers_projects, :posts, :comments, :accounts, :authors, :customers, :categories, :categorizations def test_find assert_equal(topics(:first).title, Topic.find(1).title) -- cgit v1.2.3 From 37453e11e9c071f9bdec47b073939fd34402127d Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Mon, 18 May 2009 11:55:06 -0700 Subject: Revert "Get AR CI passing again by requiring the entire core_ext" This reverts commit 8e6a18d8672f7efe6ef79b49185e4a6a23e4e547. --- activerecord/lib/active_record.rb | 3 --- 1 file changed, 3 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb index b5c17cb23b..2d98239052 100644 --- a/activerecord/lib/active_record.rb +++ b/activerecord/lib/active_record.rb @@ -25,9 +25,6 @@ activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib" $:.unshift(activesupport_path) if File.directory?(activesupport_path) require 'active_support' -# TODO: Figure out what parts of AS are *actually* required and use those -require 'active_support/core_ext' - module ActiveRecord # TODO: Review explicit loads to see if they will automatically be handled by the initilizer. def self.load_all! -- cgit v1.2.3 From c5e109bbe766b0407a909361f18d2b87e9bfc75c Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Mon, 18 May 2009 21:27:42 +0200 Subject: Make sure default_scope#create checks for options[:conditions] [#2181 state:resolved] [James Le Cuirot] --- activerecord/lib/active_record/base.rb | 2 +- activerecord/test/cases/method_scoping_test.rb | 10 ++++++++++ activerecord/test/models/developer.rb | 10 ++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index ca4f4fa6b6..968b9bde5a 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -2176,7 +2176,7 @@ module ActiveRecord #:nodoc: # default_scope :order => 'last_name, first_name' # end def default_scope(options = {}) - self.default_scoping << { :find => options, :create => (options.is_a?(Hash) && options.has_key?(:conditions)) ? options[:conditions] : {} } + self.default_scoping << { :find => options, :create => options[:conditions].is_a?(Hash) ? options[:conditions] : {} } end # Test whether the given method and optional key are scoped. diff --git a/activerecord/test/cases/method_scoping_test.rb b/activerecord/test/cases/method_scoping_test.rb index c479859ee0..d8246f49b8 100644 --- a/activerecord/test/cases/method_scoping_test.rb +++ b/activerecord/test/cases/method_scoping_test.rb @@ -591,6 +591,16 @@ class DefaultScopingTest < ActiveRecord::TestCase assert_equal expected, received end + def test_default_scope_with_conditions_string + assert_equal Developer.find_all_by_name('David').map(&:id).sort, DeveloperCalledDavid.all.map(&:id).sort + assert_equal nil, DeveloperCalledDavid.create!.name + end + + def test_default_scope_with_conditions_hash + assert_equal Developer.find_all_by_name('Jamis').map(&:id).sort, DeveloperCalledJamis.all.map(&:id).sort + assert_equal 'Jamis', DeveloperCalledJamis.create!.name + end + def test_default_scoping_with_threads scope = [{ :create => {}, :find => { :order => 'salary DESC' } }] diff --git a/activerecord/test/models/developer.rb b/activerecord/test/models/developer.rb index 92039a4f54..058970336b 100644 --- a/activerecord/test/models/developer.rb +++ b/activerecord/test/models/developer.rb @@ -89,3 +89,13 @@ class DeveloperOrderedBySalary < ActiveRecord::Base end end end + +class DeveloperCalledDavid < ActiveRecord::Base + self.table_name = 'developers' + default_scope :conditions => "name = 'David'" +end + +class DeveloperCalledJamis < ActiveRecord::Base + self.table_name = 'developers' + default_scope :conditions => { :name => 'Jamis' } +end -- cgit v1.2.3 From a69b28a8b10fdcbb6801051e3086228b56891dbb Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Mon, 18 May 2009 13:20:04 -0700 Subject: Missing 1.8.7 backport extensions --- activerecord/lib/active_record/base.rb | 1 + activerecord/lib/active_record/validations.rb | 2 ++ 2 files changed, 3 insertions(+) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index ca4f4fa6b6..e8e1746b4b 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -9,6 +9,7 @@ require 'active_support/core_ext/hash/deep_merge' require 'active_support/core_ext/hash/indifferent_access' require 'active_support/core_ext/hash/slice' require 'active_support/core_ext/string/behavior' +require 'active_support/core_ext/symbol' require 'active_support/core/time' module ActiveRecord #:nodoc: diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb index b6e848fa79..a18fb3f426 100644 --- a/activerecord/lib/active_record/validations.rb +++ b/activerecord/lib/active_record/validations.rb @@ -1,3 +1,5 @@ +require 'active_support/core_ext/integer/even_odd' + module ActiveRecord # Raised by save! and create! when the record is invalid. Use the # +record+ method to retrieve the record which did not validate. -- cgit v1.2.3 From cef76c8af4705dc60f85a721e3a14adb99418d33 Mon Sep 17 00:00:00 2001 From: Luca Guidi Date: Mon, 16 Mar 2009 13:30:30 +0100 Subject: Ensure HasManyThroughAssociation#destroy delete orphan records [#2251 state:resolved] Signed-off-by: Pratik Naik --- .../active_record/associations/has_many_through_association.rb | 7 +++++++ .../cases/associations/has_many_through_associations_test.rb | 10 ++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb index 2dca84b911..e8dbae9011 100644 --- a/activerecord/lib/active_record/associations/has_many_through_association.rb +++ b/activerecord/lib/active_record/associations/has_many_through_association.rb @@ -17,6 +17,13 @@ module ActiveRecord end end + def destroy(*records) + transaction do + delete_records(flatten_deeper(records)) + super + end + end + # Returns the size of the collection by executing a SELECT COUNT(*) query if the collection hasn't been loaded and # calling collection.size if it has. If it's more likely than not that the collection does have a size larger than zero, # and you need to fetch that collection afterwards, it'll take one fewer SELECT query if you use #length. diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb index 97efca7891..51c70b9819 100644 --- a/activerecord/test/cases/associations/has_many_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb @@ -93,7 +93,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase end def test_destroy_association - assert_difference "Person.count", -1 do + assert_difference ["Person.count", "Reader.count"], -1 do posts(:welcome).people.destroy(people(:michael)) end @@ -102,7 +102,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase end def test_destroy_all - assert_difference "Person.count", -1 do + assert_difference ["Person.count", "Reader.count"], -1 do posts(:welcome).people.destroy_all end @@ -110,6 +110,12 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase assert posts(:welcome).people(true).empty? end + def test_should_raise_exception_for_destroying_mismatching_records + assert_no_difference ["Person.count", "Reader.count"] do + assert_raise(ActiveRecord::AssociationTypeMismatch) { posts(:welcome).people.destroy(posts(:thinking)) } + end + end + def test_replace_association assert_queries(4){posts(:welcome);people(:david);people(:michael); posts(:welcome).people(true)} -- cgit v1.2.3 From 87adecfef59577be17a9731245cb201ecb1b477f Mon Sep 17 00:00:00 2001 From: Ken Collins Date: Mon, 11 May 2009 23:22:20 -0400 Subject: Reimplement Fixtures.identify so that it consistently generates identities across ruby versions. [#2633 state:committed] Signed-off-by: Jeremy Kemper --- activerecord/lib/active_record/fixtures.rb | 9 +++++---- activerecord/test/cases/fixtures_test.rb | 5 +++++ 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb index e30fcf9a4f..721114d9d0 100644 --- a/activerecord/lib/active_record/fixtures.rb +++ b/activerecord/lib/active_record/fixtures.rb @@ -1,6 +1,7 @@ require 'erb' require 'yaml' require 'csv' +require 'zlib' require 'active_support/dependencies' require 'active_support/test_case' require 'active_support/core_ext/logger' @@ -434,6 +435,7 @@ end # Any fixture labeled "DEFAULTS" is safely ignored. class Fixtures < (RUBY_VERSION < '1.9' ? YAML::Omap : Hash) + MAX_ID = 2 ** 31 - 1 DEFAULT_FILTER_RE = /\.ya?ml$/ @@all_cached_fixtures = {} @@ -525,11 +527,10 @@ class Fixtures < (RUBY_VERSION < '1.9' ? YAML::Omap : Hash) cached_fixtures(connection, table_names) end - # Returns a consistent identifier for +label+. This will always - # be a positive integer, and will always be the same for a given - # label, assuming the same OS, platform, and version of Ruby. + # Returns a consistent, platform-independent identifier for +label+. + # Identifiers are positive integers less than 2^32. def self.identify(label) - label.to_s.hash.abs + Zlib.crc32(label.to_s) % MAX_ID end attr_reader :table_name, :name diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb index 252bf4ff61..b07d4f3521 100644 --- a/activerecord/test/cases/fixtures_test.rb +++ b/activerecord/test/cases/fixtures_test.rb @@ -518,6 +518,11 @@ class FoxyFixturesTest < ActiveRecord::TestCase assert_equal(Fixtures.identify(:foo), Fixtures.identify(:foo)) end + def test_identifies_consistently + assert_equal 1281023246, Fixtures.identify(:ruby) + assert_equal 2140105598, Fixtures.identify(:sapphire_2) + end + TIMESTAMP_COLUMNS = %w(created_at created_on updated_at updated_on) def test_populates_timestamp_columns -- cgit v1.2.3 From 5463823df38310d392a3f87d633dce9b4150259a Mon Sep 17 00:00:00 2001 From: Emilio Tagua Date: Sat, 2 May 2009 13:56:10 -0300 Subject: Remove unnecessary condition and local variable [#2602 state:resolved] Signed-off-by: Pratik Naik --- activerecord/lib/active_record/base.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 968b9bde5a..af800261e5 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1541,12 +1541,12 @@ module ActiveRecord #:nodoc: end def reverse_sql_order(order_query) - reversed_query = order_query.to_s.split(/,/).each { |s| + order_query.to_s.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)$/) + else s.concat(' DESC') end }.join(',') -- cgit v1.2.3 From 20deb677a23d2a57f0a946dc98debe0fcdb70c40 Mon Sep 17 00:00:00 2001 From: Emilio Tagua Date: Mon, 18 May 2009 20:17:35 -0300 Subject: Add missing models and fixtures [#2673 state:resolved] Signed-off-by: Pratik Naik --- .../has_many_through_associations_test.rb | 46 +++++++++++----------- .../test/cases/autosave_association_test.rb | 7 +++- activerecord/test/cases/named_scope_test.rb | 4 +- 3 files changed, 32 insertions(+), 25 deletions(-) (limited to 'activerecord') diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb index 51c70b9819..4254badef2 100644 --- a/activerecord/test/cases/associations/has_many_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb @@ -13,7 +13,7 @@ require 'models/pet' require 'models/toy' class HasManyThroughAssociationsTest < ActiveRecord::TestCase - fixtures :posts, :readers, :people, :comments, :authors, :owners, :pets, :toys + fixtures :posts, :readers, :people, :comments, :authors, :owners, :pets, :toys, :jobs, :references def test_associate_existing assert_queries(2) { posts(:thinking);people(:david) } @@ -23,49 +23,49 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase assert_queries(1) do posts(:thinking).people << people(:david) end - + assert_queries(1) do assert posts(:thinking).people.include?(people(:david)) end - + assert posts(:thinking).reload.people(true).include?(people(:david)) end def test_associating_new assert_queries(1) { posts(:thinking) } new_person = nil # so block binding catches it - + assert_queries(0) do new_person = Person.new :first_name => 'bob' end - + # Associating new records always saves them # Thus, 1 query for the new person record, 1 query for the new join table record assert_queries(2) do posts(:thinking).people << new_person end - + assert_queries(1) do assert posts(:thinking).people.include?(new_person) end - + assert posts(:thinking).reload.people(true).include?(new_person) end def test_associate_new_by_building assert_queries(1) { posts(:thinking) } - + assert_queries(0) do posts(:thinking).people.build(:first_name=>"Bob") posts(:thinking).people.new(:first_name=>"Ted") end - + # Should only need to load the association once assert_queries(1) do assert posts(:thinking).people.collect(&:first_name).include?("Bob") assert posts(:thinking).people.collect(&:first_name).include?("Ted") end - + # 2 queries for each new record (1 to save the record itself, 1 for the join model) # * 2 new records = 4 # + 1 query to save the actual post = 5 @@ -73,22 +73,22 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase posts(:thinking).body += '-changed' posts(:thinking).save end - + assert posts(:thinking).reload.people(true).collect(&:first_name).include?("Bob") assert posts(:thinking).reload.people(true).collect(&:first_name).include?("Ted") end def test_delete_association assert_queries(2){posts(:welcome);people(:michael); } - + assert_queries(1) do posts(:welcome).people.delete(people(:michael)) end - + assert_queries(1) do assert posts(:welcome).people.empty? end - + assert posts(:welcome).reload.people(true).empty? end @@ -118,36 +118,36 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase def test_replace_association assert_queries(4){posts(:welcome);people(:david);people(:michael); posts(:welcome).people(true)} - + # 1 query to delete the existing reader (michael) # 1 query to associate the new reader (david) assert_queries(2) do posts(:welcome).people = [people(:david)] end - + assert_queries(0){ assert posts(:welcome).people.include?(people(:david)) assert !posts(:welcome).people.include?(people(:michael)) } - + assert posts(:welcome).reload.people(true).include?(people(:david)) assert !posts(:welcome).reload.people(true).include?(people(:michael)) end def test_associate_with_create assert_queries(1) { posts(:thinking) } - + # 1 query for the new record, 1 for the join table record # No need to update the actual collection yet! assert_queries(2) do posts(:thinking).people.create(:first_name=>"Jeb") end - + # *Now* we actually need the collection so it's loaded assert_queries(1) do assert posts(:thinking).people.collect(&:first_name).include?("Jeb") end - + assert posts(:thinking).reload.people(true).collect(&:first_name).include?("Jeb") end @@ -165,15 +165,15 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase def test_clear_associations assert_queries(2) { posts(:welcome);posts(:welcome).people(true) } - + assert_queries(1) do posts(:welcome).people.clear end - + assert_queries(0) do assert posts(:welcome).people.empty? end - + assert posts(:welcome).reload.people(true).empty? end diff --git a/activerecord/test/cases/autosave_association_test.rb b/activerecord/test/cases/autosave_association_test.rb index 919b6f857c..f95b2c0079 100644 --- a/activerecord/test/cases/autosave_association_test.rb +++ b/activerecord/test/cases/autosave_association_test.rb @@ -12,6 +12,7 @@ require 'models/reader' require 'models/ship' require 'models/ship_part' require 'models/treasure' +require 'models/company' class TestAutosaveAssociationsInGeneral < ActiveRecord::TestCase def test_autosave_should_be_a_valid_option_for_has_one @@ -38,6 +39,8 @@ class TestAutosaveAssociationsInGeneral < ActiveRecord::TestCase end class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase + fixtures :companies, :accounts + def test_should_save_parent_but_not_invalid_child firm = Firm.new(:name => 'GlobalMegaCorp') assert firm.valid? @@ -137,6 +140,8 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas end class TestDefaultAutosaveAssociationOnABelongsToAssociation < ActiveRecord::TestCase + fixtures :companies + def test_should_save_parent_but_not_invalid_child client = Client.new(:name => 'Joe (the Plumber)') assert client.valid? @@ -920,4 +925,4 @@ class TestAutosaveAssociationOnAHasAndBelongsToManyAssociation < ActiveRecord::T end include AutosaveAssociationOnACollectionAssociationTests -end \ No newline at end of file +end diff --git a/activerecord/test/cases/named_scope_test.rb b/activerecord/test/cases/named_scope_test.rb index 69d01d5c2a..92fe48cb5a 100644 --- a/activerecord/test/cases/named_scope_test.rb +++ b/activerecord/test/cases/named_scope_test.rb @@ -373,7 +373,7 @@ class NamedScopeTest < ActiveRecord::TestCase end end -class DynamicScopeMatchTest < ActiveRecord::TestCase +class DynamicScopeMatchTest < ActiveRecord::TestCase def test_scoped_by_no_match assert_nil ActiveRecord::DynamicScopeMatch.match("not_scoped_at_all") end @@ -387,6 +387,8 @@ class DynamicScopeMatchTest < ActiveRecord::TestCase end class DynamicScopeTest < ActiveRecord::TestCase + fixtures :posts + def test_dynamic_scope assert_equal Post.scoped_by_author_id(1).find(1), Post.find(1) assert_equal Post.scoped_by_author_id_and_title(1, "Welcome to the weblog").first, Post.find(:first, :conditions => { :author_id => 1, :title => "Welcome to the weblog"}) -- cgit v1.2.3 From 5f222c524ed00b2ac805e267f70a916cf8f9bc77 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 20 May 2009 17:11:41 -0700 Subject: Remove 'core' fluff. Hookable ActiveSupport.load_all! --- activerecord/lib/active_record/base.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 8a65945e61..ec49d40a12 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1,6 +1,7 @@ require 'yaml' require 'set' require 'active_support/dependencies' +require 'active_support/time' require 'active_support/core_ext/class/attribute_accessors' require 'active_support/core_ext/class/delegating_attributes' require 'active_support/core_ext/class/inheritable_attributes' @@ -10,7 +11,6 @@ require 'active_support/core_ext/hash/indifferent_access' require 'active_support/core_ext/hash/slice' require 'active_support/core_ext/string/behavior' require 'active_support/core_ext/symbol' -require 'active_support/core/time' module ActiveRecord #:nodoc: # Generic Active Record exception class. -- cgit v1.2.3 From 0f1b283e03633410729aa006f6abf070c713095d Mon Sep 17 00:00:00 2001 From: Chad Woolley Date: Thu, 21 May 2009 00:41:19 -0700 Subject: Fix eager association test related to different ordering on sqlite [#2686 state:committed] Signed-off-by: Jeremy Kemper --- activerecord/test/cases/associations/eager_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index 65049c4f87..4cf49be668 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -590,7 +590,7 @@ class EagerAssociationTest < ActiveRecord::TestCase end def test_limited_eager_with_numeric_in_association - assert_equal people(:david, :susan), Person.find(:all, :include => [:readers, :primary_contact, :number1_fan], :conditions => "number1_fans_people.first_name like 'M%'", :order => 'readers.id', :limit => 2, :offset => 0) + assert_equal people(:david, :susan), Person.find(:all, :include => [:readers, :primary_contact, :number1_fan], :conditions => "number1_fans_people.first_name like 'M%'", :order => 'people.id', :limit => 2, :offset => 0) end def test_preload_with_interpolation -- cgit v1.2.3