Reputation: 6642
I am writing a migration script to create a table with a primary key column that is named guid
and is a VARCHAR(25)
. The issue is I feel like I am having to double my effort to achieve what should be possible in one step.
If I run:
create_table(:global_feeds, :primary_key => 'guid') do |t|
t.string :guid, :limit => 25
t.text :title
t.text :subtitle
...
t.timestamps
end
I get a table with a primary key called guid
no column called id
(which is what I want). However, the issue is the guid
column is an INT(11)
with auto increment turned on. So I have to run one additional command:
change_column :global_feeds, :guid, :string, :limit => 25
Seems a bit convoluted to have to basically run two SQL commands to get what I believe should be possible in one.
Any suggestions on how to optimize this?
Upvotes: 18
Views: 39643
Reputation: 1279
In Rails 5, for thoes who got problem ArgumentError: Index name '*' on table '*' already exists
when rails db:setup
with migration as from @kakoni, the following works for me
create_table(:global_feeds, primary_key: :guid, id: false) do |t|
t.string :guid
...
end
For more information, check create_table.
Upvotes: 1
Reputation: 5120
In Rails 4 you can do;
create_table :global_feeds, id: false do |t|
t.string :guid, primary_key: true
...
end
Upvotes: 30
Reputation: 461
You need to use #column instead of #string. For instance:
create_table(:global_feeds, :primary_key => 'guid') do |t|
t.column :guid, "varchar(25)", :null => false
...
end
Note that the varchar
type is not portable to databases other than MySQL.
Upvotes: 4
Reputation: 4486
I suppose you're using mySQL, so here is what you can try
create_table :global_feeds, {:id => false} do |t|
t.string :guid
t.text :title
t.text :subtitle
t.timestamps
end
execute "ALTER TABLE global_feeds ADD PRIMARY KEY (guid);"
If you're not on mySQL you should change the query in the execute
command to work on your DB engine. I'm not sure if you can do that on SQLite though. And don't forget to put this line somewhere in global_feed.rb model:
set_primary_key :guid
Anyway you're getting the most out of Rails while you're sticking to its conventions. Changing primary key name and type might not be a very good idea.
Upvotes: 23
Reputation: 2343
This is possible in Rails 3. try:
def self.up
create_table(:signups, :id => false) do |t|
t.string :token, :primary => true
check out this gist for a great solution for using UUIDs as a primary key col: https://gist.github.com/937739
Upvotes: 3