From 8e56085817e752bb361738ec6ca7362a3398ed77 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 16 Jun 2010 09:59:59 -0700 Subject: use assert_in_delta() for floating point comparisons in tests [#4871 state:resolved] Signed-off-by: Carl Lerche --- activerecord/test/cases/migration_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index ddadde8dcf..6fe3b01281 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -1032,7 +1032,7 @@ if ActiveRecord::Base.connection.supports_migrations? elsif current_adapter?(:SQLiteAdapter) # - SQLite3 stores a float, in violation of SQL assert_kind_of BigDecimal, b.value_of_e - assert_equal BigDecimal("2.71828182845905"), b.value_of_e + assert_in_delta BigDecimal("2.71828182845905"), b.value_of_e, 0.00000000000001 else # - SQL standard is an integer assert_kind_of Fixnum, b.value_of_e -- cgit v1.2.3 From 01f3f0dbae3e5ecfd18109a0f2ec37ed0d767a8e Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Wed, 16 Jun 2010 22:30:06 +0200 Subject: use RDoc 2.2 to generate the documentation of individual components --- activerecord/Rakefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/Rakefile b/activerecord/Rakefile index bf05389eae..307e2a2c23 100644 --- a/activerecord/Rakefile +++ b/activerecord/Rakefile @@ -1,4 +1,5 @@ -require 'rubygems' +gem 'rdoc', '= 2.2' +require 'rdoc' require 'rake' require 'rake/testtask' require 'rake/rdoctask' -- cgit v1.2.3 From 2aa4e5f3fab6e0625f5f52f84518d16f23c69346 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Wed, 16 Jun 2010 22:39:13 +0200 Subject: pdoc tasks publishe APIs in api.rubyonrails.org --- activerecord/Rakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/Rakefile b/activerecord/Rakefile index 307e2a2c23..12e094b406 100644 --- a/activerecord/Rakefile +++ b/activerecord/Rakefile @@ -223,5 +223,5 @@ end desc "Publish the API documentation" task :pdoc => [:rdoc] do require 'rake/contrib/sshpublisher' - Rake::SshDirPublisher.new("wrath.rubyonrails.org", "public_html/ar", "doc").upload + Rake::SshDirPublisher.new("rails@api.rubyonrails.org", "public_html/ar", "doc").upload end -- cgit v1.2.3 From 12eef93e8901d3bdfe67bdb04c307ddc920221eb Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Thu, 17 Jun 2010 17:41:39 +0200 Subject: documents how to run an individual test in AR --- activerecord/RUNNING_UNIT_TESTS | 2 ++ 1 file changed, 2 insertions(+) (limited to 'activerecord') diff --git a/activerecord/RUNNING_UNIT_TESTS b/activerecord/RUNNING_UNIT_TESTS index 8559d72647..03e561a50b 100644 --- a/activerecord/RUNNING_UNIT_TESTS +++ b/activerecord/RUNNING_UNIT_TESTS @@ -32,5 +32,7 @@ being initialized - you can initialize the schema with: rake test_mysql TEST=test/cases/aaa_create_tables_test.rb +The incantation for running a particular test looks like this + ruby -w -I"lib:test:test/connections/native_postgresql" test/cases/datatype_test_postgresql.rb -n test_timestamp_with_zone_values_without_rails_time_zone_support -- cgit v1.2.3 From bf6661c5d75d8e29ebd5f6011f97a85c892663a0 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 17 Jun 2010 16:39:36 -0700 Subject: setting the timezone in postgres to whatever ruby thinks the timezone is [#4895 state:resolved] Signed-off-by: Jeremy Kemper --- activerecord/CHANGELOG | 5 +++++ .../lib/active_record/connection_adapters/postgresql_adapter.rb | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index 7d5e550a7c..def519c05d 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -1,3 +1,8 @@ +*Rails 3.0.0 [RC1] (unreleased)* + +* PostgreSQL: ensure the database time zone matches Ruby's time zone. #4895 [Aaron Patterson] + + *Rails 3.0.0 [beta 4] (June 8th, 2010)* * Fixed that ActiveRecord::Base.compute_type would swallow NoMethodError #4751 [Andrew Bloomgarden, Andrew White] diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index bb8850f134..e84242601b 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -927,7 +927,12 @@ module ActiveRecord # If using Active Record's time zone support configure the connection to return # TIMESTAMP WITH ZONE types in UTC. - execute("SET time zone 'UTC'") if ActiveRecord::Base.default_timezone == :utc + if ActiveRecord::Base.default_timezone == :utc + execute("SET time zone 'UTC'") + else + offset = Time.local(2000).utc_offset / 3600 + execute("SET time zone '#{offset}'") + end end # Returns the current ID of a table's sequence. -- cgit v1.2.3 From 237165feb3e5f7b117b05353bd64d756b9f18f74 Mon Sep 17 00:00:00 2001 From: Brian Durand Date: Fri, 18 Jun 2010 16:59:33 -0500 Subject: Fix bug with rolling back frozen attributes. [#2991] Signed-off-by: Jeremy Kemper --- .../connection_adapters/abstract/database_statements.rb | 4 ++-- activerecord/lib/active_record/transactions.rb | 1 + activerecord/test/cases/autosave_association_test.rb | 1 - activerecord/test/cases/transaction_callbacks_test.rb | 14 +++++++++++--- 4 files changed, 14 insertions(+), 6 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb index b9fb452eee..25432e9985 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb @@ -304,7 +304,7 @@ module ActiveRecord begin record.rolledback!(rollback) rescue Exception => e - record.logger.error(e) if record.respond_to?(:logger) + record.logger.error(e) if record.respond_to?(:logger) && record.logger end end end @@ -319,7 +319,7 @@ module ActiveRecord begin record.committed! rescue Exception => e - record.logger.error(e) if record.respond_to?(:logger) + record.logger.error(e) if record.respond_to?(:logger) && record.logger end end end diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb index 620758f5af..775d9f0fb8 100644 --- a/activerecord/lib/active_record/transactions.rb +++ b/activerecord/lib/active_record/transactions.rb @@ -320,6 +320,7 @@ module ActiveRecord if @_start_transaction_state[:level] < 1 restore_state = remove_instance_variable(:@_start_transaction_state) if restore_state + @attributes = @attributes.dup if @attributes.frozen? @new_record = restore_state[:new_record] @destroyed = restore_state[:destroyed] if restore_state[:id] diff --git a/activerecord/test/cases/autosave_association_test.rb b/activerecord/test/cases/autosave_association_test.rb index 4e4f9c385c..3b89c12a3f 100644 --- a/activerecord/test/cases/autosave_association_test.rb +++ b/activerecord/test/cases/autosave_association_test.rb @@ -712,7 +712,6 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase end assert_raise(RuntimeError) { assert !@pirate.save } - assert before.first.frozen? # the first child was indeed destroyed assert_equal before, @pirate.reload.send(association_name) end diff --git a/activerecord/test/cases/transaction_callbacks_test.rb b/activerecord/test/cases/transaction_callbacks_test.rb index ebc16653cb..df123c9de8 100644 --- a/activerecord/test/cases/transaction_callbacks_test.rb +++ b/activerecord/test/cases/transaction_callbacks_test.rb @@ -221,20 +221,28 @@ class TransactionCallbacksTest < ActiveRecord::TestCase assert_equal 2, @first.rollbacks end - def test_after_transaction_callbacks_should_not_raise_errors + def test_after_transaction_callbacks_should_prevent_callbacks_from_being_called def @first.last_after_transaction_error=(e); @last_transaction_error = e; end def @first.last_after_transaction_error; @last_transaction_error; end @first.after_commit_block{|r| r.last_after_transaction_error = :commit; raise "fail!";} @first.after_rollback_block{|r| r.last_after_transaction_error = :rollback; raise "fail!";} + @second.after_commit_block{|r| r.history << :after_commit} + @second.after_rollback_block{|r| r.history << :after_rollback} - @first.save! + Topic.transaction do + @first.save! + @second.save! + end assert_equal :commit, @first.last_after_transaction_error + assert_equal [:after_commit], @second.history + @second.history.clear Topic.transaction do @first.save! + @second.save! raise ActiveRecord::Rollback end - assert_equal :rollback, @first.last_after_transaction_error + assert_equal [:after_rollback], @second.history end end -- cgit v1.2.3 From a7cae64104008b124c834b839887bbbbe148219b Mon Sep 17 00:00:00 2001 From: Master Lambaster Date: Tue, 25 May 2010 16:11:23 +0300 Subject: Fix test which prevents connection reset on failing and remove hardcoded connection [#4689 state:committed] Signed-off-by: Jeremy Kemper --- activerecord/test/cases/adapter_test.rb | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'activerecord') diff --git a/activerecord/test/cases/adapter_test.rb b/activerecord/test/cases/adapter_test.rb index fc08c2178a..646aa88d80 100644 --- a/activerecord/test/cases/adapter_test.rb +++ b/activerecord/test/cases/adapter_test.rb @@ -65,15 +65,14 @@ class AdapterTest < ActiveRecord::TestCase end def test_not_specifying_database_name_for_cross_database_selects - assert_nothing_raised do - ActiveRecord::Base.establish_connection({ - :adapter => 'mysql', - :username => 'rails' - }) - ActiveRecord::Base.connection.execute "SELECT activerecord_unittest.pirates.*, activerecord_unittest2.courses.* FROM activerecord_unittest.pirates, activerecord_unittest2.courses" + begin + assert_nothing_raised do + ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['arunit'].except(:database)) + ActiveRecord::Base.connection.execute "SELECT activerecord_unittest.pirates.*, activerecord_unittest2.courses.* FROM activerecord_unittest.pirates, activerecord_unittest2.courses" + end + ensure + ActiveRecord::Base.establish_connection 'arunit' end - - ActiveRecord::Base.establish_connection 'arunit' end end -- cgit v1.2.3 From 033e0a041f10ef4d4aa8ebb576560df20b971026 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sat, 19 Jun 2010 17:15:21 +0200 Subject: ActiveRecord and ActionPack now use the new descendants implementation. --- activerecord/lib/active_record/associations.rb | 2 +- activerecord/lib/active_record/base.rb | 36 +++----------------------- activerecord/lib/active_record/observer.rb | 3 ++- activerecord/test/cases/base_test.rb | 4 --- 4 files changed, 7 insertions(+), 38 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 9b59266bbc..567218e6fb 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -2066,7 +2066,7 @@ module ActiveRecord unless klass.descends_from_active_record? sti_column = aliased_table[klass.inheritance_column] sti_condition = sti_column.eq(klass.sti_name) - klass.send(:subclasses).each {|subclass| sti_condition = sti_condition.or(sti_column.eq(subclass.sti_name)) } + klass.descendants.each {|subclass| sti_condition = sti_condition.or(sti_column.eq(subclass.sti_name)) } @join << sti_condition end diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 3b6ffa46f2..def0fdaa2f 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -2,6 +2,7 @@ require 'yaml' require 'set' require 'active_support/benchmarkable' require 'active_support/dependencies' +require 'active_support/descendants_tracker' require 'active_support/time' require 'active_support/core_ext/class/attribute' require 'active_support/core_ext/class/attribute_accessors' @@ -274,28 +275,6 @@ module ActiveRecord #:nodoc: # on to any new database connections made and which can be retrieved on both a class and instance level by calling +logger+. cattr_accessor :logger, :instance_writer => false - def self.inherited(child) #:nodoc: - @@subclasses[self] ||= [] - @@subclasses[self] << child - super - end - - def self.reset_subclasses #:nodoc: - nonreloadables = [] - subclasses.each do |klass| - unless ActiveSupport::Dependencies.autoloaded? klass - nonreloadables << klass - next - end - klass.instance_variables.each { |var| klass.send(:remove_instance_variable, var) } - klass.instance_methods(false).each { |m| klass.send :undef_method, m } - end - @@subclasses = {} - nonreloadables.each { |klass| (@@subclasses[klass.superclass] ||= []) << klass } - end - - @@subclasses = {} - ## # :singleton-method: # Contains the database configuration - as is typically stored in config/database.yml - @@ -810,7 +789,7 @@ module ActiveRecord #:nodoc: end def reset_column_information_and_inheritable_attributes_for_all_subclasses#:nodoc: - subclasses.each { |klass| klass.reset_inheritable_attributes; klass.reset_column_information } + descendants.each { |klass| klass.reset_inheritable_attributes; klass.reset_column_information } end def attribute_method?(attribute) @@ -975,7 +954,7 @@ module ActiveRecord #:nodoc: def type_condition sti_column = arel_table[inheritance_column] condition = sti_column.eq(sti_name) - subclasses.each{|subclass| condition = condition.or(sti_column.eq(subclass.sti_name)) } + descendants.each { |subclass| condition = condition.or(sti_column.eq(subclass.sti_name)) } condition end @@ -1165,14 +1144,6 @@ module ActiveRecord #:nodoc: with_scope(method_scoping, :overwrite, &block) end - # Returns a list of all subclasses of this class, meaning all descendants. - def subclasses - @@subclasses[self] ||= [] - @@subclasses[self] + @@subclasses[self].inject([]) {|list, subclass| list + subclass.subclasses } - end - - public :subclasses - # Sets the default options for the model. The format of the # options argument is the same as in find. # @@ -1900,6 +1871,7 @@ module ActiveRecord #:nodoc: extend ActiveModel::Naming extend QueryCache::ClassMethods extend ActiveSupport::Benchmarkable + extend ActiveSupport::DescendantsTracker include ActiveModel::Conversion include Validations diff --git a/activerecord/lib/active_record/observer.rb b/activerecord/lib/active_record/observer.rb index 0ea7fe7365..fabbc33005 100644 --- a/activerecord/lib/active_record/observer.rb +++ b/activerecord/lib/active_record/observer.rb @@ -105,8 +105,9 @@ module ActiveRecord end protected + def observed_subclasses - observed_classes.sum([]) { |klass| klass.send(:subclasses) } + observed_classes.sum([]) { |klass| klass.send(:descendants) } end def observe_callbacks? diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index 5c175de6d4..7c74d87b61 100755 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -2076,10 +2076,6 @@ class BasicsTest < ActiveRecord::TestCase assert !SubStiPost.descends_from_active_record? end - def test_base_subclasses_is_public_method - assert ActiveRecord::Base.public_methods.map(&:to_sym).include?(:subclasses) - end - def test_find_on_abstract_base_class_doesnt_use_type_condition old_class = LooseDescendant Object.send :remove_const, :LooseDescendant -- cgit v1.2.3 From 312f43324159fbcd8749cd331ed7d6500a714a83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sat, 19 Jun 2010 17:51:29 +0200 Subject: Clear DescendantsTracker on each request. --- activerecord/lib/active_record/railtie.rb | 1 - 1 file changed, 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/railtie.rb b/activerecord/lib/active_record/railtie.rb index a32fb7d399..0386fd4651 100644 --- a/activerecord/lib/active_record/railtie.rb +++ b/activerecord/lib/active_record/railtie.rb @@ -68,7 +68,6 @@ module ActiveRecord unless app.config.cache_classes ActiveSupport.on_load(:active_record) do ActionDispatch::Callbacks.after do - ActiveRecord::Base.reset_subclasses ActiveRecord::Base.clear_reloadable_connections! end end -- cgit v1.2.3 From 51739d3228d12907d60fb1b0a2b1ef96c55f66a3 Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Wed, 16 Jun 2010 11:30:37 -0400 Subject: moving before_validation and after_validation functionality from ActiveRecord to ActiveModel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [#4653 state:resolved] Signed-off-by: José Valim --- activerecord/lib/active_record/base.rb | 1 + activerecord/lib/active_record/callbacks.rb | 23 +++-------------------- activerecord/lib/active_record/validations.rb | 4 ++-- 3 files changed, 6 insertions(+), 22 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index def0fdaa2f..ef8dbdb6e5 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1874,6 +1874,7 @@ module ActiveRecord #:nodoc: extend ActiveSupport::DescendantsTracker include ActiveModel::Conversion + include ActiveModel::Validations::Callbacks include Validations extend CounterCache include Locking::Optimistic, Locking::Pessimistic diff --git a/activerecord/lib/active_record/callbacks.rb b/activerecord/lib/active_record/callbacks.rb index 44fee12001..42b56a3cf8 100644 --- a/activerecord/lib/active_record/callbacks.rb +++ b/activerecord/lib/active_record/callbacks.rb @@ -235,7 +235,7 @@ module ActiveRecord included do extend ActiveModel::Callbacks - define_callbacks :validation, :terminator => "result == false", :scope => [:kind, :name] + attr_accessor :validation_context define_model_callbacks :initialize, :find, :only => :after define_model_callbacks :save, :create, :update, :destroy @@ -250,28 +250,11 @@ module ActiveRecord end end - def before_validation(*args, &block) - options = args.last - if options.is_a?(Hash) && options[:on] - options[:if] = Array.wrap(options[:if]) - options[:if] << "@_on_validate == :#{options[:on]}" - end - set_callback(:validation, :before, *args, &block) - end - - def after_validation(*args, &block) - options = args.extract_options! - options[:prepend] = true - options[:if] = Array.wrap(options[:if]) - options[:if] << "!halted && value != false" - options[:if] << "@_on_validate == :#{options[:on]}" if options[:on] - set_callback(:validation, :after, *(args << options), &block) - end end def valid?(*) #:nodoc: - @_on_validate = new_record? ? :create : :update - _run_validation_callbacks { super } + self.validation_context = new_record? ? :create : :update + super end def destroy #:nodoc: diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb index be64e00bd1..6ef9382b2a 100644 --- a/activerecord/lib/active_record/validations.rb +++ b/activerecord/lib/active_record/validations.rb @@ -49,12 +49,12 @@ module ActiveRecord # Runs all the specified validations and returns true if no errors were added otherwise false. def valid?(context = nil) context ||= (new_record? ? :create : :update) - super(context) + output = super(context) deprecated_callback_method(:validate) deprecated_callback_method(:"validate_on_#{context}") - errors.empty? + errors.empty? && output end protected -- cgit v1.2.3 From 0247995d05b3cd3ff5fe32d5fbd8fdd866646909 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sat, 19 Jun 2010 18:18:45 +0200 Subject: ActiveModel::Validations::Callbacks should not be required by default. --- activerecord/lib/active_record/base.rb | 1 - activerecord/lib/active_record/callbacks.rb | 10 ++-------- 2 files changed, 2 insertions(+), 9 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index ef8dbdb6e5..def0fdaa2f 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1874,7 +1874,6 @@ module ActiveRecord #:nodoc: extend ActiveSupport::DescendantsTracker include ActiveModel::Conversion - include ActiveModel::Validations::Callbacks include Validations extend CounterCache include Locking::Optimistic, Locking::Pessimistic diff --git a/activerecord/lib/active_record/callbacks.rb b/activerecord/lib/active_record/callbacks.rb index 42b56a3cf8..997c85ef8c 100644 --- a/activerecord/lib/active_record/callbacks.rb +++ b/activerecord/lib/active_record/callbacks.rb @@ -234,8 +234,7 @@ module ActiveRecord included do extend ActiveModel::Callbacks - - attr_accessor :validation_context + include ActiveModel::Validations::Callbacks define_model_callbacks :initialize, :find, :only => :after define_model_callbacks :save, :create, :update, :destroy @@ -249,12 +248,6 @@ module ActiveRecord send(meth.to_sym, meth.to_sym) end end - - end - - def valid?(*) #:nodoc: - self.validation_context = new_record? ? :create : :update - super end def destroy #:nodoc: @@ -269,6 +262,7 @@ module ActiveRecord end private + def create_or_update #:nodoc: _run_save_callbacks { super } end -- cgit v1.2.3 From f664c57fe854c230d25c448b941569b81860fa79 Mon Sep 17 00:00:00 2001 From: James Le Cuirot Date: Sat, 12 Jun 2010 11:55:31 +0100 Subject: Don't overwrite unsaved updates when loading an association but preserve the order of the loaded records. Reapplied from before but now allows already-saved records to be refreshed. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [#4830 state:resolved] Signed-off-by: José Valim --- .../associations/association_collection.rb | 6 +++++- activerecord/test/cases/nested_attributes_test.rb | 21 +++++++++++++++++++++ activerecord/test/models/pirate.rb | 4 ++-- 3 files changed, 28 insertions(+), 3 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index d9903243ce..bd67516518 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -388,7 +388,11 @@ module ActiveRecord begin if !loaded? if @target.is_a?(Array) && @target.any? - @target = find_target + @target.find_all {|t| t.new_record? } + @target = find_target.map do |f| + i = @target.index(f) + t = @target.delete_at(i) if i + (t && t.changed?) ? t : f + end + @target else @target = find_target end diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb index 685b11cb03..65d6080ea5 100644 --- a/activerecord/test/cases/nested_attributes_test.rb +++ b/activerecord/test/cases/nested_attributes_test.rb @@ -466,6 +466,27 @@ module NestedAttributesOnACollectionAssociationTests assert_equal 'Grace OMalley', @child_1.reload.name end + def test_should_not_overwrite_unsaved_updates_when_loading_association + @pirate.reload + @pirate.send(association_setter, [{ :id => @child_1.id, :name => 'Grace OMalley' }]) + assert_equal 'Grace OMalley', @pirate.send(@association_name).send(:load_target).find { |r| r.id == @child_1.id }.name + end + + def test_should_preserve_order_when_not_overwriting_unsaved_updates + @pirate.reload + @pirate.send(association_setter, [{ :id => @child_1.id, :name => 'Grace OMalley' }]) + assert_equal @child_1.id, @pirate.send(@association_name).send(:load_target).first.id + end + + def test_should_refresh_saved_records_when_not_overwriting_unsaved_updates + @pirate.reload + record = @pirate.class.reflect_on_association(@association_name).klass.new(:name => 'Grace OMalley') + @pirate.send(@association_name) << record + record.save! + @pirate.send(@association_name).last.update_attributes!(:name => 'Polly') + assert_equal 'Polly', @pirate.send(@association_name).send(:load_target).last.name + end + def test_should_take_a_hash_with_composite_id_keys_and_assign_the_attributes_to_the_associated_models @child_1.stubs(:id).returns('ABC1X') @child_2.stubs(:id).returns('ABC2X') diff --git a/activerecord/test/models/pirate.rb b/activerecord/test/models/pirate.rb index f1dbe32c6e..d89c8cf381 100644 --- a/activerecord/test/models/pirate.rb +++ b/activerecord/test/models/pirate.rb @@ -1,7 +1,7 @@ class Pirate < ActiveRecord::Base belongs_to :parrot, :validate => true belongs_to :non_validated_parrot, :class_name => 'Parrot' - has_and_belongs_to_many :parrots, :validate => true + has_and_belongs_to_many :parrots, :validate => true, :order => 'parrots.id ASC' has_and_belongs_to_many :non_validated_parrots, :class_name => 'Parrot' has_and_belongs_to_many :parrots_with_method_callbacks, :class_name => "Parrot", :before_add => :log_before_add, @@ -21,7 +21,7 @@ class Pirate < ActiveRecord::Base has_one :ship has_one :update_only_ship, :class_name => 'Ship' has_one :non_validated_ship, :class_name => 'Ship' - has_many :birds + has_many :birds, :order => 'birds.id ASC' has_many :birds_with_method_callbacks, :class_name => "Bird", :before_add => :log_before_add, :after_add => :log_after_add, -- cgit v1.2.3 From e061212e86ef0342fad1211fd980fc4b2195fe69 Mon Sep 17 00:00:00 2001 From: Emilio Tagua Date: Mon, 14 Jun 2010 13:39:58 -0300 Subject: Refactor build_arel: move joins out and simplify havings. [#4860 state:resolved] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Valim --- .../lib/active_record/relation/query_methods.rb | 92 +++++++++++----------- 1 file changed, 46 insertions(+), 46 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 7a48a6596a..50e94134f5 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -116,45 +116,7 @@ module ActiveRecord def build_arel arel = table - joined_associations = [] - association_joins = [] - - joins = @joins_values.map {|j| j.respond_to?(:strip) ? j.strip : j}.uniq - - joins.each do |join| - association_joins << join if [Hash, Array, Symbol].include?(join.class) && !array_of_strings?(join) - end - - stashed_association_joins = joins.select {|j| j.is_a?(ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation)} - - non_association_joins = (joins - association_joins - stashed_association_joins).reject {|j| j.blank?} - custom_joins = custom_join_sql(*non_association_joins) - - join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(@klass, association_joins, custom_joins) - - join_dependency.graft(*stashed_association_joins) - - @implicit_readonly = true unless association_joins.empty? && stashed_association_joins.empty? - - to_join = [] - - join_dependency.join_associations.each do |association| - if (association_relation = association.relation).is_a?(Array) - to_join << [association_relation.first, association.join_class, association.association_join.first] - to_join << [association_relation.last, association.join_class, association.association_join.last] - else - to_join << [association_relation, association.join_class, association.association_join] - end - end - - to_join.each do |tj| - unless joined_associations.detect {|ja| ja[0] == tj[0] && ja[1] == tj[1] && ja[2] == tj[2] } - joined_associations << tj - arel = arel.join(tj[0], tj[1]).on(*tj[2]) - end - end - - arel = arel.join(custom_joins) + arel = build_joins(arel, @joins_values) if @joins_values.present? @where_values.uniq.each do |where| next if where.blank? @@ -168,9 +130,7 @@ module ActiveRecord end end - @having_values.uniq.each do |h| - arel = h.is_a?(String) ? arel.having(h) : arel.having(*h) - end + arel = arel.having(*@having_values.uniq.select{|h| h.present?}) arel = arel.take(@limit_value) if @limit_value.present? arel = arel.skip(@offset_value) if @offset_value.present? @@ -181,18 +141,16 @@ module ActiveRecord selects = @select_values.uniq - quoted_table_name = @klass.quoted_table_name - if selects.present? selects.each do |s| @implicit_readonly = false arel = arel.project(s) if s.present? end else - arel = arel.project(quoted_table_name + '.*') + arel = arel.project(@klass.quoted_table_name + '.*') end - arel = @from_value.present? ? arel.from(@from_value) : arel.from(quoted_table_name) + arel = @from_value.present? ? arel.from(@from_value) : arel.from(@klass.quoted_table_name) case @lock_value when TrueClass @@ -221,6 +179,48 @@ module ActiveRecord private + def build_joins(relation, joins) + joined_associations = [] + association_joins = [] + + joins = @joins_values.map {|j| j.respond_to?(:strip) ? j.strip : j}.uniq + + joins.each do |join| + association_joins << join if [Hash, Array, Symbol].include?(join.class) && !array_of_strings?(join) + end + + stashed_association_joins = joins.select {|j| j.is_a?(ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation)} + + non_association_joins = (joins - association_joins - stashed_association_joins).reject {|j| j.blank?} + custom_joins = custom_join_sql(*non_association_joins) + + join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(@klass, association_joins, custom_joins) + + join_dependency.graft(*stashed_association_joins) + + @implicit_readonly = true unless association_joins.empty? && stashed_association_joins.empty? + + to_join = [] + + join_dependency.join_associations.each do |association| + if (association_relation = association.relation).is_a?(Array) + to_join << [association_relation.first, association.join_class, association.association_join.first] + to_join << [association_relation.last, association.join_class, association.association_join.last] + else + to_join << [association_relation, association.join_class, association.association_join] + end + end + + to_join.each do |tj| + unless joined_associations.detect {|ja| ja[0] == tj[0] && ja[1] == tj[1] && ja[2] == tj[2] } + joined_associations << tj + relation = relation.join(tj[0], tj[1]).on(*tj[2]) + end + end + + relation.join(custom_joins) + end + def apply_modules(modules) values = Array.wrap(modules) @extensions += values if values.present? -- cgit v1.2.3 From 95a8f252c028c94b70cce4888bce42b7e9e30786 Mon Sep 17 00:00:00 2001 From: rohit Date: Wed, 16 Jun 2010 18:50:50 +0530 Subject: remove executable permission from files that don't need it. [#4802 state:resolved] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Valim --- activerecord/examples/performance.rb | 0 activerecord/lib/active_record/associations.rb | 0 activerecord/lib/active_record/base.rb | 0 activerecord/lib/active_record/connection_adapters/abstract_adapter.rb | 0 activerecord/test/cases/base_test.rb | 0 activerecord/test/cases/counter_cache_test.rb | 0 6 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 activerecord/examples/performance.rb mode change 100755 => 100644 activerecord/lib/active_record/associations.rb mode change 100755 => 100644 activerecord/lib/active_record/base.rb mode change 100755 => 100644 activerecord/lib/active_record/connection_adapters/abstract_adapter.rb mode change 100755 => 100644 activerecord/test/cases/base_test.rb mode change 100755 => 100644 activerecord/test/cases/counter_cache_test.rb (limited to 'activerecord') diff --git a/activerecord/examples/performance.rb b/activerecord/examples/performance.rb old mode 100755 new mode 100644 diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb old mode 100755 new mode 100644 diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb old mode 100755 new mode 100644 diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb old mode 100755 new mode 100644 diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb old mode 100755 new mode 100644 diff --git a/activerecord/test/cases/counter_cache_test.rb b/activerecord/test/cases/counter_cache_test.rb old mode 100755 new mode 100644 -- cgit v1.2.3 From 451594784552bd6955687d8ff617c484ec26946b Mon Sep 17 00:00:00 2001 From: Steve Abatangle Date: Fri, 11 Jun 2010 13:15:14 -0700 Subject: Fix problem with migrations template that can cause bogus code to be created MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Valim --- .../active_record/migration/templates/migration.rb | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/rails/generators/active_record/migration/templates/migration.rb b/activerecord/lib/rails/generators/active_record/migration/templates/migration.rb index bbb7c53d86..d6ab3257a0 100644 --- a/activerecord/lib/rails/generators/active_record/migration/templates/migration.rb +++ b/activerecord/lib/rails/generators/active_record/migration/templates/migration.rb @@ -1,11 +1,15 @@ class <%= migration_class_name %> < ActiveRecord::Migration def self.up<% attributes.each do |attribute| %> - <%= migration_action %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'add' %>, :<%= attribute.type %><% end -%> - <%- end %> + <%- if migration_action -%> + <%= migration_action %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'add' %>, :<%= attribute.type %><% end %> + <%- end -%> + <%- end -%> end def self.down<% attributes.reverse.each do |attribute| %> - <%= migration_action == 'add' ? 'remove' : 'add' %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'remove' %>, :<%= attribute.type %><% end -%> - <%- end %> + <%- if migration_action -%> + <%= migration_action == 'add' ? 'remove' : 'add' %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'remove' %>, :<%= attribute.type %><% end %> + <%- end -%> + <%- end -%> end end -- cgit v1.2.3