Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Telling ActiveRecord::ConnectionAdapters::SchemaStatements#create_table to not create a primary key isn't effective if you manually create an id column

#1788

The situation

I want an "id" column, but I don't want it to be a primary key, and I want full control over its population.

Steps to reproduce


create_table :people, :id => false do |t|
      t.integer :id
      t.timestamps
end

>> Person.primary_key
=> "id"

Problem #1 - Person should not have any primary key, clearly, from the schema dump:

CREATE TABLE "people" ("id" integer, "created_at" datetime, "updated_at" datetime);

That leads to Problem #2:


>> Person.create(:id => 123)
=> #<Person id: 1, created_at: "2009-01-22 06:31:43", updated_at: "2009-01-22 06:31:43">

Using constructor syntax #create or #new, #attributes_from_column_definition is used and the "id" column is filtered out because it's thought of (incorrectly) as the primary key.

If you use the block creation syntax like:


person = Person.new do |p|
p.id = 123
end
person.save

Then you get id correctly set to 123. So the behavior is inconsistent.

Conclusion

If possible, ActiveRecord should not consider a column as being a primary key unless the DB layer says so. Currently it falls back on the string "id".

I'm not sure if you can "set_primary_key null" in the ActiveRecord model, but that might be a valid workaround if we can't rely on the DB layer. In the case of a workaround, it should be documented alongside AR::CA::SS#create_table to let people know they should explicitly set the primary key to null (or whatever) if they expect to use a column called "id".

Reported by Luke Burton · January 22nd, 2009 @ 06:42 AM

State: wontfix
Milestone: 2.x
Assigned to: nobody
Importance: none

Activity

  1. rdavila
    rdavila

    Rails has many conventions and I think that this is one of these. You can't use the id column if it isn't a primary key, but you can setup a distinct primary through the set_primary_key class method. In my opinion if there is and id column and it isn't a primary key it's a problem with the table design.

    April 18th, 2010 @ 10:05 PM

  2. Jeremy Kemper
    Jeremy Kemper
    • State changed from new to wontfix

    April 24th, 2010 @ 10:10 PM