From 57d750edf7c71e001ac314fa188aa1fc6292f8ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 30 Jun 2010 19:38:20 +0200 Subject: Make relation a private method. --- activerecord/lib/active_record/base.rb | 11 ++++++----- activerecord/lib/active_record/named_scope.rb | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index c8795e4496..c868ff3ae8 100644 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -896,11 +896,6 @@ module ActiveRecord #:nodoc: store_full_sti_class ? name : name.demodulize end - def relation - @relation ||= Relation.new(self, arel_table) - finder_needs_type_condition? ? @relation.where(type_condition) : @relation - end - def arel_table @arel_table ||= Arel::Table.new(table_name, :engine => arel_engine) end @@ -941,6 +936,12 @@ module ActiveRecord #:nodoc: end private + + def relation #:nodoc: + @relation ||= Relation.new(self, arel_table) + finder_needs_type_condition? ? @relation.where(type_condition) : @relation + end + # Finder methods must instantiate through this method to work with the # single-table inheritance model that makes it possible to create # objects of different types from the same table. diff --git a/activerecord/lib/active_record/named_scope.rb b/activerecord/lib/active_record/named_scope.rb index c010dac64e..849ec9c884 100644 --- a/activerecord/lib/active_record/named_scope.rb +++ b/activerecord/lib/active_record/named_scope.rb @@ -29,7 +29,7 @@ module ActiveRecord if options.present? scoped.apply_finder_options(options) else - current_scoped_methods ? unscoped.merge(current_scoped_methods) : unscoped.clone + current_scoped_methods ? relation.merge(current_scoped_methods) : relation.clone end end -- cgit v1.2.3 From f3fedd7f84c25d1d99a70af1e21e20abb48f100f Mon Sep 17 00:00:00 2001 From: James Le Cuirot Date: Wed, 30 Jun 2010 23:22:13 +0100 Subject: Don't remove scheduled destroys when loading an association. [#4642 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/associations/association_collection.rb | 7 ++++++- activerecord/test/cases/nested_attributes_test.rb | 6 ++++++ 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index ddf4ce4058..a4e08c7d41 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -393,7 +393,12 @@ module ActiveRecord @target = find_target.map do |f| i = @target.index(f) t = @target.delete_at(i) if i - (t && t.changed?) ? t : f + if t && t.changed? + t + else + f.mark_for_destruction if t && t.marked_for_destruction? + f + end end + @target else @target = find_target diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb index 3c797076e0..62237f955b 100644 --- a/activerecord/test/cases/nested_attributes_test.rb +++ b/activerecord/test/cases/nested_attributes_test.rb @@ -489,6 +489,12 @@ module NestedAttributesOnACollectionAssociationTests assert_equal 'Polly', @pirate.send(@association_name).send(:load_target).last.name end + def test_should_not_remove_scheduled_destroys_when_loading_association + @pirate.reload + @pirate.send(association_setter, [{ :id => @child_1.id, :_destroy => '1' }]) + assert @pirate.send(@association_name).send(:load_target).find { |r| r.id == @child_1.id }.marked_for_destruction? + 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') -- cgit v1.2.3 From 53b34e84762b7f2d6b641f99dadbb1eab42907ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Thu, 1 Jul 2010 17:07:48 +0200 Subject: Avoid calls to Rails::Application since this is not the official API. Your application should *always* reference your application const (as Blog::Application) and Rails.application should be used just internally. --- activerecord/lib/active_record/railties/databases.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index 7882f05d07..5024787c3c 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -1,7 +1,7 @@ namespace :db do task :load_config => :rails_env do require 'active_record' - ActiveRecord::Base.configurations = Rails::Application.config.database_configuration + ActiveRecord::Base.configurations = Rails.application.config.database_configuration end namespace :create do -- cgit v1.2.3 From a5dda97602f2188a13cbcab5c7e9a5ba84ba876b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 5 Jul 2010 12:50:08 +0200 Subject: Define a convention for descendants and subclasses. The former should be symmetric with ancestors and include all children. However, it should not include self since ancestors + descendants should not have duplicated. The latter is symmetric to superclass in the sense it only includes direct children. By adopting a convention, we expect to have less conflict with other frameworks, as Datamapper. For this moment, to ensure ActiveModel::Validations can be used with Datamapper, we should always call ActiveSupport::DescendantsTracker.descendants(self) internally instead of self.descendants avoiding conflicts. --- activerecord/lib/active_record/observer.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/observer.rb b/activerecord/lib/active_record/observer.rb index 5f80bd86df..d2ed643f35 100644 --- a/activerecord/lib/active_record/observer.rb +++ b/activerecord/lib/active_record/observer.rb @@ -94,7 +94,7 @@ module ActiveRecord def initialize super - observed_subclasses.each { |klass| add_observer!(klass) } + observed_descendants.each { |klass| add_observer!(klass) } end def self.method_added(method) @@ -108,8 +108,8 @@ module ActiveRecord protected - def observed_subclasses - observed_classes.sum([]) { |klass| klass.send(:descendants) } + def observed_descendants + observed_classes.sum([]) { |klass| klass.descendants } end def observe_callbacks? -- cgit v1.2.3 From 92ff71bb14b1b589a3d5c04d120e4b9210b243b1 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Tue, 6 Jul 2010 17:29:19 +0200 Subject: documents automatic management of join models in hmt associations, in particular the gotcha that deletion is direct --- activerecord/lib/active_record/associations.rb | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 4caa434fc0..eebbd17f43 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -768,15 +768,20 @@ module ActiveRecord # Objects will be in addition destroyed if they're associated with :dependent => :destroy, # and deleted if they're associated with :dependent => :delete_all. # [collection=objects] - # Replaces the collections content by deleting and adding objects as appropriate. + # Replaces the collections content by deleting and adding objects as appropriate. If the :through + # option is true callbacks in the join models are triggered except destroy callbacks, since deletion is + # direct. # [collection_singular_ids] # Returns an array of the associated objects' ids # [collection_singular_ids=ids] - # Replace the collection with the objects identified by the primary keys in +ids+ + # Replace the collection with the objects identified by the primary keys in +ids+. This + # method loads the models and calls collection=. See above. # [collection.clear] # Removes every object from the collection. This destroys the associated objects if they # are associated with :dependent => :destroy, deletes them directly from the # database if :dependent => :delete_all, otherwise sets their foreign keys to +NULL+. + # If the :through option is true no destroy callbacks are invoked on the join models. + # Join models are directly deleted. # [collection.empty?] # Returns +true+ if there are no associated objects. # [collection.size] @@ -869,9 +874,11 @@ module ActiveRecord # [:as] # Specifies a polymorphic interface (See belongs_to). # [:through] - # Specifies a Join Model through which to perform the query. Options for :class_name and :foreign_key + # Specifies a join model through which to perform the query. Options for :class_name and :foreign_key # are ignored, as the association uses the source reflection. You can only use a :through query through a belongs_to - # has_one or has_many association on the join model. + # has_one or has_many association on the join model. The collection of join models can be managed via the collection + # API. For example, new join models are created for newly associated objects, and if some are gone their rows are deleted (directly, + # no destroy callbacks are triggered). # [:source] # Specifies the source association name used by has_many :through queries. Only use it if the name cannot be # inferred from the association. has_many :subscribers, :through => :subscriptions will look for either :subscribers or -- cgit v1.2.3