Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modify Devise to support UUID primary key

I want to modify Devise to make it work with a users table with a UUID primary key with PostgreSQL.

Here is the migration:

class DeviseCreateUsers < ActiveRecord::Migration

  def change
    create_table :users, id: false do |t|
      t.uuid :uuid, null: false
      # ...
    end

    change_table :users do |t|
      t.index :uuid, unique: true
      # ...
    end
  end

  def migrate(direction)
    super
    if direction == :up
      # This is only necessary because the following does not work:
      # t.uuid :uuid, primary: true, null: false
      execute "ALTER TABLE users ADD PRIMARY KEY (uuid);"
    end
  end
end

Here is the User model:

class User < ActiveRecord::Base

  primary_key = :uuid

  devise :database_authenticatable, :recoverable, :registerable,
    :rememberable, :trackable, :validatable

  validates :uuid, presence: true
  before_validation :ensure_uuid
  def ensure_uuid; self.uuid ||= SecureRandom.uuid end

end

Here is the error:

PG::Error: ERROR:  operator does not exist: uuid = integer
LINE 1: ...ECT  "users".* FROM "users"  WHERE "users"."uuid" = 1  ORDER...
                                                             ^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.
: SELECT  "users".* FROM "users"  WHERE "users"."uuid" = 1  ORDER BY "users"."uuid" ASC LIMIT 1

Extracted source (around line #5):

1    .navbar-inner
2      .container
3        = a_nav_tag "App", root_path
4        - if user_signed_in?
5          %ul.nav.pull-right
6            %li.dropdown#user_menu
7              %a.dropdown-toggle(data-toggle="dropdown" href="#")

As you can see above, user_signed_in? is broken. I expect there are several changes needed to move from a 'normal' auto-incrementing ID to a UUID.

For now, I'm just posting the question. I'll take a swing at this later today. If you happen to know how to do this -- or know of a Devise fork, I'd appreciate it.

like image 570
David J. Avatar asked Jan 18 '26 07:01

David J.


1 Answers

I've done this in Rails 4 simply by making the id column a uuid data type when creating the table, and no other configuration changes whatsoever. ie. do not create a column named 'uuid', just change the type of the 'id' column to uuid.

like image 126
Chris Aitchison Avatar answered Jan 19 '26 23:01

Chris Aitchison