aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarl Lerche <carllerche@mac.com>2010-04-02 22:33:57 -0700
committerCarl Lerche <carllerche@mac.com>2010-04-02 22:33:57 -0700
commit13004d4f849682772060371273fda3312dd3b884 (patch)
tree914af96637598ba61fb458c5837eb8894a65af29
parent386b7bfd9d78a6d8c8bc7cc4a310df806ad0ba57 (diff)
downloadrails-13004d4f849682772060371273fda3312dd3b884.tar.gz
rails-13004d4f849682772060371273fda3312dd3b884.tar.bz2
rails-13004d4f849682772060371273fda3312dd3b884.zip
Make the query built by has_many ...., :dependent => :____ lazy since all the information is not really available yet.
-rwxr-xr-xactiverecord/lib/active_record/associations.rb72
-rw-r--r--activerecord/lib/active_record/reflection.rb10
2 files changed, 32 insertions, 50 deletions
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index 40022a614a..7d628005dd 100755
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -1495,13 +1495,6 @@ module ActiveRecord
# finder conditions.
def configure_dependency_for_has_many(reflection)
if reflection.options.include?(:dependent)
- # Add polymorphic type if the :as option is present
- dependent_conditions = []
- dependent_conditions << "#{reflection.primary_key_name} = \#{record.#{reflection.name}.send(:owner_quoted_id)}"
- dependent_conditions << "#{reflection.options[:as]}_type = '#{base_class.name}'" if reflection.options[:as]
- dependent_conditions << sanitize_sql(reflection.options[:conditions], reflection.table_name) if reflection.options[:conditions]
- dependent_conditions = dependent_conditions.collect {|where| "(#{where})" }.join(" AND ")
- dependent_conditions = dependent_conditions.gsub('@', '\@')
case reflection.options[:dependent]
when :destroy
method_name = "has_many_dependent_destroy_for_#{reflection.name}".to_sym
@@ -1510,51 +1503,30 @@ module ActiveRecord
end
before_destroy method_name
when :delete_all
- # before_destroy do |record|
- # self.class.send(:delete_all_has_many_dependencies,
- # record,
- # "posts",
- # Post,
- # %@...@) # this is a string literal like %(...)
- # end
- # end
- module_eval <<-CALLBACK
- before_destroy do |record|
- self.class.send(:delete_all_has_many_dependencies,
- record,
- "#{reflection.name}",
- #{reflection.class_name},
- %@#{dependent_conditions}@)
- end
- CALLBACK
+ before_destroy do |record|
+ self.class.send(:delete_all_has_many_dependencies,
+ record,
+ reflection.name,
+ reflection.klass,
+ reflection.dependent_conditions(record, self.class))
+ end
when :nullify
- # before_destroy do |record|
- # self.class.send(:nullify_has_many_dependencies,
- # record,
- # "posts",
- # Post,
- # "user_id",
- # %@...@) # this is a string literal like %(...)
- # end
- # end
- module_eval <<-CALLBACK
- before_destroy do |record|
- self.class.send(:nullify_has_many_dependencies,
- record,
- "#{reflection.name}",
- #{reflection.class_name},
- "#{reflection.primary_key_name}",
- %@#{dependent_conditions}@)
- end
- CALLBACK
- when :restrict
- method_name = "has_many_dependent_restrict_for_#{reflection.name}".to_sym
- define_method(method_name) do
- unless send(reflection.name).empty?
- raise DeleteRestrictionError.new(reflection)
- end
+ before_destroy do |record|
+ self.class.send(:nullify_has_many_dependencies,
+ record,
+ reflection.name,
+ reflection.klass,
+ reflection.primary_key_name,
+ reflection.dependent_conditions(record, self.class))
+ end
+ when :restrict
+ method_name = "has_many_dependent_restrict_for_#{reflection.name}".to_sym
+ define_method(method_name) do
+ unless send(reflection.name).empty?
+ raise DeleteRestrictionError.new(reflection)
end
- before_destroy method_name
+ end
+ before_destroy method_name
else
raise ArgumentError, "The :dependent option expects either :destroy, :delete_all, :nullify or :restrict (#{reflection.options[:dependent].inspect})"
end
diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb
index 5e8fc104cb..2a3f3f8713 100644
--- a/activerecord/lib/active_record/reflection.rb
+++ b/activerecord/lib/active_record/reflection.rb
@@ -277,6 +277,16 @@ module ActiveRecord
!options[:validate].nil? ? options[:validate] : (options[:autosave] == true || macro == :has_many)
end
+ def dependent_conditions(record, base_class)
+ dependent_conditions = []
+ dependent_conditions << "#{primary_key_name} = #{record.send(name).send(:owner_quoted_id)}"
+ dependent_conditions << "#{options[:as]}_type = '#{base_class.name}'" if options[:as]
+ dependent_conditions << klass.send(:sanitize_sql, options[:conditions]) if options[:conditions]
+ dependent_conditions = dependent_conditions.collect {|where| "(#{where})" }.join(" AND ")
+ dependent_conditions = dependent_conditions.gsub('@', '\@')
+ dependent_conditions
+ end
+
private
def derive_class_name
class_name = name.to_s.camelize