many to many :through problem

Hi all,

This should be a simple one, but I just don't see my mistake.

Migration1: class CreateCompanyUsers < ActiveRecord::Migration   def self.up     create_table :employments, :id => false do |t|       t.boolean :admin_role       t.integer :company_id, :user_id       t.timestamps     end   end

  def self.down     drop_table :employments   end end

Migration2: class CreateCompanies < ActiveRecord::Migration   def self.up     create_table :companies do |t|       t.string :name, :subdomain       t.boolean :admin_company       t.timestamps     end     add_index :companies, :subdomain, :unique => true     Company.create :name => "Default", :subdomain => "default", :admin_company => true   end

  def self.down     drop_table :companies   end end

Migration3: class CreateUsers < ActiveRecord::Migration   def self.up     create_table "users", :force => true do |t|       t.column :login, :string, :limit => 40       t.column :name, :string, :limit => 100, :default => '', :null => true       t.column :email, :string, :limit => 100       t.column :crypted_password, :string, :limit => 40       t.column :salt, :string, :limit => 40       t.column :created_at, :datetime       t.column :updated_at, :datetime       t.column :remember_token, :string, :limit => 40       t.column :remember_token_expires_at, :datetime

    end     add_index :users, :login, :unique => true     User.create :login => "admin", :name => "Administrator God", :email => 'admin@example.com', :password => 'password', :password_confirmation => 'password'   end

  def self.down     drop_table "users"   end end

And my models: class Employment < ActiveRecord::Base   belongs_to :company   belongs_to :user end

class Company < ActiveRecord::Base   has_many :employments   has_many :users, :through => :employments end

class User < ActiveRecord::Base   # cut out restful_auth stuff   has_many :employments   has_many :companies, :through => :employments

When testing in script/console: Loading development environment (Rails 2.1.0)

user=User.find :first

=> #<User id: 1, login: "admin", name: "Administrator God", email: "admin@example.com", crypted_password: "a5d460ff8566a5e0e11b6e591f1d8921a5726ea6", salt: "872d3a4ebb1d9b2ef6be18938d36aea3bafe2646", created_at: "2008-08-24 15:53:40", updated_at: "2008-08-24 15:53:40", remember_token: nil, remember_token_expires_at: nil>

company=Company.find :first

=> #<Company id: 1, name: "Default", subdomain: "default", admin_company: true, created_at: "2008-08-24 15:53:40", updated_at: "2008-08-24 15:53:40">

company.users << user

NameError: uninitialized constant Company::Employment   from /Library/Ruby/Gems/1.8/gems/activesupport-2.1.0/lib/ active_support/dependencies.rb:492:in `const_missing'   from /Library/Ruby/Gems/1.8/gems/activerecord-2.1.0/lib/active_record/ base.rb:1909:in `compute_type'   from /Library/Ruby/Gems/1.8/gems/activerecord-2.1.0/lib/active_record/ reflection.rb:129:in `send'   from /Library/Ruby/Gems/1.8/gems/activerecord-2.1.0/lib/active_record/ reflection.rb:129:in `klass'   from /Library/Ruby/Gems/1.8/gems/activerecord-2.1.0/lib/active_record/ reflection.rb:189:in `source_reflection'   from /Library/Ruby/Gems/1.8/gems/activerecord-2.1.0/lib/active_record/ reflection.rb:189:in `collect'   from /Library/Ruby/Gems/1.8/gems/activerecord-2.1.0/lib/active_record/ reflection.rb:189:in `source_reflection'   from /Library/Ruby/Gems/1.8/gems/activerecord-2.1.0/lib/active_record/ reflection.rb:198:in `check_validity!'   from /Library/Ruby/Gems/1.8/gems/activerecord-2.1.0/lib/active_record/ associations/has_many_through_association.rb:5:in `initialize'   from /Library/Ruby/Gems/1.8/gems/activerecord-2.1.0/lib/active_record/ associations.rb:1128:in `new'   from /Library/Ruby/Gems/1.8/gems/activerecord-2.1.0/lib/active_record/ associations.rb:1128:in `users'   from (irb):3

So what did I do wrong, or what did I miss?

Kind regards, Wijnand

Hi all,

This should be a simple one, but I just don't see my mistake.

Migration1: class CreateCompanyUsers < ActiveRecord::Migration def self.up    create_table :employments, :id => false do |t|      t.boolean :admin_role      t.integer :company_id, :user_id      t.timestamps    end end

With has many through, the join table is a model in its own right so
you must not skip :id like you are doing here.

def self.down    drop_table :employments end end

And my models: class Employment < ActiveRecord::Base belongs_to :company belongs_to :user end

class Company < ActiveRecord::Base has_many :employments has_many :users, :through => :employments end

class User < ActiveRecord::Base # cut out restful_auth stuff has_many :employments has_many :companies, :through => :employments

When testing in script/console: Loading development environment (Rails 2.1.0)

user=User.find :first

=> #<User id: 1, login: "admin", name: "Administrator God", email: "admin@example.com", crypted_password: "a5d460ff8566a5e0e11b6e591f1d8921a5726ea6", salt: "872d3a4ebb1d9b2ef6be18938d36aea3bafe2646", created_at: "2008-08-24 15:53:40", updated_at: "2008-08-24 15:53:40", remember_token: nil, remember_token_expires_at: nil>

company=Company.find :first

=> #<Company id: 1, name: "Default", subdomain: "default", admin_company: true, created_at: "2008-08-24 15:53:40", updated_at: "2008-08-24 15:53:40">

company.users << user

NameError: uninitialized constant Company::Employment

That's odd, it couldn't find your Employment class. Is it in
employment.rb ?

Fred