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

rename Relation#uniq to Relation#distinct #9683

Merged
merged 2 commits into from
Mar 15, 2013

Conversation

senny
Copy link
Member

@senny senny commented Mar 12, 2013

1.

The similarity of Relation#uniq to Array#uniq is confusing. Since our
Relation API is close to SQL terms I renamed #uniq to #distinct.

There is no deprecation. #uniq and #uniq! are aliases and will continue
to work. I also updated the documentation to promote the use of #distinct.
c7f94f0

2.

Deprecate the :distinct option for Relation#count.
We moved more and more away from passing options to finder / calculation
methods. The :distinct option in #count was one of the remaining places.
Since we can now combine Relation#distinct with Relation#count the option
is no longer necessary and can be deprecated.

@senny
Copy link
Member Author

senny commented Mar 12, 2013

@jonleighton @carlosantoniodasilva what do you think?

@@ -651,9 +651,10 @@ def destroy(*records)
#
# person.pets.select(:name).uniq

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably this doc should be also updated.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@senny ^^ ping about this

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missed this one 😕 . Pushed an updated version.

@carlosantoniodasilva
Copy link
Member

Overall it looks good, just afraid that people could be using uniq_value directly, and that could break?

@senny
Copy link
Member Author

senny commented Mar 12, 2013

@carlosantoniodasilva we could alias it too...

@jonleighton
Copy link
Member

Seems good to me. I agree about aliasing uniq_values. We should probably explicitly mention that uniq is "soft deprecated" and may be switched back to doing to_a.uniq in the future, so new code should definitely be written using distinct.

@senny
Copy link
Member Author

senny commented Mar 15, 2013

@jonleighton I alias #uniq_value and described the silent deprecation.

The similarity of `Relation#uniq` to `Array#uniq` is confusing. Since our
Relation API is close to SQL terms I renamed `#uniq` to `#distinct`.

There is no deprecation. `#uniq` and `#uniq!` are aliases and will continue
to work. I also updated the documentation to promote the use of `#distinct`.
We moved more and more away from passing options to finder / calculation
methods. The `:distinct` option in `#count` was one of the remaining places.
Since we can now combine `Relation#distinct` with `Relation#count` the option
is no longer necessary and can be deprecated.
jonleighton added a commit that referenced this pull request Mar 15, 2013
rename `Relation#uniq` to `Relation#distinct`
@jonleighton jonleighton merged commit 0721d3b into rails:master Mar 15, 2013
@senny senny deleted the deprecate_count_distinct_option branch March 15, 2013 13:22
@carlosantoniodasilva
Copy link
Member

👍 ❤️

@bughit
Copy link
Contributor

bughit commented Aug 18, 2013

this seems wrong, distinct is a parameter specifically to the count expression COUNT(DISTINCT date(attr)), so it's completely logical for it to be a parameter to the AR analogue of COUNT, the count method. Separating distinct from count does not make sense.

.count('date(attr)', distinct: true)

is this supposed to be a replacement for the above?

.distinct. ...possible intervening chain... .count('date(attr)')

this both reads wrong, and produces unintended (albeit innocuous in this case) sql:

SELECT DISTINCT COUNT(DISTINCT date(created_at))

@rafaelfranca
Copy link
Member

.count('DISTINCT date(attr)') should work fine.

@bughit
Copy link
Contributor

bughit commented Aug 19, 2013

so would .count_by_sql, but why is it deemed necessary to break count('expression', distinct: true)

@rafaelfranca
Copy link
Member

The reason is to make the API consistent with our view of not passing options to finders/calculations methods. It is a matter of reducing the API possibilities to focus on what is important.

This feature in my opinion doesn't add anything over .count('DISTINCT date(attr)'), so we don't need to keep it.

@bughit
Copy link
Contributor

bughit commented Aug 19, 2013

This feature in my opinion doesn't add anything ...

That may be an argument for rejecting a feature request, but not for introducing a breaking change.
We are talking about one line of code: distinct = options[:distinct]
It and the code that relies on it .count('expression', distinct: true) are not so offensive that a breaking change is needed.

@senny
Copy link
Member Author

senny commented Aug 19, 2013

In my opinion keeping the API consistent is worth a breaking change. There were also special cases where distinct: true did not work. For example PostgreSQL allows you to do a distinct on multiple columns:

SELECT COUNT(DISTINCT(name, email)) FROM members;

It's better to let the user know that he can specify the exact count clause than abstracting that away with the distunct: true option.

Member.count("DISTINCT(name, email)")

Also the Relation#distinct method is there to be combined with `select´:

Person.select("name").distinct.count

Those two avenues provide a more complete API and there is no more need to keep the third option (passing distinct: true) around.

@rafaelfranca
Copy link
Member

That may be an argument for rejecting a feature request, but not for introducing a breaking change.

Yes, it is an argument to introducing a breaking change too for two reasons:

  1. Rails Core don't want to maintain this feature in the future. The behavior introduced by this feature is not worth the maintenance cost or the doubts that it can introduce for the users like the examples @senny added in the last comment.
  2. Rails 4 was a major release so breaking changes are expected and it was the best moment to remove code that doesn't fit the direction the framework is taking or doesn't seems a good API.

senny added a commit that referenced this pull request May 26, 2015
See #9683 for the reasons we switched to `distinct`.

Here is the discussion that triggered the actual deprecation #20198.

`uniq`, `uniq!` and `uniq_value` are still around.
They will be removed in the next minor release after Rails 5.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants