Forums | Admin

Discussion Forums: help

Start New Thread Start New Thread

 

By: Gavin Kistner
RE: Can't use HABTM tables in rails. (help!) [ reply ]  
2007-05-25 18:23
Nevermind, user error - I should have specified :id=>false on the migrations for the habtm tables. Removing the id column fixes the 'problem' described above.

By: Gavin Kistner
Can't use HABTM tables in rails. (help!) [ reply ]  
2007-05-25 18:03
SQLite3 and ActiveRecord fail to work with the simplest HABTM join table. Am I doing something wrong?

Following is the simplest end-to-end test case showing the failure.

SUMMARY

REPRODUCE
C:\>ruby -v
ruby 1.8.5 (2006-08-25) [i386-mswin32]

C:\>rails -v
Rails 1.2.3

C:\>sqlite3 -version
3.3.14

C:\>gem list sqlite3-ruby

*** LOCAL GEMS ***

sqlite3-ruby (1.2.1)
SQLite3/Ruby is a module to allow Ruby scripts to interface with a
SQLite database.

C:\>rails sqltest -q --database=sqlite3

C:\>cd sqltest

C:\sqltest>ruby script\generate model -q Person

C:\sqltest>ruby script\generate model -q Address



...edit migrations elsewhere...



C:\sqltest>type db\migrate\001_create_people.rb
class CreatePeople < ActiveRecord::Migration
def self.up
create_table :people do |t|
t.column :name, :string
end

create_table :addresses_people do |t|
t.column :address_id, :integer
t.column :person_id, :integer
end
end

def self.down
drop_table :people
end
end

C:\sqltest>type db\migrate\002_create_addresses.rb
class CreateAddresses < ActiveRecord::Migration
def self.up
create_table :addresses do |t|
t.column :address, :string
end
end

def self.down
drop_table :addresses
end
end

C:\sqltest>rake db:migrate
(in C:/sqltest)
== CreatePeople: migrating ====================================================
-- create_table(:people)
-> 0.0940s
-- create_table(:addresses_people)
-> 0.0780s
== CreatePeople: migrated (0.1720s) ===========================================

== CreateAddresses: migrating =================================================
-- create_table(:addresses)
-> 0.1400s
== CreateAddresses: migrated (0.1400s) ========================================

C:\sqltest>sqlite3 db\development.sqlite3
SQLite version 3.3.14
Enter ".help" for instructions
sqlite> .schema
CREATE TABLE addresses ("id" INTEGER PRIMARY KEY NOT NULL, "address" varchar(255) DEFAULT NULL);
CREATE TABLE addresses_people ("id" INTEGER PRIMARY KEY NOT NULL, "address_id" integer DEFAULT NULL, "person_id" integer DEFAULT NULL);
CREATE TABLE people ("id" INTEGER PRIMARY KEY NOT NULL, "name" varchar(255) DEFAULT NULL);
CREATE TABLE schema_info (version integer);
sqlite> .quit



...edit models elsewhere...



C:\sqltest>type app\models\address.rb
class Address < ActiveRecord::Base
has_and_belongs_to_many :people
end

C:\sqltest>type app\models\person.rb
class Person < ActiveRecord::Base
has_and_belongs_to_many :addresses
end



C:\sqltest>ruby script\console
Loading development environment.
>> a1 = Address.create :address=>'here'
=> #<Address:0x47b94dc @errors=#<ActiveRecord::Errors:0x47328b0 @errors={}, @base=#<Address:0x47b94dc ...>>, @new_record=false, @attributes={"id"=>1, "address"=>"here"}, @new_record_before_save=true>

>> a2 = Address.create :address=>'there'
=> #<Address:0x471aa30 @errors=#<ActiveRecord::Errors:0x471a300 @errors={}, @base=#<Address:0x471aa30 ...>>, @new_record=false, @attributes={"id"=>2, "address"=>"there"}, @new_record_before_save=true>

>> p1 = Person.create :name=>'Gavin'
=> #<Person:0x471f5a8 @errors=#<ActiveRecord::Errors:0x471ee00 @errors={}, @base=#<Person:0x471f5a8 ...>>, @new_record=false, @attributes={"name"=>"Gavin", "id"=>1}, @new_record_before_save=true>

>> a1.person_ids = [p1.id]
=> [1]

>> a2.person_ids = [p1.id]
ActiveRecord::StatementInvalid: SQLite3::SQLException: SQL logic error or missing database: INSERT INTO addresses_people ("id", "address_id", "person_id") VALUES (1, 2, 1)
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/abstract_adapter.rb:128:in `log'
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/sqlite_adapter.rb:145:in `execute'
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/sqlite_adapter.rb:346:in `catch_schema_changes'
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/sqlite_adapter.rb:145:in `execute'
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/associations/has_and_belongs_to_many_association.rb:132:in `insert_record'
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/associations/association_collection.rb:26:in `concat'
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/associations/association_collection.rb:23:in `each'
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/associations/association_collection.rb:23:in `concat'
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/abstract/database_statements.rb:59:in `transaction'
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/transactions.rb:95:in `transaction'
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/transactions.rb:121:in `transaction'
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/associations/association_collection.rb:22:in `concat'
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/associations/association_collection.rb:145:in `replace'
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/abstract/database_statements.rb:59:in `transaction'
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/transactions.rb:95:in `transaction'
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/transactions.rb:121:in `transaction'
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/associations/association_collection.rb:143:in `replace'
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/associations.rb:950:in `people='
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/associations.rb:960:in `send'
from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/associations.rb:960:in `person_ids='
from (irb):8>>