2010/7/31 Nicolás Sanguinetti <h...@nicolassanguinetti.info>: > On Sat, Jul 31, 2010 at 6:08 PM, DBA <diogo.borges.alme...@gmail.com> wrote: >> I've implemented the following scope in a rails 3 application: >> >> scope :popular, lambda { |l = 5| order('views desc').limit(l) } >> >> However, it seems that when you attempt to count its records directly >> it doesn't apply the scope filters. >> >> For example: >> >> Post.popular.size #=> 20 >> >> Checking the log, it executes the following query: >> >> SQL (0.4ms) SELECT COUNT(*) AS count_id FROM `posts` LIMIT 5 >> >> Now if I execute >> >> Post.popular.all.size #=> 5 >> >> And the correct query is executed: >> >> Post Load (1.5ms) SELECT `posts`.* FROM `posts` ORDER BY views >> desc LIMIT 5 >> >> Anyone else experienced this kind of behavior? If so, any idea if this >> is the expected behavior or am I facing a bug? > > This is expected. The three ways to get the size of an ActiveRecord > collection are: > > .count #=> this always triggers a SELECT COUNT(*) on the database > .size #=> if the collection has been loaded, defers to > Enumerable#size, else does the SELECT COUNT(*) > .length #=> always loads the collection and then defers to > Enumerable#size (I think it's length, but I don't think I ever used it > :P) > > So, since Post.popular doesn't trigger the query and load the objects, > calling size will do a count query. > > This is, apparently, a good use case for Post.popular.length :)
Or a good reason to change the code to do: SELECT COUNT(*) FROM (SELECT `posts`.* FROM `posts` ORDER BY views desc LIMIT 5) AS some_alias which is Sequel's behavior. Jeremy -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-c...@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.