ActiveRecord, insert and not auto-incremented primary keys

Hi,

After playing while with ActiveRecord, I’m surprised it isn’t easier to
insert data into a table whose primary key is not auto-incremented by
the database server.

The following code…


– MySQL database “test”

CREATE TABLE gardens
(
code integer NOT NULL,
name varchar(50),
PRIMARY KEY (code)
);


– Ruby

#!/usr/local/bin/ruby
require ‘rubygems’
require_gem ‘activerecord’

ActiveRecord::Base.establish_connection(
:adapter => “mysql”,
:username => “root”,
:host => “localhost”,
:password => “”,
:database => “test”
)

class Garden < ActiveRecord::Base
set_primary_key :code
end

garden = Garden.new(“code” => 1, “name” => “garden1”)
garden.save

… gives this error:

/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/connection_adapters/abstract_adapter.rb:120:in
log': Mysql::Error: #23000Duplicate entry '0' for key 1: INSERT INTO gardens (name) VALUES('garden1') (ActiveRecord::StatementInvalid) from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/connection_adapters/mysql_adapter.rb:184:inexecute’
from
/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/connection_adapters/mysql_adapter.rb:194:in
insert' from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/base.rb:1739:increate_without_callbacks’
from
/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/callbacks.rb:261:in
create_without_timestamps' from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/timestamp.rb:30:increate’
from
/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/base.rb:1718:in
create_or_update_without_callbacks' from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/callbacks.rb:249:increate_or_update’
from
/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/base.rb:1392:in
save_without_validation' from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/validations.rb:724:insave_without_transactions’
from
/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/transactions.rb:126:in
save' from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/connection_adapters/abstract/database_statements.rb:51:intransaction’
from
/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/transactions.rb:91:in
transaction' from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/transactions.rb:118:intransaction’
from
/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/transactions.rb:126:in
`save’
from activerecord.rb:24

What is the most elegant way to solve that?

If I remove the primary key configuration, like this:


class Garden < ActiveRecord::Base
End

… it works.

Is there an equivalent to this?


class Garden < ActiveRecord::Base
set_primary_key :code, :manual
End

Thanks,


Philippe L., Ing. Dipl. EPFL
Attik System
rte de la Fonderie 2
1700 Fribourg
Switzerland
http://www.attiksystem.ch

Tel: +41 (26) 422 13 75
Fax: +41 (26) 422 13 76

Philippe L. wrote:

class Garden < ActiveRecord::Base
set_primary_key :code
end

garden = Garden.new(“code” => 1, “name” => “garden1”)
garden.save

When you use set_primary_key, ActiveRecord maps your key to the
attribute “id” behind the scenes. So you still use “id”.

  • Mark.