GitHub is home to over 20 million developers working together to host and review code, manage projects, and build software together.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
Already on GitHub? Sign in to your account
Use case and stop-gap solution are described in this StackOverflow QA.
class User < ActiveRecord::Base
has_many :roles, :through => :user_roles
Dev wants to append a role without having to check:
user.roles << role # automatically checks roles.include?
Novice Rails devs might assume that adding :uniq would work:
has_many :roles, :through => :user_roles, :uniq => true
Of course it doesn't because that presently affects only queries, ignoring duplicates. What would be nice if it it also ignored attempts to add a duplicate, running up against any DB constraints.
A work-around described on the QA is:
has_many :roles, :through => :user_roles do
super( Array(new_item) - proxy_association.owner.roles )
Could this contextual redefinition of << be made automatically when marking a has_many as uniq?
I don't think so. This is your domain logic so it your responsibility to check it. Also we don't get feature requests in the issues tracker.
Sorry, I read "only bug reports and pull requests" in CONTRIBUTING and thought of it as a bug.
has_many dedupes. Why shouldn't has_many :through ?
+1 for this. I really consider this as a bug.
Why do you think that people using :uniq does not require de-duplication?
<< is actually an only way to append an element to the association; it really should take care about duplications by itself. Otherwise collection.where() becomes the only way to do that.
This keeps coming up!
see: #10047 (comment)
Will re-iterate my 👍 (and agree that it doesn't seem like the expected behavior and thus bug-esque) but apparently there's a race condition issue here — the (non-optimal) fix is to add an unique constraint on the database layer.
@mbhnyc Thanks for referencing! I'll check it out.