# Problems with has\_many :through and habtm

**URL:** <https://www.ruby-forum.com/t/problems-with-has-many-through-and-habtm/170686>\
**Category:** Rails\
**Created:** [June 21, 2009, 2:19am UTC](https://www.ruby-forum.com/t/problems-with-has-many-through-and-habtm/170686 "2009-06-21T02:19:45Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![erik](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/b5ac83/32.png) [@erik](https://www.ruby-forum.com/u/erik)\
**Post date:** [June 21, 2009, 2:19am UTC](https://www.ruby-forum.com/t/problems-with-has-many-through-and-habtm/170686/1 "2009-06-21T02:19:45Z")

</div>

I have tried this both ways and each time same results, duplicate  
entries.

Here is the simple test:  
t = Trim.find(:first, :conditions =\> [‘id \> 65000000’])  
options = Option.find\_all\_by\_trim\_id(t.id)  
puts options.size  
v = NewVehicle.new({:trim\_id =\> t.id})  
v.option\_ids = options.map {|o| o.id}  
v.save

I also tried it just with v.options = options, using option\_ids was  
just another attempt to make this work

The size of options in this case is 47. options\_vehicles which is my  
join table will have 94 results exactly 2 of each one option. So if  
the option\_id = 6 and vehicle\_id is 4 i have 6,4 in the join table  
twice.

I am doing one thing a little odd, but i have no idea what’s causing  
this issue. My models look like this:  
Option.rb  
set\_primary\_key “option\_id”  
has\_many :options\_vehicles  
has\_many :vehicles, :through =\> :options\_vehicles

I have to use option\_id as the primary key and it’s a string. This is  
other data i’m importing and I can’t change the way it’s organzied.

Vehicle.rb  
has\_many :options\_vehicles,  
has\_many :options, :through =\> :options\_vehicles

My join table looks like a habtm table because it was. I have tried  
this both ways activerecord continues to put in dupes.

I actually went into the code at  
/data/www/production/vendor/rails/activerecord/lib/active\_record/  
associations.rb:1392  
and put prints in there and see it showing the size of the records to  
save as 47, but it’s going through here twice.

I have option\_id in options marked as the primary key with a unique  
index in mysql.

Any help would be appreciated I feel like I’m going crazy…  
Erik

---

<div class="post-metadata">

**Author:** ![erik](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/b5ac83/32.png) [@erik](https://www.ruby-forum.com/u/erik)\
**Post date:** [June 21, 2009, 8:41am UTC](https://www.ruby-forum.com/t/problems-with-has-many-through-and-habtm/170686/2 "2009-06-21T08:41:09Z")

</div>

On Jun 20, 5:18 pm, erik [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Option.rb
> 
> index in mysql.
> 
> Any help would be appreciated I feel like I’m going crazy…  
> Erik

You don’t need to do the Options.find because you already have  
t.options. This may also explain the dupes.

-eric

---

<div class="post-metadata">

**Author:** ![erik](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/b5ac83/32.png) [@erik](https://www.ruby-forum.com/u/erik)\
**Post date:** [June 21, 2009, 5:28pm UTC](https://www.ruby-forum.com/t/problems-with-has-many-through-and-habtm/170686/3 "2009-06-21T17:28:08Z")

</div>

I don’t follow you.

I find all the options based on the idea of a trim (a style). Think  
about how a honda civic ex might have different options then a honda  
civic lx. In the real app you would only select a subset of those  
options to assign to your vehicle. Vehicle is kind of like an  
instance of a Trim, but it’s different and has it’s own model. So I  
am grabbing all the options by trim (options =  
Option.find\_all\_by\_trim\_id(t.id)) and then assigning them to a vehicle  
(v.options = options or v.options\_ids = options\_ids).

You are right I could of done t.options instead of  
Option.find\_all\_by\_trim\_id, but I have tried both. I replaced:  
Option.find\_all\_by\_trim\_id with options = t.options and I have 47 in  
the array of options, but 94 are saved, 2 each exactly.

It works fine if I do:  
options.each {|o|  
OptionsVehicle.create({‘option\_id’ =\> o.option\_id, ‘vehicle\_id’ =\>  
v.id})  
}

and explicitly create the join table values.

I have confused rails…I guess.  
Erik

---

<div class="post-metadata">

**Author:** ![erik](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/b5ac83/32.png) [@erik](https://www.ruby-forum.com/u/erik)\
**Post date:** [June 21, 2009, 5:29pm UTC](https://www.ruby-forum.com/t/problems-with-has-many-through-and-habtm/170686/4 "2009-06-21T17:29:54Z")

</div>

I’m in Rails 2.2.2 if that matters.  
Erik

---

<div class="post-metadata">

**Author:** ![erik](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/b5ac83/32.png) [@erik](https://www.ruby-forum.com/u/erik)\
**Post date:** [June 21, 2009, 6:30pm UTC](https://www.ruby-forum.com/t/problems-with-has-many-through-and-habtm/170686/5 "2009-06-21T18:30:34Z")

</div>

What are the associations for the Trim model, wrt Options and  
Vehicles? I’m also assuming that the NewVehicle model is a typo and  
it’s supposed to be just Vehicle.new in the snippet.

I’m thinking that you need either uniqueness validations or to dedupe  
manually in your save/updates, but it’s hard to tell so far.

-eric

---

<div class="post-metadata">

**Author:** ![erik](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/b5ac83/32.png) [@erik](https://www.ruby-forum.com/u/erik)\
**Post date:** [June 21, 2009, 11:03pm UTC](https://www.ruby-forum.com/t/problems-with-has-many-through-and-habtm/170686/6 "2009-06-21T23:03:03Z")

</div>

NewVehicle is STI off of Vehicle.  
It doesn’t matter if you use Vehicle or NewVehicle the outcome is the  
same.

Trim definition:  
class Trim \< ActiveRecord::Base

## Associations

belongs\_to :model  
has\_many :colors  
has\_many :options

so it has\_many options, which is why t.options would of worked along  
with find the options by trim id.  
class Vehicle \< ActiveRecord::Base  
def Vehicle:

## Associations

belongs\_to :trim  
belongs\_to :base\_exterior\_color, :class\_name  
=\>‘Colors’, :foreign\_key =\> ‘exterior\_color\_base\_id’  
has\_many :options\_vehicles, :foreign\_key =\> :vehicle\_id  
has\_many :options, :through =\> :options\_vehicles

I think you are on the right track. Since a vehicle belongs to a  
trim, that trim already has every single option available for that car  
attached to it. What I want to do is say only X amount of those  
options are actually on this Vehicle though. Vehicle is more of an  
instance of a trim. I do need to store the trims though…i can’t  
just make them a pure virtual class.

Unique doesn’t work exactly. It’s fine on the read, but i still have  
double values in the join table.

It must be something to do with the fact trim has\_many options and  
vehicles belong to a trim? i would assume this would work as i’m  
saving into a join table.

Erik
