Saya salah menyebutkan kolom, hased_password
bukan hashed_password
.
Bagaimana cara saya memperbarui skema database, menggunakan migrasi untuk mengganti nama kolom ini?
Saya salah menyebutkan kolom, hased_password
bukan hashed_password
.
Bagaimana cara saya memperbarui skema database, menggunakan migrasi untuk mengganti nama kolom ini?
Jawaban:
rename_column :table, :old_column, :new_column
Anda mungkin ingin membuat migrasi terpisah untuk melakukan ini. (Ganti nama FixColumnName
sesuai keinginan Anda.):
script/generate migration FixColumnName
# creates db/migrate/xxxxxxxxxx_fix_column_name.rb
Kemudian edit migrasi untuk melakukan keinginan Anda:
# 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
Untuk Rails 3.1 gunakan:
Sementara, up
dan down
metode masih berlaku, Rails 3.1 menerima change
metode yang "tahu cara memigrasi database Anda dan membalikkannya ketika migrasi dibatalkan tanpa perlu menulis metode turun terpisah".
Lihat " Migrasi Rekaman Aktif " untuk informasi lebih lanjut.
rails g migration FixColumnName
class FixColumnName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
Jika Anda kebetulan memiliki banyak kolom untuk diganti nama, atau sesuatu yang harus mengulangi nama tabel berulang-ulang:
rename_column :table_name, :old_column1, :new_column1
rename_column :table_name, :old_column2, :new_column2
...
Anda bisa menggunakan change_table
untuk menjaga hal-hal sedikit lebih rapi:
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
Kemudian db:migrate
seperti biasa atau bagaimanapun Anda menjalankan bisnis Anda.
Untuk Rails 4:
Saat membuat Migration
untuk mengganti nama kolom, Rails 4 menghasilkan change
metode, bukan up
dan down
seperti yang disebutkan di bagian di atas. change
Metode yang dihasilkan adalah:
$ > rails g migration ChangeColumnName
yang akan membuat file migrasi mirip dengan:
class ChangeColumnName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
self.up
saya tidak akan mengatakan self.down
"harus selalu berlawanan". Masuk tergantung pada konteks migrasi Anda. Hanya menempatkan "lawan" mungkin bukan "kanan" migrasi bawah.
def self.up
dan def self.down
dengan def change
dan itu akan tahu cara mengembalikan.
change
metode ini bukan bukti lengkap, jadi cenderung menggunakan up
dan down
metode untuk migrasi kompleks.
Menurut pendapat saya, dalam hal ini, lebih baik digunakan rake db:rollback
, lalu edit migrasi Anda dan jalankan kembali rake db:migrate
.
Namun, jika Anda memiliki data di kolom yang tidak ingin hilang, gunakan rename_column
.
Jika kolom sudah diisi dengan data dan hidup dalam produksi, saya akan merekomendasikan pendekatan langkah demi langkah, untuk menghindari downtime dalam produksi sambil menunggu migrasi.
Pertama saya akan membuat migrasi db untuk menambahkan kolom dengan nama baru dan mengisinya dengan nilai-nilai dari nama kolom yang lama.
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
Lalu saya akan melakukan perubahan itu saja, dan mendorong perubahan ke dalam produksi.
git commit -m 'adding columns with correct name'
Kemudian begitu komit telah didorong ke dalam produksi, saya akan lari.
Production $ bundle exec rake db:migrate
Lalu saya akan memperbarui semua tampilan / pengontrol yang merujuk nama kolom lama ke nama kolom baru. Jalankan melalui test suite saya, dan lakukan hanya perubahan itu. (Setelah memastikan itu berfungsi secara lokal dan melewati semua tes terlebih dahulu!)
git commit -m 'using correct column name instead of old stinky bad column name'
Lalu saya akan mendorong komitmen itu untuk produksi.
Pada titik ini Anda dapat menghapus kolom asli tanpa khawatir tentang segala jenis downtime yang terkait dengan migrasi itu sendiri.
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
Kemudian dorong migrasi terbaru ini ke produksi dan berjalan bundle exec rake db:migrate
di latar belakang.
Saya menyadari ini sedikit lebih terlibat dalam suatu proses, tetapi saya lebih suka melakukan ini daripada memiliki masalah dengan migrasi produksi saya.
execute "Update table_name set correct_name_column_one = old_name_column_one"
http://api.rubyonrails.org/classes/ActiveRecord/Migration.html
Dibawah Available Transformations
rename_column(table_name, column_name, new_column_name):
Mengganti nama kolom tetapi menyimpan tipe dan kontennya.
rename_column
.
Jalankan perintah di bawah ini untuk membuat file migrasi:
rails g migration ChangeHasedPasswordToHashedPassword
Kemudian pada file yang dihasilkan di db/migrate
folder, tulis rename_column
seperti di bawah ini:
class ChangeOldCoulmnToNewColumn < ActiveRecord::Migration
def change
rename_column :table_name, :hased_password, :hashed_password
end
end
Beberapa versi Ruby on Rails mendukung metode naik / turun untuk migrasi dan jika Anda memiliki metode naik / turun dalam migrasi Anda, maka:
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
Jika Anda memiliki change
metode dalam migrasi Anda, maka:
def change
rename_column :table_name, :column_old_name, :column_new_name
end
Untuk informasi lebih lanjut, Anda dapat memindahkan: Ruby on Rails - Migrations atau Migrasi Rekaman Aktif .
Jika kode Anda tidak dibagikan dengan yang lain, maka opsi terbaik adalah dengan hanya rake db:rollback
mengedit nama kolom Anda dalam migrasi dan rake db:migrate
. Itu dia
Dan Anda dapat menulis migrasi lain untuk mengganti nama kolom
def change
rename_column :table_name, :old_name, :new_name
end
Itu dia.
rake db:rollback
adalah saran yang bagus. Tapi seperti yang Anda katakan, hanya jika migrasi belum didorong.
Sebagai opsi alternatif, jika Anda belum menikah dengan ide migrasi, ada permata yang menarik untuk ActiveRecord yang akan menangani perubahan nama secara otomatis untuk Anda, gaya Datamapper. Yang Anda lakukan hanyalah mengubah nama kolom pada model Anda (dan pastikan Anda meletakkan Model.auto_upgrade! Di bagian bawah model.rb Anda) dan biola! Database diperbarui dengan cepat.
https://github.com/DAddYE/mini_record
Catatan: Anda perlu nuke db / schema.rb untuk mencegah konflik
Masih dalam fase beta dan jelas bukan untuk semua orang tetapi masih merupakan pilihan yang menarik (saya saat ini menggunakannya dalam dua aplikasi produksi non-sepele tanpa masalah)
Jika Anda perlu mengganti nama kolom, Anda harus membuat placeholder untuk menghindari kesalahan nama kolom duplikat . Ini sebuah contoh:
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
Jika data saat ini tidak penting bagi Anda, Anda bisa menghapus migrasi asli menggunakan:
rake db:migrate:down VERSION='YOUR MIGRATION FILE VERSION HERE'
Tanpa tanda kutip, lalu buat perubahan dalam migrasi asli dan jalankan migrasi lagi dengan:
rake db:migrate
Untuk Ruby on Rails 4:
def change
rename_column :table_name, :column_name_old, :column_name_new
end
Secara manual kita dapat menggunakan metode di bawah ini:
Kami dapat mengedit migrasi secara manual seperti:
Buka app/db/migrate/xxxxxxxxx_migration_file.rb
Perbarui hased_password
kehashed_password
Jalankan perintah di bawah ini
$> rake db:migrate:down VERSION=xxxxxxxxx
Maka itu akan menghapus migrasi Anda:
$> rake db:migrate:up VERSION=xxxxxxxxx
Itu akan menambah migrasi Anda dengan perubahan yang diperbarui.
Lari rails g migration ChangesNameInUsers
(atau apa pun yang ingin Anda beri nama)
Buka file migrasi yang baru saja dibuat, dan tambahkan baris ini dalam metode (di antara def change
dan end
):
rename_column :table_name, :the_name_you_want_to_change, :the_new_name
Simpan file, dan jalankan rake db:migrate
di konsol
Periksa Anda schema.db
untuk melihat apakah nama itu benar-benar telah berubah dalam database!
Semoga ini membantu :)
Mari kita Kiss . Yang diperlukan hanyalah tiga langkah sederhana. Berikut ini berfungsi untuk Rails 5.2 .
rails g migration RenameNameToFullNameInStudents
rails g RenameOldFieldToNewFieldInTableName
- dengan begitu sangat jelas bagi pengelola basis kode nanti. (gunakan jamak untuk nama tabel).
# I prefer to explicitly write the
naik and
ke bawahmethods.
# ./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
Dan Anda pergi ke balapan!
$: rails g migration RenameHashedPasswordColumn
invoke active_record
create db/migrate/20160323054656_rename_hashed_password_column.rb
Buka file migrasi itu dan modifikasi file itu seperti di bawah ini (Masukkan yang asli table_name
)
class RenameHashedPasswordColumn < ActiveRecord::Migration
def change
rename_column :table_name, :hased_password, :hashed_password
end
end
Buka konsol Ruby on Rails Anda dan masukkan:
ActiveRecord::Migration.rename_column :tablename, :old_column, :new_column
Anda memiliki dua cara untuk melakukan ini:
Dalam jenis ini secara otomatis menjalankan kode sebaliknya, ketika rollback.
def change
rename_column :table_name, :old_column_name, :new_column_name
end
Untuk jenis ini, ia menjalankan metode naik kapan rake db:migrate
dan menjalankan metode turun ketika 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
Saya di kereta 5.2, dan mencoba mengubah nama kolom pada Pengguna yang dirancang.
yang rename_column
sedikit bekerja untuk saya, tapi bentuk tunggal :table_name
melemparkan "meja Pengguna tidak ditemukan" kesalahan. Plural bekerja untuk saya.
rails g RenameAgentinUser
Kemudian ubah file migrasi ke ini:
rename_column :users, :agent?, :agent
Di mana: agen? adalah nama kolom yang lama.
Pembaruan - Sepupu dekat create_table adalah change_table, digunakan untuk mengubah tabel yang ada. Ini digunakan dengan cara yang mirip dengan create_table tetapi objek yang dihasilkan blok tahu lebih banyak trik. Sebagai contoh:
class ChangeBadColumnNames < ActiveRecord::Migration
def change
change_table :your_table_name do |t|
t.rename :old_column_name, :new_column_name
end
end
end
Cara ini lebih efisien jika kita lakukan dengan metode alter lain seperti: hapus / tambah indeks / hapus indeks / tambahkan kolom, misalnya kita dapat melakukan lebih lanjut seperti:
# 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
#...
Hasilkan migrasi menggunakan perintah saja
rails g migration rename_hased_password
Setelah itu edit migrasi tambahkan baris berikut dalam metode perubahan
rename_column :table, :hased_password, :hashed_password
Ini harus melakukan trik.
Perubahan migrasi Rails 5
misalnya:
rails g model Student_name student: usia string: integer
jika Anda ingin mengubah kolom student_name sebagai nama
Catatan: - jika Anda tidak menjalankan rails db: migrate
Anda bisa melakukan langkah-langkah berikut
rails d model Student_name student: usia string: integer
Ini akan menghapus file migrasi yang dihasilkan, Sekarang Anda dapat memperbaiki nama kolom Anda
rails g model Nama siswa: usia string: integer
Jika Anda bermigrasi (rails db: migrate), opsi berikut untuk mengubah nama kolom
rails g migrasi RemoveStudentNameFromStudent student_name: string
rel g migrasi AddNameToStudent name: string
rails g migration RemoveStudentNameFromStudentS student_name:string
(para siswa jamak)?