1.9.2 / Polymorphic has_many / calling .size

Group has_many :topics, :as => :discussable (via a module) Topic belongs_to :discussable, :polymorphic => true named_scope :unhidden, { :conditions => [‘hidden = ?’, false] } Under rails 1.9.2 without the named_scope this works properly:

reload! ; Group.find(56).topics.size Reloading… …snip show tables etc… Group Load (12.8ms) SELECT * FROM groups WHERE (groups.id = 56) Topic Columns (13.6ms) SHOW FIELDS FROM topics SQL (81.7ms) SELECT count() AS count_all FROM topics WHERE (topics.discussable_id = 56 AND topics.discussable_type = ‘Group’) However with the named scope in there: reload! ; Group.find(56).topics.unhidden.size Group Load (14.3ms) SELECT * FROM groups WHERE (groups.id = 56) Topic Load (40.1ms) SELECT * FROM topics WHERE (topics.discussable_id = 56 AND topics.discussable_type = ‘Group’) Topic Columns (13.5ms) SHOW FIELDS FROM topics SQL (11.8ms) SELECT count() AS count_all FROM topics WHERE (((hidden = 0) AND (topics.discussable_id = 56 AND topics.discussable_type = ‘Group’)) AND (topics.discussable_id = 56 AND topics.discussable_type = ‘Group’))

So the problem is under the seond one, it selects all the topics and then does select count(*).

Under rails 1.9.1p243 this worked correctly in both cases.

Any ideas?

Stephen wrote in post #955565:

Group has_many :topics, :as => :discussable (via a module)

Topic   belongs_to :discussable, :polymorphic => true   named_scope :unhidden, { :conditions => ['hidden = ?', false] }

Under rails 1.9.2

[...]

There is no such version. Do you mean Ruby 1.9.2? And with what version of Rails?

Best,

Yes yes, thats what I meant =) Ruby 1.9.2 and Rails 2.3.9 it causes a double query. Under Ruby 1.9.1p243 and Rails 2.3.9 it correctly only does the count query.

I found a bug for it in Lighthouse although no solutions..... https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/5410-multiple-database-queries-when-chaining-named-scopes-with-rails-238-and-ruby-192#ticket-5410-2

Here’s the problem.

1.9.2 defines a new way of handling method_missing/responds_to responds_to_missing?

This seems to get called automatically and triggers the method_missing in association_collection.

AssociationCollection calls “super” in method and passes it to AssociationProxy which also triggers method_missing…

The first line of method_missing in AssociationProxy is load_target which causes the extra DB load…

This is a workaround:

— a/association_collection.rb 2010-10-20 13:22:58.629947001 -0400 +++ b/association_collection.rb 2010-10-20 13:22:54.509947004 -0400 @@ -390,7 +390,7 @@ if block_given? super { |*block_args| yield(*block_args) } else

  •          super
    
  •          super unless method.to_s == "respond_to_missing?"
           end
         elsif @reflection.klass.scopes.include?(method)
           @reflection.klass.scopes[method].call(self, *args)