Re: [Rails-core] CollectionAssociation shadows Enumerable#count

80 views
Skip to first unread message

Rafael Mendonça França

unread,
Jan 31, 2013, 5:45:59 PM1/31/13
to rubyonra...@googlegroups.com

I'm not sure but this can add some confusion.

I remember we removed the possibility to pass a block to sum and count to avoid confusion of users that may think the block will change the database query.

On Jan 31, 2013 8:12 PM, "Christian Romney" <xml...@gmail.com> wrote:
Hi all,

I realize this behavior is by design, and in some respects the right thing to do. It also pre-dates the addition of Enumerable#count. I'm wondering, however, if it's possible/desirable to allow the caller to access the Enumerable versions under certain conditions. I originally wrote the up as an issue, but was informed this would be the better venue. I'm linking to the original issue on Github because the syntax highlighting is nice. 


TIA for taking the time to think this over.

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-co...@googlegroups.com.
To post to this group, send email to rubyonra...@googlegroups.com.
Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Matt Jones

unread,
Feb 1, 2013, 1:12:36 PM2/1/13
to rubyonra...@googlegroups.com

On Jan 31, 2013, at 1:35 PM, Christian Romney wrote:

> Hi all,
>
> I realize this behavior is by design, and in some respects the right thing to do. It also pre-dates the addition of Enumerable#count. I'm wondering, however, if it's possible/desirable to allow the caller to access the Enumerable versions under certain conditions. I originally wrote the up as an issue, but was informed this would be the better venue. I'm linking to the original issue on Github because the syntax highlighting is nice.
>
> https://github.com/rails/rails/issues/9132

In the example in the issue, wouldn't this work nearly as well:

def incomplete_submissions
submissions.to_a.count(&:incomplete?)
end

In short, if you want the Enumerable behavior, just ask for it...

--Matt Jones

Matt Wean

unread,
May 15, 2017, 6:18:07 PM5/15/17
to Ruby on Rails: Core

I just ran into this issue, and I would actually call it a bug since it causes very unexpected behavior:

> User.count { |user| user.not_a_method! }
=> 10

So the block isn't even being evaluated. I'm fine if we don't delegate to Enumerable, but I would expect #count to at least raise an error if a block is given so people don't accidentally try to count with a predicate and get the wrong answer.

Miles Georgi

unread,
May 15, 2017, 6:33:26 PM5/15/17
to Ruby on Rails: Core
Agreed :+1:

Omar Bohsali

unread,
May 15, 2017, 7:32:44 PM5/15/17
to Ruby on Rails: Core
Also agree with Matt Wean and Miles on this one.

Jason Fleetwood-Boldt

unread,
May 16, 2017, 7:50:35 AM5/16/17
to rubyonra...@googlegroups.com


I've never passed an argument to a .count method in my 9 years of writing ruby code. I would never think to do such a thing and such a thing would never occur to me (passing anything — block or otherwise — to a count method)

Here's the efficiency problem with your code & proposal:

submissions.to_a.count(&:incomplete?)

This code inherently encourages a code smell design— the objects must first be retrieved from the database before they are evaluated for incomplete?. This is slow, and won't scale.

Instead, you would do well to define incomplete as a scope and not a method and instead rewrite it like so:

submissions.incomplete.count

That will correctly use Active-Relation (A-Rel) objects to create the right SQL, something like

SELECT count(*) FROM submissions where incomplete = 1

Otherwise, you fetch all submissions from the database and then call incomplete? on each one, creating both an N+1 query problem and also a scaling problem because you have to instantiate each object (object instantiation is not fast) just to find out if it responds true or false. 

For efficiency alone, I would be :thumbs_down: on a change like this as it would encourage this kind of bad coding practices.

-Jason




--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-co...@googlegroups.com.
To post to this group, send email to rubyonra...@googlegroups.com.

If you'd like to reply by encrypted email you can find my public key on jasonfleetwoodboldt.com (more about setting GPG: https://gpgtools.org

Phillip Getto

unread,
May 16, 2017, 12:40:31 PM5/16/17
to Ruby on Rails: Core
I think this was merged into 5.1 (https://github.com/rails/rails/pull/24203).

- Phil
Reply all
Reply to author
Forward
0 new messages