Eu nomeei erroneamente uma coluna em hased_password
vez de hashed_password
.
Como atualizo o esquema do banco de dados, usando a migração para renomear esta coluna?
Eu nomeei erroneamente uma coluna em hased_password
vez de hashed_password
.
Como atualizo o esquema do banco de dados, usando a migração para renomear esta coluna?
Respostas:
rename_column :table, :old_column, :new_column
Você provavelmente desejará criar uma migração separada para fazer isso. (Renomeie FixColumnName
como quiser.):
script/generate migration FixColumnName
# creates db/migrate/xxxxxxxxxx_fix_column_name.rb
Em seguida, edite a migração para fazer sua vontade:
# db/migrate/xxxxxxxxxx_fix_column_name.rb
class FixColumnName < ActiveRecord::Migration
def self.up
rename_column :table_name, :old_column, :new_column
end
def self.down
# rename back if you need or do something else or do nothing
end
end
Para o Rails 3.1, use:
Enquanto os métodos up
e down
ainda se aplicam, o Rails 3.1 recebe umachange
método que "sabe como migrar seu banco de dados e revertê-lo quando a migração é revertida sem a necessidade de escrever um método separado".
Consulte " Migrações de registros ativos " para obter mais informações.
rails g migration FixColumnName
class FixColumnName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
Se você tiver um monte de colunas para renomear ou algo que exigiria repetir o nome da tabela repetidas vezes:
rename_column :table_name, :old_column1, :new_column1
rename_column :table_name, :old_column2, :new_column2
...
Você pode usar change_table
para manter as coisas um pouco mais organizadas:
class FixColumnNames < ActiveRecord::Migration
def change
change_table :table_name do |t|
t.rename :old_column1, :new_column1
t.rename :old_column2, :new_column2
...
end
end
end
Então, db:migrate
como sempre, ou como você trabalha com seus negócios.
Para Rails 4:
Ao criar um Migration
para renomear uma coluna, o Rails 4 gera um change
método em vez de up
e down
como mencionado na seção acima. O change
método gerado é:
$ > rails g migration ChangeColumnName
que criará um arquivo de migração semelhante a:
class ChangeColumnName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
self.up
eu não diria self.down
" sempre deve ser o oposto". Depende do contexto da sua migração. Apenas colocar o "oposto" pode não ser a migração "certa" para baixo.
def self.up
e def self.down
com, def change
e ele saberá reverter.
change
método não é uma prova completa, por isso tendem a usar up
e down
métodos para migrações complexas.
Na minha opinião, nesse caso, é melhor usar rake db:rollback
, editar a migração e executar novamente rake db:migrate
.
No entanto, se você tiver dados na coluna que não deseja perder, use rename_column
.
Se a coluna já estiver preenchida com dados e estiver em produção, recomendo uma abordagem passo a passo, para evitar tempo de inatividade na produção enquanto aguarda as migrações.
Primeiro, eu criaria uma migração de banco de dados para adicionar colunas com os novos nomes e preenchê-los com os valores do nome da coluna antiga.
class AddCorrectColumnNames < ActiveRecord::Migration
def up
add_column :table, :correct_name_column_one, :string
add_column :table, :correct_name_column_two, :string
puts 'Updating correctly named columns'
execute "UPDATE table_name SET correct_name_column_one = old_name_column_one, correct_name_column_two = old_name_column_two"
end
end
def down
remove_column :table, :correct_name_column_one
remove_column :table, :correct_name_column_two
end
end
Depois, comprometia exatamente essa mudança e empurrava a mudança para a produção.
git commit -m 'adding columns with correct name'
Então, uma vez que o commit foi colocado em produção, eu executaria.
Production $ bundle exec rake db:migrate
Em seguida, atualizava todas as visualizações / controladores que referenciavam o nome da coluna antiga para o novo nome da coluna. Execute meu conjunto de testes e confirme apenas essas alterações. (Depois de verificar se estava funcionando localmente e passando todos os testes primeiro!)
git commit -m 'using correct column name instead of old stinky bad column name'
Então eu empurrava esse compromisso para a produção.
Nesse ponto, você pode remover a coluna original sem se preocupar com qualquer tipo de tempo de inatividade associado à própria migração.
class RemoveBadColumnNames < ActiveRecord::Migration
def up
remove_column :table, :old_name_column_one
remove_column :table, :old_name_column_two
end
def down
add_column :table, :old_name_column_one, :string
add_column :table, :old_name_column_two, :string
end
end
Em seguida, envie essa última migração para a produção e execute bundle exec rake db:migrate
em segundo plano.
Sei que isso é um pouco mais envolvido em um processo, mas prefiro fazer isso do que ter problemas com minha migração de produção.
execute "Update table_name set correct_name_column_one = old_name_column_one"
http://api.rubyonrails.org/classes/ActiveRecord/Migration.html
Debaixo Available Transformations
rename_column(table_name, column_name, new_column_name):
Renomeia uma coluna, mas mantém o tipo e o conteúdo.
rename_column
.
Execute o comando abaixo para criar um arquivo de migração:
rails g migration ChangeHasedPasswordToHashedPassword
Em seguida, no arquivo gerado na db/migrate
pasta, escreva rename_column
como abaixo:
class ChangeOldCoulmnToNewColumn < ActiveRecord::Migration
def change
rename_column :table_name, :hased_password, :hashed_password
end
end
Algumas versões do Ruby on Rails suportam o método up / down para a migração e, se você tiver o método up / down na sua migração, então:
def up
rename_column :table_name, :column_old_name, :column_new_name
end
def down
rename_column :table_name, :column_new_name, :column_old_name
end
Se você possui o change
método em sua migração, então:
def change
rename_column :table_name, :column_old_name, :column_new_name
end
Para obter mais informações, você pode mover: Ruby on Rails - Migrações ou Migrações do Active Record .
Se o seu código não for compartilhado com outro, a melhor opção é fazer apenas rake db:rollback
então editar o nome da coluna na migração e rake db:migrate
. É isso aí
E você pode escrever outra migração para renomear a coluna
def change
rename_column :table_name, :old_name, :new_name
end
É isso aí.
rake db:rollback
é uma ótima sugestão. Mas, como você disse, apenas se a migração ainda não tiver sido enviada.
Como opção alternativa, se você não é casado com a idéia de migrações, existe uma jóia atraente para o ActiveRecord que manipulará as alterações de nome automaticamente para você, no estilo Datamapper. Tudo o que você faz é alterar o nome da coluna no seu modelo (e certifique-se de colocar Model.auto_upgrade! Na parte inferior do seu model.rb) e viola! O banco de dados é atualizado em tempo real.
https://github.com/DAddYE/mini_record
Nota: Você precisará nuke db / schema.rb para evitar conflitos
Ainda em fase beta e, obviamente, não para todos, mas ainda assim uma opção atraente (atualmente estou usando-o em dois aplicativos de produção não triviais sem problemas)
Se você precisar mudar os nomes das colunas, precisará criar um espaço reservado para evitar um erro duplicado no nome da coluna . Aqui está um exemplo:
class SwitchColumns < ActiveRecord::Migration
def change
rename_column :column_name, :x, :holder
rename_column :column_name, :y, :x
rename_column :column_name, :holder, :y
end
end
Se os dados atuais não forem importantes para você, você pode simplesmente cancelar sua migração original usando:
rake db:migrate:down VERSION='YOUR MIGRATION FILE VERSION HERE'
Sem as aspas, faça as alterações na migração original e execute a migração novamente novamente:
rake db:migrate
Para Ruby on Rails 4:
def change
rename_column :table_name, :column_name_old, :column_name_new
end
Manualmente, podemos usar o método abaixo:
Podemos editar a migração manualmente como:
Aberto app/db/migrate/xxxxxxxxx_migration_file.rb
Atualizar hased_password
parahashed_password
Execute o comando abaixo
$> rake db:migrate:down VERSION=xxxxxxxxx
Em seguida, ele removerá sua migração:
$> rake db:migrate:up VERSION=xxxxxxxxx
Ele adicionará sua migração com a alteração atualizada.
Executar rails g migration ChangesNameInUsers
(ou o que você quiser nomear)
Abra o arquivo de migração que acabou de ser gerado e adicione esta linha no método (entre def change
e end
):
rename_column :table_name, :the_name_you_want_to_change, :the_new_name
Salve o arquivo e execute rake db:migrate
no console
Verifique o seu schema.db
para ver se o nome realmente mudou no banco de dados!
Espero que isto ajude :)
Vamos BEIJAR . Só é preciso três etapas simples. O seguinte funciona para o Rails 5.2 .
rails g migration RenameNameToFullNameInStudents
rails g RenameOldFieldToNewFieldInTableName
- dessa forma, é perfeitamente claro para os mantenedores da base de código posteriormente. (use um plural para o nome da tabela).
# I prefer to explicitly write the
de cima and
para baixomethods.
# ./db/migrate/20190114045137_rename_name_to_full_name_in_students.rb
class RenameNameToFullNameInStudents < ActiveRecord::Migration[5.2]
def up
# rename_column :table_name, :old_column, :new_column
rename_column :students, :name, :full_name
end
def down
# Note that the columns are reversed
rename_column :students, :full_name, :name
end
end
rake db:migrate
E você está pronto para as corridas!
$: rails g migration RenameHashedPasswordColumn
invoke active_record
create db/migrate/20160323054656_rename_hashed_password_column.rb
Abra esse arquivo de migração e modifique-o conforme abaixo (Digite o original table_name
)
class RenameHashedPasswordColumn < ActiveRecord::Migration
def change
rename_column :table_name, :hased_password, :hashed_password
end
end
Abra seu console do Ruby on Rails e digite:
ActiveRecord::Migration.rename_column :tablename, :old_column, :new_column
Você tem duas maneiras de fazer isso:
Nesse tipo, ele executa automaticamente o código reverso, quando é revertido.
def change
rename_column :table_name, :old_column_name, :new_column_name
end
Para esse tipo, ele executa o método up quando rake db:migrate
e o método down quando rake db:rollback
:
def self.up
rename_column :table_name, :old_column_name, :new_column_name
end
def self.down
rename_column :table_name,:new_column_name,:old_column_name
end
Estou no Rails 5.2 e tentando renomear uma coluna em um usuário ideal.
o rename_column
bit funcionou para mim, mas o singular :table_name
lançou um erro "Tabela do usuário não encontrada". Plural funcionou para mim.
rails g RenameAgentinUser
Altere o arquivo de migração para este:
rename_column :users, :agent?, :agent
Onde: agente? é o nome da coluna antiga.
Atualização - Um primo próximo de create_table é change_table, usado para alterar as tabelas existentes. É usado de maneira semelhante ao create_table, mas o objeto cedido ao bloco conhece mais truques. Por exemplo:
class ChangeBadColumnNames < ActiveRecord::Migration
def change
change_table :your_table_name do |t|
t.rename :old_column_name, :new_column_name
end
end
end
Dessa forma, é mais eficiente se o fizermos com outros métodos alter, como: remover / adicionar índice / remover índice / adicionar coluna, por exemplo, podemos fazer outros procedimentos:
# Rename
t.rename :old_column_name, :new_column_name
# Add column
t.string :new_column
# Remove column
t.remove :removing_column
# Index column
t.index :indexing_column
#...
Apenas gere a migração usando o comando
rails g migration rename_hased_password
Depois disso, edite a migração, adicione a seguinte linha no método de alteração
rename_column :table, :hased_password, :hashed_password
Isso deve fazer o truque.
Mudanças na migração do Rails 5
por exemplo:
modelo rails g Student student_name: string age: integer
se você deseja alterar a coluna student_name como nome
Nota: - se você não executar o Rails db: migrate
Você pode seguir os seguintes passos
modelo rails d Aluno student_name: string age: integer
Isso removerá o arquivo de migração gerado. Agora você pode corrigir o nome da sua coluna
modelo rails g Nome do aluno: string age: integer
Se você migrou (rails db: migrate), siga as opções para alterar o nome da coluna
migração rails g RemoveStudentNameFromStudent student_name: string
trilhos g migração AddNameToStudent name: string
rails g migration RemoveStudentNameFromStudentS student_name:string
(os alunos são plurais)?