# Habtm confusion

**URL:** <https://www.ruby-forum.com/t/habtm-confusion/109590>\
**Category:** Rails\
**Created:** [July 17, 2007, 4:56am UTC](https://www.ruby-forum.com/t/habtm-confusion/109590 "2007-07-17T04:56:53Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![frew](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/c0e974/32.png) [@frew](https://www.ruby-forum.com/u/frew)\
**Post date:** [July 17, 2007, 4:56am UTC](https://www.ruby-forum.com/t/habtm-confusion/109590/1 "2007-07-17T04:56:53Z")

</div>

Hello friends!

I am trying to make a database that will have a group of people set to  
committees, and a person can be in multiple committees, and a committee  
obviously has multiple people. The people are senators at my  
university. These are my current models:

## senator.rb:

## class Senator \< ActiveRecord::Base validates\_presence\_of :first\_name, :last\_name, :floor has\_and\_belongs\_to\_many :committees#, :dependent =\> :nullify #has\_many :chairs, :class\_name =\> “Committee”#, :dependent =\> :nullify end

The last has\_many is commented out so that I can at least get this  
working, and then I’ll add that in later. Also note that the :dependent  
has been commented out. Is this deprecated or no longer supported?  
What’s the deal?

## committee.rb

## class Committee \< ActiveRecord::Base validates\_presence\_of :name has\_and\_belongs\_to\_many :senators #, :dependent =\> :nullify #has\_one :head, :class\_name =\> “Senator” #, :dependent =\> :nullify end

Same as before on the comments.

## Also, for my view I am trying the following:

Committee  
\<%= select(:senator, :committees, Committee.find(:all).map {|c| [c.name, c.id]}, {:include\_blank =\> true}, {:multiple =\> true}) %\>

--

On the view I get the following error:

ActiveRecord::StatementInvalid

and the trace:

/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active\_record/connection\_adapters/sqlite\_adapter.rb:360:in  
`table_structure' /usr/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/core_ext/object/misc.rb:23:in`returning’  
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active\_record/connection\_adapters/sqlite\_adapter.rb:359:in  
`table_structure' /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/sqlite_adapter.rb:210:in`columns’  
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active\_record/associations/has\_and\_belongs\_to\_many\_association.rb:165:in  
`finding_with_ambigious_select?' /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/associations/has_and_belongs_to_many_association.rb:55:in`find’  
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active\_record/associations/association\_collection.rb:159:in  
`find_target' /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/associations/association_proxy.rb:131:in`load\_target’  
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active\_record/associations/association\_proxy.rb:29:in  
`respond_to?' /usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_view/helpers/form_options_helper.rb:116:in`options\_for\_select’  
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active\_record/base.rb:1358:in  
`inject' /usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_view/helpers/form_options_helper.rb:114:in`each’  
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action\_view/helpers/form\_options\_helper.rb:114:in  
`inject' /usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_view/helpers/form_options_helper.rb:114:in`options\_for\_select’  
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action\_view/helpers/form\_options\_helper.rb:302:in  
`to_select_tag' /usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_view/helpers/form_options_helper.rb:66:in`select’  
#{RAILS\_ROOT}/app/views/admin/\_form.rhtml:26:in  
`_run_rhtml_47app47views47admin47_form46rhtml' #{RAILS_ROOT}/app/views/admin/edit.rhtml:4:in`\_run\_rhtml\_47app47views47admin47edit46rhtml’  
#{RAILS\_ROOT}/app/views/admin/edit.rhtml:3:in  
`\_run\_rhtml\_47app47views47admin47edit46rhtml’

Any help at all would be much appreciated.

---

<div class="post-metadata">

**Author:** ![frew](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/c0e974/32.png) [@frew](https://www.ruby-forum.com/u/frew)\
**Post date:** [July 17, 2007, 6:11pm UTC](https://www.ruby-forum.com/t/habtm-confusion/109590/2 "2007-07-17T18:11:43Z")

</div>

Frew S. schrieb:

> validates\_presence\_of :first\_name, :last\_name, :floor  
> committee.rb  
> Also, for my view I am trying the following:  
> ActiveRecord::StatementInvalid  
> `columns' /usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_view/helpers/form_options_helper.rb:116:in `to\_select\_tag’

first, you have a “committees\_senators” table to manage your many-many  
join

second, your rhtml looks odd to me, I haven’t used that in a while but I  
think the bit…

:senator, :committees,

… looks wrong

I’m guessing you want a list of committees. You should have something  
more like…

Committee  
 \> \<%= select('committee', 'committee\_id', \> Committee.find(:all).map {|c| [c.name, c.id]}, \> {:include\_blank =\> true}, {:multiple =\> true}) %\> \>

… if you want the committees a senator is associated with you’ll need  
to add some extra code, something like “:selected =\> [Arr of Committee  
Id’s]” should work

finally, I think :dependent is for has\_many, not habtm. You should  
check the documentation to be certain. [http://api.rubyonrails.org](http://api.rubyonrails.org)

good luck,

andy koch

---

<div class="post-metadata">

**Author:** ![frew](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/c0e974/32.png) [@frew](https://www.ruby-forum.com/u/frew)\
**Post date:** [July 17, 2007, 6:39pm UTC](https://www.ruby-forum.com/t/habtm-confusion/109590/3 "2007-07-17T18:39:40Z")

</div>

Thanks for the reply Andy!

> first, you have a “committees\_senators” table to manage your many-many  
> join

I know that, but that’s abstracted away right? I don’t need to deal  
with it, do I?

> Committee  
> \> \<%= select('committee', 'committee\_id', \> Committee.find(:all).map {|c| [c.name, c.id]}, \> {:include\_blank =\> true}, {:multiple =\> true}) %\> \>

as for the rhtml, the docs said the following:

select(object, method, choices, options = {}, html\_options = {})

so I presumed that I wanted :senator, :committees, but now that I think  
about that, that really doesn’t make a whole lot of sense.

> … if you want the committees a senator is associated with you’ll need  
> to add some extra code, something like “:selected =\> [Arr of Committee  
> Id’s]” should work

Nah, I’ll do that later, once I have the basics figured out.

> finally, I think :dependent is for has\_many, not habtm. You should  
> check the documentation to be certain. [http://api.rubyonrails.org](http://api.rubyonrails.org)

Yeah, I realized last night that :dependent really doesn’t make any  
sense at all for habtm, because there is the intermediary table. I’m  
sure I don’t need to explain it to you guys.

Thanks a bunch for the tips. When I get time I will make modifications  
based on this and see how things go.

-fREW

---

<div class="post-metadata">

**Author:** ![frew](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/c0e974/32.png) [@frew](https://www.ruby-forum.com/u/frew)\
**Post date:** [July 17, 2007, 6:55pm UTC](https://www.ruby-forum.com/t/habtm-confusion/109590/4 "2007-07-17T18:55:49Z")

</div>

Frew S. schrieb:

> Thanks for the reply Andy!
> 
> > first, you have a “committees\_senators” table to manage your many-many  
> > join
> 
> I know that, but that’s abstracted away right? I don’t need to deal  
> with it, do I?

> -fREW

correct, but you must first create the table in your DB with appropriate  
structure

/ak

---

<div class="post-metadata">

**Author:** ![frew](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/c0e974/32.png) [@frew](https://www.ruby-forum.com/u/frew)\
**Post date:** [July 17, 2007, 7:05pm UTC](https://www.ruby-forum.com/t/habtm-confusion/109590/5 "2007-07-17T19:05:26Z")

</div>

Andy K. wrote:

> Frew S. schrieb:
> 
> > Thanks for the reply Andy!
> > 
> > > first, you have a “committees\_senators” table to manage your many-many  
> > > join
> > 
> > I know that, but that’s abstracted away right? I don’t need to deal  
> > with it, do I?
> 
> > -fREW
> 
> correct, but you must first create the table in your DB with appropriate  
> structure

Oooh!

I never made that connection. Here is the migration that I have made to  
define the table. Tell me if anything looks totally wrong with it:

## 005\_create\_committees\_senators.rb

class CreateCommitteesSenators \< ActiveRecord::Migration  
def self.up  
create\_table :committees\_senators do |t|  
t.column :committee\_id, :integer  
t.column :senator\_id, :integer  
end  
end

## def self.down drop\_table :committees end end

(It seems to have worked so far.)

---

<div class="post-metadata">

**Author:** ![frew](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/c0e974/32.png) [@frew](https://www.ruby-forum.com/u/frew)\
**Post date:** [July 19, 2007, 1:24am UTC](https://www.ruby-forum.com/t/habtm-confusion/109590/6 "2007-07-19T01:24:55Z")

</div>

Frew S. schrieb:

> > >
> 
> ## – end end
> 
> (It seems to have worked so far.)

close, but you’re missing a few bits. See this rewrite…

def self.up  
create\_table :committees\_senators, :id =\> false do |t|  
t.column :committee\_id, :integer, :null =\> false  
t.column :senator\_id, :integer, :null =\> false  
end

say “Add unique index on ‘committees\_senators’”, true  
add\_index(:committees\_senators, [:committee\_id, :senator\_id], :unique =\>  
true)  
end

…  
The difference is:

1. this removes the ‘id’ column from your join table with the “:id =\>  
false”, it is not needed since the joined pairs are the key
2. enforces in DB that neither ID in a pair may ever be null (:null =\>  
false)
3. creates a unique index on the table, while this isn’t a true primary  
key index it does ensure you won’t have any duplicity in the table.

And that should do it.

andy
