Tôi đặt tên sai một cột hased_password
thay vì hashed_password
.
Làm cách nào để cập nhật lược đồ cơ sở dữ liệu, sử dụng di chuyển để đổi tên cột này?
Tôi đặt tên sai một cột hased_password
thay vì hashed_password
.
Làm cách nào để cập nhật lược đồ cơ sở dữ liệu, sử dụng di chuyển để đổi tên cột này?
Câu trả lời:
rename_column :table, :old_column, :new_column
Có lẽ bạn sẽ muốn tạo một di chuyển riêng để làm điều này. (Đổi tên FixColumnName
như bạn muốn.):
script/generate migration FixColumnName
# creates db/migrate/xxxxxxxxxx_fix_column_name.rb
Sau đó chỉnh sửa di chuyển để làm theo ý của bạn:
# 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
Đối với Rails 3.1 sử dụng:
Mặc dù, up
và down
các phương thức vẫn được áp dụng, Rails 3.1 nhận được một change
phương thức "biết cách di chuyển cơ sở dữ liệu của bạn và đảo ngược nó khi di chuyển được khôi phục mà không cần phải viết một phương thức riêng biệt".
Xem " Di chuyển bản ghi hoạt động " để biết thêm thông tin.
rails g migration FixColumnName
class FixColumnName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
Nếu bạn tình cờ có một loạt các cột để đổi tên hoặc một cái gì đó sẽ phải lặp đi lặp lại tên bảng nhiều lần:
rename_column :table_name, :old_column1, :new_column1
rename_column :table_name, :old_column2, :new_column2
...
Bạn có thể sử dụng change_table
để giữ mọi thứ gọn gàng hơn:
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
Sau đó, db:migrate
như thường lệ hoặc tuy nhiên bạn đi về doanh nghiệp của bạn.
Đối với đường ray 4:
Trong khi tạo một Migration
để đổi tên một cột, Rails 4 tạo ra một change
phương thức thay vì up
và down
như đã đề cập trong phần trên. change
Phương thức được tạo là:
$ > rails g migration ChangeColumnName
sẽ tạo một tệp di chuyển tương tự như:
class ChangeColumnName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
self.up
tôi sẽ không nói self.down
"nên luôn luôn ngược lại". Trong tùy thuộc vào bối cảnh di chuyển của bạn. Chỉ cần đặt "đối diện" có thể không phải là "di chuyển" xuống.
def self.up
và def self.down
bằng def change
và nó sẽ biết cách khôi phục.
change
phương pháp này không đầy đủ bằng chứng, vì vậy có xu hướng sử dụng up
và down
phương pháp cho việc di chuyển phức tạp.
Theo tôi, trong trường hợp này, tốt hơn là sử dụng rake db:rollback
, sau đó chỉnh sửa di chuyển của bạn và chạy lại rake db:migrate
.
Tuy nhiên, nếu bạn có dữ liệu trong cột mà bạn không muốn mất thì hãy sử dụng rename_column
.
Nếu cột đã được điền dữ liệu và sống trong sản xuất, tôi khuyên bạn nên thực hiện từng bước một để tránh thời gian ngừng sản xuất trong khi chờ di chuyển.
Trước tiên tôi sẽ tạo một di chuyển db để thêm các cột có (các) tên mới và điền chúng với các giá trị từ tên cột cũ.
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
Sau đó, tôi cam kết thay đổi đó và đẩy sự thay đổi vào sản xuất.
git commit -m 'adding columns with correct name'
Sau đó, một khi cam kết đã được đưa vào sản xuất, tôi sẽ chạy.
Production $ bundle exec rake db:migrate
Sau đó, tôi sẽ cập nhật tất cả các chế độ xem / bộ điều khiển đã tham chiếu tên cột cũ thành tên cột mới. Chạy qua bộ thử nghiệm của tôi và cam kết chỉ những thay đổi đó. (Sau khi chắc chắn rằng nó hoạt động tại địa phương và vượt qua tất cả các bài kiểm tra trước!)
git commit -m 'using correct column name instead of old stinky bad column name'
Sau đó, tôi sẽ thúc đẩy cam kết sản xuất.
Tại thời điểm này, bạn có thể xóa cột ban đầu mà không phải lo lắng về bất kỳ loại thời gian chết nào liên quan đến việc di chuyển.
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
Sau đó đẩy di chuyển mới nhất này vào sản xuất và chạy bundle exec rake db:migrate
trong nền.
Tôi nhận ra rằng đây là một quá trình liên quan nhiều hơn một chút, nhưng tôi muốn làm điều này hơn là có vấn đề với việc di chuyển sản xuất của tôi.
execute "Update table_name set correct_name_column_one = old_name_column_one"
http://api.rubyonrails.org/groupes/ActiveRecord/Migration.html
Dưới Available Transformations
rename_column(table_name, column_name, new_column_name):
Đổi tên một cột nhưng vẫn giữ loại và nội dung.
rename_column
.
Chạy lệnh dưới đây để tạo tệp di chuyển:
rails g migration ChangeHasedPasswordToHashedPassword
Sau đó, trong tệp được tạo trong db/migrate
thư mục, viết rename_column
như dưới đây:
class ChangeOldCoulmnToNewColumn < ActiveRecord::Migration
def change
rename_column :table_name, :hased_password, :hashed_password
end
end
Một số phiên bản của Ruby on Rails hỗ trợ phương pháp lên / xuống để di chuyển và nếu bạn có phương pháp lên / xuống trong quá trình di chuyển của mình thì:
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
Nếu bạn có change
phương thức trong di chuyển của mình, thì:
def change
rename_column :table_name, :column_old_name, :column_new_name
end
Để biết thêm thông tin, bạn có thể di chuyển: Ruby on Rails - Di chuyển hoặc Di chuyển bản ghi hoạt động .
Nếu mã của bạn không được chia sẻ với mã khác, thì tùy chọn tốt nhất là chỉ cần rake db:rollback
chỉnh sửa tên cột của bạn khi di chuyển vàrake db:migrate
. Đó là nó
Và bạn có thể viết một di chuyển khác để đổi tên cột
def change
rename_column :table_name, :old_name, :new_name
end
Đó là nó.
rake db:rollback
là một gợi ý tuyệt vời. Nhưng như bạn đã nói, chỉ khi di chuyển chưa được đẩy.
Là một lựa chọn thay thế, nếu bạn chưa kết hôn với ý tưởng di chuyển, có một viên ngọc hấp dẫn cho ActiveRecord sẽ tự động xử lý các thay đổi tên cho bạn, theo kiểu Datamapper. Tất cả những gì bạn làm là thay đổi tên cột trong mô hình của bạn (và đảm bảo bạn đặt Model.auto_upTHER! Ở cuối mô hình của bạn.rb) và viola! Cơ sở dữ liệu được cập nhật nhanh chóng.
https://github.com/DAddYE/mini_record
Lưu ý: Bạn sẽ cần nuke db / lược đồ.rb để ngăn xung đột
Vẫn trong giai đoạn beta và rõ ràng không dành cho tất cả mọi người nhưng vẫn là một lựa chọn hấp dẫn (tôi hiện đang sử dụng nó trong hai ứng dụng sản xuất không tầm thường mà không có vấn đề gì)
Nếu bạn cần chuyển đổi tên cột, bạn sẽ cần tạo một trình giữ chỗ để tránh lỗi tên cột trùng lặp . Đây là một ví dụ:
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
Nếu dữ liệu hiện tại không quan trọng đối với bạn, bạn có thể gỡ bỏ di chuyển ban đầu của mình bằng cách sử dụng:
rake db:migrate:down VERSION='YOUR MIGRATION FILE VERSION HERE'
Nếu không có dấu ngoặc kép, sau đó thực hiện thay đổi trong di chuyển ban đầu và chạy lại di chuyển lên bằng cách:
rake db:migrate
Dành cho Ruby trên Rails 4:
def change
rename_column :table_name, :column_name_old, :column_name_new
end
Thủ công chúng ta có thể sử dụng phương pháp dưới đây:
Chúng tôi có thể chỉnh sửa di chuyển theo cách thủ công như:
Mở app/db/migrate/xxxxxxxxx_migration_file.rb
Cập nhật hased_password
lênhashed_password
Chạy lệnh dưới đây
$> rake db:migrate:down VERSION=xxxxxxxxx
Sau đó, nó sẽ xóa di chuyển của bạn:
$> rake db:migrate:up VERSION=xxxxxxxxx
Nó sẽ thêm di chuyển của bạn với sự thay đổi được cập nhật.
Chạy rails g migration ChangesNameInUsers
(hoặc bất cứ điều gì bạn muốn đặt tên cho nó)
Mở tệp di chuyển vừa được tạo và thêm dòng này vào phương thức (ở giữa def change
và end
):
rename_column :table_name, :the_name_you_want_to_change, :the_new_name
Lưu tệp và chạy rake db:migrate
trong bảng điều khiển
Kiểm tra của bạn schema.db
để xem tên đã thực sự thay đổi trong cơ sở dữ liệu!
Hi vọng điêu nay co ich :)
Hãy KISS . Tất cả chỉ mất ba bước đơn giản. Các công việc sau đây cho Rails 5.2 .
rails g migration RenameNameToFullNameInStudents
rails g RenameOldFieldToNewFieldInTableName
- theo cách đó nó hoàn toàn rõ ràng đối với những người duy trì cơ sở mã sau này. (sử dụng số nhiều cho tên bảng).
# I prefer to explicitly write the
lên and
xuốngmethods.
# ./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
Và bạn đang đi đến các cuộc đua!
$: rails g migration RenameHashedPasswordColumn
invoke active_record
create db/migrate/20160323054656_rename_hashed_password_column.rb
Mở tệp di chuyển đó và sửa đổi tệp đó như dưới đây (Không nhập bản gốc của bạn table_name
)
class RenameHashedPasswordColumn < ActiveRecord::Migration
def change
rename_column :table_name, :hased_password, :hashed_password
end
end
Bạn có hai cách để làm điều này:
Trong loại này, nó tự động chạy mã ngược của nó, khi rollback.
def change
rename_column :table_name, :old_column_name, :new_column_name
end
Với kiểu này, nó chạy phương thức up khi rake db:migrate
và chạy phương thức down khi 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
Tôi đang trên đường ray 5.2 và đang cố đổi tên một cột trên Người dùng đã nghĩ ra.
các rename_column
chút làm việc cho tôi, nhưng số ít :table_name
ném một "bảng Người dùng không tìm thấy" lỗi. Số nhiều làm việc cho tôi.
rails g RenameAgentinUser
Sau đó thay đổi tệp di chuyển sang đây:
rename_column :users, :agent?, :agent
Ở đâu: đại lý? là tên cột cũ.
Cập nhật - Một người anh em họ thân của create_table là change_table, được sử dụng để thay đổi các bảng hiện có. Nó được sử dụng theo cách tương tự với created_table nhưng đối tượng mang lại cho khối biết nhiều thủ thuật hơn. Ví dụ:
class ChangeBadColumnNames < ActiveRecord::Migration
def change
change_table :your_table_name do |t|
t.rename :old_column_name, :new_column_name
end
end
end
Cách này hiệu quả hơn nếu chúng ta thực hiện với các phương thức thay đổi khác, chẳng hạn như: remove / add index / remove index / add cột, ví dụ: chúng ta có thể làm thêm như:
# 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
#...
Chỉ cần tạo di chuyển bằng lệnh
rails g migration rename_hased_password
Sau đó chỉnh sửa di chuyển thêm dòng sau trong phương thức thay đổi
rename_column :table, :hased_password, :hashed_password
Cái này cần phải dùng mẹo.
Rails 5 thay đổi di chuyển
ví dụ:
rails g model Student student_name: chuỗi age: số nguyên
nếu bạn muốn thay đổi cột student_name thành tên
Lưu ý: - nếu bạn không chạy rails db: di chuyển
Bạn có thể làm các bước sau
rails d model Student student_name: chuỗi age: số nguyên
Điều này sẽ xóa tệp di chuyển được tạo, Bây giờ bạn có thể sửa tên cột của mình
rails g model Tên sinh viên: chuỗi tuổi: số nguyên
Nếu bạn đã di chuyển (rails db: di chuyển), các tùy chọn sau để thay đổi tên cột
rails g di chuyển RemoveStudentNameFromStudent student_name: chuỗi
rails g di chuyển Tên AddNameToStudent: chuỗi
rails g migration RemoveStudentNameFromStudentS student_name:string
(các sinh viên là số nhiều)?