habtm confusion

Frew Schmidt schrieb:

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: -- <p><label for="senator_committee">Committee</label><br/> <%= select(:senator, :committees,            Committee.find(:all).map {|c| [c.name, c.id]}, {:include_blank => true}, {:multiple => true}) %> </p> --

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.

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...

<p><label for="senator_committee">Committee</label><br/> > <%= select('committee', 'committee_id', > Committee.find(:all).map {|c| [c.name, c.id]}, > {:include_blank => true}, {:multiple => true}) %> > </p>

... 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

good luck,

andy koch

Frew Schmidt 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

Frew Schmidt schrieb:

Andy Koch wrote:

Frew Schmidt 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.)

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