diff options
author | Jon Leighton <j@jonathanleighton.com> | 2012-11-09 11:27:46 +0000 |
---|---|---|
committer | Jon Leighton <j@jonathanleighton.com> | 2012-11-09 11:43:15 +0000 |
commit | aae4f357b5dae389b91129258f9d6d3043e7631e (patch) | |
tree | 653a11901502610f0d6c963e9db8b209b225a244 /activerecord/lib/active_record | |
parent | 6710f057f9033aec2ef62b961b9a2000a2d499e5 (diff) | |
download | rails-aae4f357b5dae389b91129258f9d6d3043e7631e.tar.gz rails-aae4f357b5dae389b91129258f9d6d3043e7631e.tar.bz2 rails-aae4f357b5dae389b91129258f9d6d3043e7631e.zip |
Nullify the relation at a more general level.
This allows us to avoid hacks like the "return 0 if owner.new_record?"
in #count (which this commit removes).
Also, the relevant foreign key may actually be present even on a new
owner record, in which case we *don't* want a null relation. This logic
is encapsulated in the #null_scope? method.
We also need to make sure that the CollectionProxy is not 'infected'
with the NullRelation module, or else the methods from there will
override the definitions in CollectionProxy, leading to incorrect
results. Hence the nullify: false option to CollectionAssociation#scope.
(This feels a bit nasty but I can't think of a better way.)
Diffstat (limited to 'activerecord/lib/active_record')
3 files changed, 14 insertions, 7 deletions
diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb index 54215cf88d..862ff201de 100644 --- a/activerecord/lib/active_record/associations/collection_association.rb +++ b/activerecord/lib/active_record/associations/collection_association.rb @@ -174,8 +174,6 @@ module ActiveRecord # association, it will be used for the query. Otherwise, construct options and pass them with # scope to the target class's +count+. def count(column_name = nil, count_options = {}) - return 0 if owner.new_record? - column_name, count_options = nil, column_name if column_name.is_a?(Hash) if options[:counter_sql] || options[:finder_sql] @@ -366,6 +364,16 @@ module ActiveRecord record end + def scope(opts = {}) + scope = super() + scope.none! if opts.fetch(:nullify, true) && null_scope? + scope + end + + def null_scope? + owner.new_record? && !foreign_key_present? + end + private def custom_counter_sql diff --git a/activerecord/lib/active_record/associations/collection_proxy.rb b/activerecord/lib/active_record/associations/collection_proxy.rb index 536e108f0e..50f9fca7c0 100644 --- a/activerecord/lib/active_record/associations/collection_proxy.rb +++ b/activerecord/lib/active_record/associations/collection_proxy.rb @@ -31,7 +31,7 @@ module ActiveRecord def initialize(association) #:nodoc: @association = association super association.klass, association.klass.arel_table - merge! association.scope + merge! association.scope(nullify: false) end def target @@ -835,9 +835,8 @@ module ActiveRecord # Returns a <tt>Relation</tt> object for the records in this association def scope association = @association - scope = @association.scope - scope.none! if @association.owner.new_record? - scope.extending! do + + @association.scope.extending! do define_method(:proxy_association) { association } end end diff --git a/activerecord/lib/active_record/null_relation.rb b/activerecord/lib/active_record/null_relation.rb index 4c1c91e3df..f8f7a6c976 100644 --- a/activerecord/lib/active_record/null_relation.rb +++ b/activerecord/lib/active_record/null_relation.rb @@ -46,7 +46,7 @@ module ActiveRecord {} end - def count + def count(*) 0 end |