Jepessen
Jepessen

Reputation: 12415

generate a model with a string field as primary key

I want to create a User model inside my Ruby on Rails application.

I use following command:

rails generate model User email:string name:string role:string

It is possible to define the email as primary key with this command? Or I must modify the database migration file that I create with this command? And how?

Upvotes: 6

Views: 9628

Answers (4)

David Moles
David Moles

Reputation: 51093

In recent versions of ActiveRecord you can use --primary-key-type to specify the primary key type in the generate command:

rails generate model User email:string --primary-key-type=string

produces the migration:

class CreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users, id: :string do |t|
      t.string :email

      t.timestamps
    end
  end
end

However, as far as I can tell there's still no way to change the name of the primary key column, except by hand.

Upvotes: 1

Chetan Kondawle
Chetan Kondawle

Reputation: 323

In Migration 6.0 or Rails 6

class CreateUsers < ActiveRecord::Migration[6.0]
   def change
       create_table :users, id: false do |t|
           t.string :email, null: false, primary_key: true
           t.timestamps
       end
   end
end

Upvotes: 2

Richard Peck
Richard Peck

Reputation: 76774

To add to @Simone Carletti's answer, you may need to use execute to set the primary key (if it's obscure). This would be especially true if you're modifying an existing table, which you're obviously not doing:

class CreateUsers < ActiveRecord::Migration
   def change
      create_table :users, id: false do |t|
         t.string :email, null: false
         t.timestamps
      end
      execute "ALTER TABLE users ADD PRIMARY KEY (email);"
   end
end

We use uuid's in some of our apps, and that's what we had to do (primary_key: :uuid didn't work)...

enter image description here


Upvotes: 8

Simone Carletti
Simone Carletti

Reputation: 176382

No, you can't. By default the primary key is an auto-increment integer.

However, you can open the migration that was generated from the command, and change it (before running the rake db:migrate command). The migration will likely have a create_table command:

class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      # ...
    end
  end
end

If you read the create_table documentation, you will notice you can pass two options. Specifically, you need to set :id to false to not generate an id field, and you will need to specify the name of the primary key field.

    create_table :users, id: false, primary_key: :email do |t|

Upvotes: 9

Related Questions