Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make AR::Relation include Enumerable #8794

Closed
wants to merge 1 commit into from

Conversation

@bogdan
Copy link
Contributor

commented Jan 7, 2013

In this way Relation will gain more Array behaviors (like as_json method that is no longer required in Relation).
Also it delegates every method to to_a without method_missing which is faster.

A few tests need a change because collect without a block doesn't load the relation anymore. This seems ok.

@robin850

This comment has been minimized.

Copy link
Member

commented Jan 13, 2013

@luke-gru

This comment has been minimized.

Copy link
Contributor

commented Jan 13, 2013

I'm worried about the order of the include here for Enumerable. Wouldn't this override certain methods, such as count from ActiveRecord::Calculations? It would delegate to to_a and the records would be loaded instead of just querying for the count. Not sure if there are other cases like this, just putting this out there. Otherwise I think this makes sense.

Edit: just thought of others as well. first, last, select, find

@bogdan

This comment has been minimized.

Copy link
Contributor Author

commented Jan 13, 2013

@luke-gru Enumerable goes below any other module included in relation in hierarchy, so a method from any other module including Calculations and many others will be called before.

@luke-gru

This comment has been minimized.

Copy link
Contributor

commented Jan 13, 2013

oh, right. My bad!

@guiocavalcanti

This comment has been minimized.

Copy link
Contributor

commented May 14, 2013

Any news from about this?

@apotonick

This comment has been minimized.

Copy link
Contributor

commented May 15, 2013

This totally makes sense and allows us to detect collections easily.

@rafaelfranca

This comment has been minimized.

Copy link
Member

commented Sep 22, 2013

@jonleighton @tenderlove what do you think?

@jonleighton

This comment has been minimized.

Copy link
Member

commented Sep 24, 2013

In the past we made methods like select behave differently depending on whether or not they were passed a block. This turned out to cause confusion, so we removed that. I believe select now raises an error when passed a block. Basicalley I don't think Relation can be transparently treated as enumerable, so I don't think it should include Enumerable.

@tenderlove

This comment has been minimized.

Copy link
Member

commented Sep 24, 2013

Agree with @jonleighton

@tenderlove tenderlove closed this Sep 24, 2013

@bogdan

This comment has been minimized.

Copy link
Contributor Author

commented Sep 25, 2013

It is not raising anything when block is passed:


As I remember "Make Relation behave like Enumerable" started from the fact that in previous versions of Rails association was magically showing itself as array:

User.has_many :projects
User.first.projects.class # => Array

Maybe that was a confusion mentioned by @jonleighton, but there is right idea behind it:
Anyway people expecting associations and relations to behave like Array even if it never was it
I think we should give people what they want instead of teaching them that they have to do instead.

My personal concern behind this patch (that supposed to be next step) was ability to embed batches into relation's each method:
Long running Relation#each can appear in places where you didn't expect it initially. Like one object appeared with 10k+ records in has_many relation while the average is below 10.
That is why random memory usage tsunamis appear.

Making Relation to include Enumerable would introduce single point of control for each method. That should make each to use batches by default an easy feature.
It also would be super-cool to forget about batches and make their usage completely automatic.

@rafaelfranca

This comment has been minimized.

Copy link
Member

commented Sep 25, 2013

We already discussed this a lot and we will stand with this decision. Relations are not Arrays even if they have some methods in common.

@bogdan bogdan deleted the bogdan:relation-enumerable branch May 7, 2014

bogdan referenced this pull request Jun 19, 2015
Use `Enumerable#sum` on `ActiveRecord::Relation` when a block is given
This matches our behavior in other cases where useful enumerable methods
might have a different definition in `Relation`. Wanting to actually
enumerate over the records in this case is completely reasonable, and
wanting `.sum` is reasonable for the same reason it is on `Enumerable`
in the first place.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
8 participants
You can’t perform that action at this time.