postgres adapater problem with create_table :id => false

Howard Yeh
Wed, 16 Sep 2009 20:36:29 -0000

Hi All,

When saving a record to a table that doesn''t use primary key, the
adapater raises

ActiveRecord::StatementInvalid: PGError: ERROR:  column "id" does not
exist

That''s because the postgres adapter does,

INSERT INTO ... RETURNING "id"

And "id" doesn''t exist for a table that doesn''t ues
it.

The offending block of code is from

PostgreSQLAdapter#insert(sql, name = nil, pk = nil, id_value = nil,
sequence_name = nil)

if supports_insert_with_returning?
  pk, sequence_name = *pk_and_sequence_for(table) unless pk
  if pk
    id = select_value("#{sql} RETURNING #{quote_column_name(pk)}")
    clear_query_cache
    return id
  end
end

The problem is that ActiveRecord::Base.create
would pass in the primary_key "id" for the
parameter pk even though the ActiveRecord class
doesn''t have a primary key.

# this would work
if supports_insert_with_returning?
  # this would work
  pk, sequence_name = *pk_and_sequence_for(table)
  if pk
    id = select_value("#{sql} RETURNING #{quote_column_name(pk)}")
    clear_query_cache
    return id
  end
end


Or is there a way to set the primary key to nil?

class Foo < ActiveRecord::Base
 set_primary_key nil
 primary_key # => ""
end

Howard