Alexandre
Posted on December 6, 2022
Esse post vai ser uma rápida instalação de uuid no rails 7.
Vamos começar criando uma nova aplicação e depois vamos tentar trocar o id padrão para uuid em um projeto existente.
Se você não sabe o que é uuid, eu recomendo esse post.
Índice
Criando um projeto
A nossa aplicação vai usar o PostgreSQL como banco de dado.
rails new uuid_rails -d=postgresql
Para ser capaz de usar uuid no postgresql, tem que ativar a extensão pgcrypto
.
Então vamos criar uma migração para isso.
rails g migration enable_uuid
Abra o arquivo db/migrate/enable_uuid.rb
e adicione o enable_extension 'pgcrypto'
, como você pode ver abaixo.
# db/migrate/enable_uuid
class EnableUuid < ActiveRecord::Migration[7.0]
def change
enable_extension 'pgcrypto'
end
end
Uma rápida explicação sobre esse pgcrypto
.
Essa extensão permite que nós sejamos capaz de usar função de criptografia e tem uma função chamado gen_random_uuid
que ele gera um uuid para gente.
Bem, agora vamos colocar o uuid como chave primária.
Definindo o uuid como chave primária
Vamos criar um generator para evitar o trabalho manual.
Crie um arquivo chamado de generators.rb
no config/initializers/
e coloque o código a seguir.
# config/initializers/generators.rb
Rails.application.config.generators do |g|
g.orm :active_record, primary_key_type: :uuid
end
Agora qualquer modelo criado, vai usar o uuid como chave primária.
Então vamos criar um modelo para ver que está funcionando.
Criando o nosso modelo
Vamos criar um modelo chamado de publicação com título.
rails g model Publicacao titulo
Abra o arquivo db/migrate/create_publicacaos.rb
para observar um coisa.
# db/migrate/create_publicacaos.rb
class CreatePublicacaos < ActiveRecord::Migration[7.0]
def change
create_table :publicacaos, id: :uuid do |t|
t.string :titulo
t.timestamps
end
end
end
Podemos ver que ele está passando um argumento chamado id com valor :uuid
, Então até aqui, ele fez um trabalho correto.
Agora vamos criar o banco de dados e migrar.
rails db:create db:migrate
Abra o rails console
para criar uma nova publicação.
rails console
irb(main):001:0> Publicacao.create(titulo: "Nossa primeira publicação")
TRANSACTION (0.4ms) BEGIN
Publicacao Create (7.0ms) INSERT INTO "publicacaos" ("titulo", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["titulo", "Nossa primeira publicação"], ["created_at", "2022-12-06 10:43:48.903056"], ["updated_at", "2022-12-06 10:43:48.903056"]]
TRANSACTION (1.3ms) COMMIT
=>
#<Publicacao:0x00007fe438a57340
id: "fb030e22-5d0d-47d3-a856-cc5a028da2d3",
titulo: "Nossa primeira publicação",
created_at: Tue, 06 Dec 2022 10:43:48.903056000 UTC +00:00,
updated_at: Tue, 06 Dec 2022 10:43:48.903056000 UTC +00:00>
Podemos ver que o id está com formato de uuid, então vamos criar outro para confirmar.
irb(main):002:0> Publicacao.create(titulo: "Nossa segunda publicação")
TRANSACTION (0.9ms) BEGIN
Publicacao Create (0.9ms) INSERT INTO "publicacaos" ("titulo", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["titulo", "Nossa segunda publicação"], ["created_at", "2022-12-06 10:45:00.606342"], ["updated_at", "2022-12-06 10:45:00.606342"]]
TRANSACTION (4.0ms) COMMIT
=>
#<Publicacao:0x00007fe43a2b6490
id: "4f539d04-43d4-427a-bcc8-b3fc54f3c3db",
titulo: "Nossa segunda publicação",
created_at: Tue, 06 Dec 2022 10:45:00.606342000 UTC +00:00,
updated_at: Tue, 06 Dec 2022 10:45:00.606342000 UTC +00:00>
De fato, está criando o id como uuid.
Com isso, acabamos aqui, mas agora vamos para aqueles que quer mudar o id padrão para uuid com um projeto existente.
Trocando id padrão para uuid em um projeto existente
Eu recomendo que você crie um backup do seu banco de dados antes de tentar aplicar isso no projeto existente.
Vamos criar um aplicação que use id padrão e depois mudarei ele.
rails new id_para_uuid_rails -d=postgresql
cd id_para_uuid_rails/
rails g model Publicacao titulo
rails db:create db:migrate
Agora vamos criar milhares de publicação.
Vamos para rails console
.
rails console
irb(main):001:1> 1000.times do |i|
irb(main):002:1* Publicacao.create titulo: i
irb(main):003:1> end
...
Pronto nós temos mil publicações e eles estão usando id padrão, agora vamos transformar eles em uuid.
Como eu estou usando PostgreSQL como banco de dado, vamos adicionar a extensão pgcrypto
.
Para isso, vamos criar uma migração.
rails g migration enable_uuid
Agora vamos adicionar enable_extension 'pgcrypto'
no db/migrate/enable_uuid
.
# db/migrate/enable_uuid
class EnableUuid < ActiveRecord::Migration[7.0]
def change
enable_extension 'pgcrypto'
end
end
Agora vamos mudar o id.
Crie uma migração para fazer isso.
rails g migration IdToUUID
E adicione o código abaixo no db/migrate/id_to_uuid
.
# db/migrate/id_to_uuid
class IdToUuid < ActiveRecord::Migration[7.0]
def change
add_column :publicacaos, :uuid, :uuid, default: "gen_random_uuid()", null: false
change_table :publicacaos do |t|
t.remove :id
t.rename :uuid, :id
end
execute "ALTER TABLE publicacaos ADD PRIMARY KEY (id);"
end
end
OBS: Se você está mudando em seu projeto, basta trocar a tabela publicacaos para a tabela que você está mudando, e se você quer mudar todos as tabelas, vai tem que copiar e colar, por exemplo:
# db/migrate/id_to_uuid
class IdToUuid < ActiveRecord::Migration[7.0]
def change
add_column :publicacaos, :uuid, :uuid, default: "gen_random_uuid()", null: false
add_column :comentarios, :uuid, :uuid, default: "gen_random_uuid()", null: false
change_table :publicacaos do |t|
t.remove :id
t.rename :uuid, :id
end
change_table :comentarios do |t|
t.remove :id
t.rename :uuid, :id
end
execute "ALTER TABLE publicacaos ADD PRIMARY KEY (id);"
execute "ALTER TABLE comentarios ADD PRIMARY KEY (id);"
end
end
Bem, vamos continuar.
Agora vamos migrar e rodar o rails console
para ver se funcionou.
rails db:migrate
...
rails console
irb(main):001:0> Publicacao.first
Publicacao Load (1.6ms) SELECT "publicacaos".* FROM "publicacaos" ORDER BY "publicacaos"."id" ASC LIMIT $1 [["LIMIT", 1]]
=>
#<Publicacao:0x00007f7cd4d96838
titulo: "299",
created_at: Tue, 06 Dec 2022 12:00:24.017099000 UTC +00:00,
updated_at: Tue, 06 Dec 2022 12:00:24.017099000 UTC +00:00,
id: "002b5dbd-6087-4437-959a-32c06cf96c11">
Podemos ver que o id está de fato em uuid, mas vamos ver se todos estão realmente em formato de uuid.
irb(main):002:0> Publicacao.all.all? { |p| p.id.match? /^.{8}-.{4}-.{4}-.{17}$/ }
Publicacao Load (4.0ms) SELECT "publicacaos".* FROM "publicacaos"
=> true
Deu true
, quer dizer que todos eles estão como uuid.
Com isso, nós acabamos aqui.
Caso tenha dado erro, comente o erro, que tentarei te ajudar.
Bem, então é isso, Tchau!
Posted on December 6, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.