On has_and_belongs_to_many relationships you can use the :uniq option
to ensure that duplicate records in the association table don’t
generate duplicate ActiveRecord objects when you traverse the
relationship.
Is there any way to achieve the same effect when using a
has_many :through relationship?
You could add validation to your join model to disallow records
that will cause duplicate entries when accessing the
has_many :through association.
In this case I can’t do that, because I’m doing a three-way
association. So let’s say my join table has:
id a_id b_id c_id
1 1 1 1
2 1 1 2
Now I want to get all the unique As corresponding to B id 1. How do I
do it? (Assume there might be lots of As for a B, and I want to be
able to do pagination, so would rather do the uniqueness test in the
database rather than in Ruby.)
Obviously I can’t put the validation you suggest on my join table,
because then I can’t have a particular combination of As and Bs
linked to multiple Cs.
(There’s a good chance that I need to re-evaluate my model, but I’ve
looked at it from about twenty different angles and still haven’t
found a way of representing things that seems more comfortable.)
because then I can’t have a particular combination of As and Bs
linked to multiple Cs.
(There’s a good chance that I need to re-evaluate my model, but I’ve
looked at it from about twenty different angles and still haven’t
found a way of representing things that seems more comfortable.)
Pete Y.
–
When a man says he approves of something in principle, it means he
hasn’t the slightest intention of putting it into practice. –
Bismarck
Can you not enforce uniqueness in the DB itself with a unique index?
(And, SHOULD you not for some reason?)
I thought I’d explained this pretty well, but I guess not.
On what should I put the unique index? If I put it just on the pair
of a_id and b_id then I can no longer represent arbitrary 3-way
associations…even the simple example I gave would be ruled out. If
I put the unique index on the combination of a_id, b_id, and c_id
then it still doesn’t solve my problem when querying a B for all
associated As, or vice versa.
The :uniq option on has_many :through in edge since May, and will be
available in Rails 1.2 in a few weeks if you don’t want to go the edge
way.
Thanks Josh, that’s very handy to know.
I don’t really understand the problem you are trying to solve, but
I’ve
had no trouble using the :uniq option, the :select => ‘DISTINCT *’
option, or a unique index in the database. I’ve done all three at
different times and each works as I’d expect.
I seem to have singularly failed to explain my problem in a way that
anybody other than me can understand! Oh well, I’ve somehow ended up
with a couple of useful answers anyway.
On has_and_belongs_to_many relationships you can use the :uniq option
to ensure that duplicate records in the association table don’t
generate duplicate ActiveRecord objects when you traverse the
relationship.
Is there any way to achieve the same effect when using a
has_many :through relationship?
I don’t really understand the problem you are trying to solve, but I’ve
had no trouble using the :uniq option, the :select => ‘DISTINCT *’
option, or a unique index in the database. I’ve done all three at
different times and each works as I’d expect.