From aec5ef243a0c85a9e3bafa89ce873d3837a6ce59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Wed, 13 Oct 2010 15:59:57 -0300 Subject: Remove doc for debugging callbacks. Methods don't exist in Rails master --- activerecord/lib/active_record/callbacks.rb | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/callbacks.rb b/activerecord/lib/active_record/callbacks.rb index 49671a1042..47428cfd0f 100644 --- a/activerecord/lib/active_record/callbacks.rb +++ b/activerecord/lib/active_record/callbacks.rb @@ -218,16 +218,6 @@ module ActiveRecord # needs to be aware of it because an ordinary +save+ will raise such exception # instead of quietly returning +false+. # - # == Debugging callbacks - # - # To list the methods and procs registered with a particular callback, append _callback_chain to - # the callback name that you wish to list and send that to your class from the Rails console: - # - # >> Topic.after_save_callback_chain - # => [#, kind:after_save, identifiernil, - # options{}] - # module Callbacks extend ActiveSupport::Concern -- cgit v1.2.3 From 9ebe582830fd0386e09a917d81eb6cff494cd590 Mon Sep 17 00:00:00 2001 From: Michael Koziarski Date: Fri, 15 Oct 2010 10:25:49 +1300 Subject: Revert 0c0b0aa0f223523331afdc157fb3992a121bf497 which introduced a security vulnerability. This addresses CVE-2010-3933 Conflicts: activerecord/lib/active_record/nested_attributes.rb --- .../lib/active_record/nested_attributes.rb | 17 +++++++------- activerecord/test/cases/nested_attributes_test.rb | 26 ++++++++++------------ 2 files changed, 20 insertions(+), 23 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/nested_attributes.rb b/activerecord/lib/active_record/nested_attributes.rb index bdd940f3ee..aca91c907d 100644 --- a/activerecord/lib/active_record/nested_attributes.rb +++ b/activerecord/lib/active_record/nested_attributes.rb @@ -324,9 +324,7 @@ module ActiveRecord assign_to_or_mark_for_destruction(record, attributes, options[:allow_destroy]) unless call_reject_if(association_name, attributes) elsif attributes['id'] - existing_record = self.class.reflect_on_association(association_name).klass.find(attributes['id']) - assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy]) - self.send(association_name.to_s+'=', existing_record) + raise_nested_attributes_record_not_found(association_name, attributes['id']) elsif !reject_new_record?(association_name, attributes) method = "build_#{association_name}" @@ -402,15 +400,12 @@ module ActiveRecord association.build(attributes.except(*UNASSIGNABLE_KEYS)) end - elsif existing_records.count == 0 #Existing record but not yet associated - existing_record = self.class.reflect_on_association(association_name).klass.find(attributes['id']) - association.send(:add_record_to_target_with_callbacks, existing_record) if !association.loaded? && !call_reject_if(association_name, attributes) - assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy]) - elsif existing_record = existing_records.detect { |record| record.id.to_s == attributes['id'].to_s } association.send(:add_record_to_target_with_callbacks, existing_record) if !association.loaded? && !call_reject_if(association_name, attributes) assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy]) + else + raise_nested_attributes_record_not_found(association_name, attributes['id']) end end end @@ -430,7 +425,7 @@ module ActiveRecord ConnectionAdapters::Column.value_to_boolean(hash['_destroy']) end - # Determines if a new record should be built by checking for + # Determines if a new record should be build by checking for # has_destroy_flag? or if a :reject_if proc exists for this # association and evaluates to +true+. def reject_new_record?(association_name, attributes) @@ -446,5 +441,9 @@ module ActiveRecord end end + def raise_nested_attributes_record_not_found(association_name, record_id) + reflection = self.class.reflect_on_association(association_name) + raise RecordNotFound, "Couldn't find #{reflection.klass.name} with ID=#{record_id} for #{self.class.name} with ID=#{id}" + end end end diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb index 8382ca048b..60f89da95e 100644 --- a/activerecord/test/cases/nested_attributes_test.rb +++ b/activerecord/test/cases/nested_attributes_test.rb @@ -203,6 +203,12 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase assert_equal 'Davy Jones Gold Dagger', @pirate.ship.name end + def test_should_raise_RecordNotFound_if_an_id_is_given_but_doesnt_return_a_record + assert_raise_with_message ActiveRecord::RecordNotFound, "Couldn't find Ship with ID=1234567890 for Pirate with ID=#{@pirate.id}" do + @pirate.ship_attributes = { :id => 1234567890 } + end + end + def test_should_take_a_hash_with_string_keys_and_update_the_associated_model @pirate.reload.ship_attributes = { 'id' => @ship.id, 'name' => 'Davy Jones Gold Dagger' } @@ -382,13 +388,10 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase assert_equal 'Arr', @ship.pirate.catchphrase end - def test_should_associate_with_record_if_parent_record_is_not_saved - @ship.destroy - @pirate = Pirate.create(:catchphrase => 'Arr') - @ship = Ship.new(:name => 'Nights Dirty Lightning', :pirate_attributes => { :id => @pirate.id, :catchphrase => @pirate.catchphrase}) - - assert_equal @ship.name, 'Nights Dirty Lightning' - assert_equal @pirate, @ship.pirate + def test_should_raise_RecordNotFound_if_an_id_is_given_but_doesnt_return_a_record + assert_raise_with_message ActiveRecord::RecordNotFound, "Couldn't find Pirate with ID=1234567890 for Ship with ID=#{@ship.id}" do + @ship.pirate_attributes = { :id => 1234567890 } + end end def test_should_take_a_hash_with_string_keys_and_update_the_associated_model @@ -518,11 +521,6 @@ module NestedAttributesOnACollectionAssociationTests assert_equal ['Grace OMalley', 'Privateers Greed'], [@child_1.reload.name, @child_2.reload.name] end - def test_should_assign_existing_children_if_parent_is_new - @pirate = Pirate.new({:catchphrase => "Don' botharr talkin' like one, savvy?"}.merge(@alternate_params)) - assert_equal ['Grace OMalley', 'Privateers Greed'], [@pirate.send(@association_name)[0].name, @pirate.send(@association_name)[1].name] - end - def test_should_also_work_with_a_HashWithIndifferentAccess @pirate.send(association_setter, HashWithIndifferentAccess.new('foo' => HashWithIndifferentAccess.new(:id => @child_1.id, :name => 'Grace OMalley'))) @pirate.save @@ -586,8 +584,8 @@ module NestedAttributesOnACollectionAssociationTests assert_equal ['Grace OMalley', 'Privateers Greed'], [@child_1.name, @child_2.name] end - def test_should_not_raise_RecordNotFound_if_an_id_is_given_but_doesnt_return_a_record - assert_nothing_raised ActiveRecord::RecordNotFound do + def test_should_raise_RecordNotFound_if_an_id_is_given_but_doesnt_return_a_record + assert_raise_with_message ActiveRecord::RecordNotFound, "Couldn't find #{@child_1.class.name} with ID=1234567890 for Pirate with ID=#{@pirate.id}" do @pirate.attributes = { association_getter => [{ :id => 1234567890 }] } end end -- cgit v1.2.3 From 69789c3b29b9ee0b89928f4211060f470d0e0c44 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Thu, 14 Oct 2010 21:27:40 -0700 Subject: #transaction on the instance level should take options as well --- activerecord/lib/active_record/transactions.rb | 4 ++-- activerecord/test/cases/transactions_test.rb | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb index a7709b9489..ab737f0f88 100644 --- a/activerecord/lib/active_record/transactions.rb +++ b/activerecord/lib/active_record/transactions.rb @@ -224,8 +224,8 @@ module ActiveRecord end # See ActiveRecord::Transactions::ClassMethods for detailed documentation. - def transaction(&block) - self.class.transaction(&block) + def transaction(options = {}, &block) + self.class.transaction(options, &block) end def destroy #:nodoc: diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb index 8385286fd0..44af54b143 100644 --- a/activerecord/test/cases/transactions_test.rb +++ b/activerecord/test/cases/transactions_test.rb @@ -263,6 +263,27 @@ class TransactionTest < ActiveRecord::TestCase assert !@second.reload.approved? end if Topic.connection.supports_savepoints? + def test_force_savepoint_on_instance + @first.transaction do + @first.approved = true + @second.approved = false + @first.save! + @second.save! + + begin + @second.transaction :requires_new => true do + @first.happy = false + @first.save! + raise + end + rescue + end + end + + assert @first.reload.approved? + assert !@second.reload.approved? + end if Topic.connection.supports_savepoints? + def test_no_savepoint_in_nested_transaction_without_force Topic.transaction do @first.approved = true -- cgit v1.2.3 From 21ff8849bb7d4f1c277d767c7704eb63d8920cc7 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Fri, 15 Oct 2010 16:31:00 +0200 Subject: in regexps, the dot in a character class is not a metacharacter --- .../lib/active_record/connection_adapters/postgresql_adapter.rb | 4 ++-- activerecord/lib/active_record/relation.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index dce9e99d27..a7503ccdc9 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -465,8 +465,8 @@ module ActiveRecord # (2) $12.345.678,12 case data when /^-?\D+[\d,]+\.\d{2}$/ # (1) - data.gsub!(/[^-\d\.]/, '') - when /^-?\D+[\d\.]+,\d{2}$/ # (2) + data.gsub!(/[^-\d.]/, '') + when /^-?\D+[\d.]+,\d{2}$/ # (2) data.gsub!(/[^-\d,]/, '').sub!(/,/, '.') end end diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 04ba5b291e..f129b54f9a 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -379,7 +379,7 @@ module ActiveRecord return [] if string.blank? # always convert table names to downcase as in Oracle quoted table names are in uppercase # ignore raw_sql_ that is used by Oracle adapter as alias for limit/offset subqueries - string.scan(/([a-zA-Z_][\.\w]+).?\./).flatten.map{ |s| s.downcase }.uniq - ['raw_sql_'] + string.scan(/([a-zA-Z_][.\w]+).?\./).flatten.map{ |s| s.downcase }.uniq - ['raw_sql_'] end end -- cgit v1.2.3 From 552636c65240c7104054d0a4ef63cde9622d838d Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 15 Oct 2010 15:46:13 -0700 Subject: testing that symbols work as sql literals --- activerecord/test/cases/base_test.rb | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'activerecord') diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index 16fd9a7465..d9c7aa16c1 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -48,6 +48,11 @@ class Boolean < ActiveRecord::Base; end class BasicsTest < ActiveRecord::TestCase fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, 'warehouse-things', :authors, :categorizations, :categories, :posts + def test_select_symbol + topic_ids = Topic.select(:id).map(&:id).sort + assert_equal Topic.find(:all).map(&:id), topic_ids + end + def test_table_exists assert !NonExistentTable.table_exists? assert Topic.table_exists? -- cgit v1.2.3 From dc76e3c38f8c58c492fa69ccaca43a9499f95588 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 15 Oct 2010 15:47:09 -0700 Subject: should sort these ids before asserting they are equal! --- activerecord/test/cases/base_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index d9c7aa16c1..8acee9ac71 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -50,7 +50,7 @@ class BasicsTest < ActiveRecord::TestCase def test_select_symbol topic_ids = Topic.select(:id).map(&:id).sort - assert_equal Topic.find(:all).map(&:id), topic_ids + assert_equal Topic.find(:all).map(&:id).sort, topic_ids end def test_table_exists -- cgit v1.2.3 From ea14396c455b0816e87abe424275290fc4b09b32 Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Sat, 16 Oct 2010 23:12:19 -0400 Subject: replace if ! with unless Signed-off-by: Santiago Pastorino --- .../connection_adapters/abstract/connection_specification.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb index ec7035e540..3716937689 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb @@ -72,7 +72,7 @@ module ActiveRecord end adapter_method = "#{spec[:adapter]}_connection" - if !respond_to?(adapter_method) + unless respond_to?(adapter_method) raise AdapterNotFound, "database configuration specifies nonexistent #{spec[:adapter]} adapter" end -- cgit v1.2.3 From f527f9097b20d4c6178bcdd70a2be11a129bc866 Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Sat, 16 Oct 2010 23:17:14 -0400 Subject: no need to check for nil Signed-off-by: Santiago Pastorino --- activerecord/lib/active_record/attribute_methods/read.rb | 2 +- activerecord/lib/active_record/schema_dumper.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/attribute_methods/read.rb b/activerecord/lib/active_record/attribute_methods/read.rb index 01699746d8..a487bcf78b 100644 --- a/activerecord/lib/active_record/attribute_methods/read.rb +++ b/activerecord/lib/active_record/attribute_methods/read.rb @@ -85,7 +85,7 @@ module ActiveRecord def _read_attribute(attr_name) attr_name = attr_name.to_s attr_name = self.class.primary_key if attr_name == 'id' - if !(value = @attributes[attr_name]).nil? + if (value = @attributes[attr_name]) if column = column_for_attribute(attr_name) if unserializable_attribute?(attr_name, column) unserialize_attribute(attr_name) diff --git a/activerecord/lib/active_record/schema_dumper.rb b/activerecord/lib/active_record/schema_dumper.rb index f5331bb8a9..e30b481fe1 100644 --- a/activerecord/lib/active_record/schema_dumper.rb +++ b/activerecord/lib/active_record/schema_dumper.rb @@ -114,9 +114,9 @@ HEADER column.type.to_s end spec[:limit] = column.limit.inspect if column.limit != @types[column.type][:limit] && spec[:type] != 'decimal' - spec[:precision] = column.precision.inspect if !column.precision.nil? - spec[:scale] = column.scale.inspect if !column.scale.nil? - spec[:null] = 'false' if !column.null + spec[:precision] = column.precision.inspect if column.precision + spec[:scale] = column.scale.inspect if column.scale + spec[:null] = 'false' unless column.null spec[:default] = default_string(column.default) if column.has_default? (spec.keys - [:name, :type]).each{ |k| spec[k].insert(0, "#{k.inspect} => ")} spec -- cgit v1.2.3 From 67df21f8954073ddc7f3409ec618c953f97cb412 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Sun, 17 Oct 2010 12:34:51 -0200 Subject: No need for parenthesis here --- activerecord/lib/active_record/attribute_methods/read.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/attribute_methods/read.rb b/activerecord/lib/active_record/attribute_methods/read.rb index a487bcf78b..ad5a3e7562 100644 --- a/activerecord/lib/active_record/attribute_methods/read.rb +++ b/activerecord/lib/active_record/attribute_methods/read.rb @@ -85,7 +85,7 @@ module ActiveRecord def _read_attribute(attr_name) attr_name = attr_name.to_s attr_name = self.class.primary_key if attr_name == 'id' - if (value = @attributes[attr_name]) + if value = @attributes[attr_name] if column = column_for_attribute(attr_name) if unserializable_attribute?(attr_name, column) unserialize_attribute(attr_name) -- cgit v1.2.3 From 460c4efd711cc1fbcd87b4779fc682c149af36e9 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 18 Oct 2010 12:24:41 -0200 Subject: Merge CHANGELOGs from 3-0-stable --- activerecord/CHANGELOG | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'activerecord') diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index 8f283e1117..75657cb6ee 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -15,6 +15,10 @@ [Aaron Patterson] +*Rails 3.0.1 (October 15, 2010)* + +* Introduce a fix for CVE-2010-3993 + *Rails 3.0.0 (August 29, 2010)* * Changed update_attribute to not run callbacks and update the record directly in the database [Neeraj Singh] -- cgit v1.2.3 From 4120e95dce3ccea43ef9fb4bfeb513114f71ba9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=81omnicki?= Date: Tue, 19 Oct 2010 08:18:19 +0800 Subject: Use ALTER INDEX syntax to rename an index --- .../lib/active_record/connection_adapters/postgresql_adapter.rb | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index a7503ccdc9..5949985e4d 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -849,6 +849,10 @@ module ActiveRecord execute "DROP INDEX #{quote_table_name(index_name)}" end + def rename_index(table_name, old_name, new_name) + execute "ALTER INDEX #{quote_column_name(old_name)} RENAME TO #{quote_table_name(new_name)}" + end + def index_name_length 63 end -- cgit v1.2.3 From 1856e975c380920b5d4a67e903ed7c96624fd27b Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 18 Oct 2010 17:57:19 -0700 Subject: "instance_methods" includes public and protected --- activerecord/lib/active_record/attribute_methods.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb index 7297af9f79..67f70c434e 100644 --- a/activerecord/lib/active_record/attribute_methods.rb +++ b/activerecord/lib/active_record/attribute_methods.rb @@ -18,7 +18,7 @@ module ActiveRecord # method is defined by Active Record though. def instance_method_already_implemented?(method_name) method_name = method_name.to_s - @_defined_class_methods ||= ancestors.first(ancestors.index(ActiveRecord::Base)).sum([]) { |m| m.public_instance_methods(false) | m.private_instance_methods(false) | m.protected_instance_methods(false) }.map {|m| m.to_s }.to_set + @_defined_class_methods ||= ancestors.first(ancestors.index(ActiveRecord::Base)).sum([]) { |m| m.instance_methods(false) | m.private_instance_methods(false) }.map {|m| m.to_s }.to_set @@_defined_activerecord_methods ||= defined_activerecord_methods raise DangerousAttributeError, "#{method_name} is defined by ActiveRecord" if @@_defined_activerecord_methods.include?(method_name) @_defined_class_methods.include?(method_name) -- cgit v1.2.3