2009-01-23 20 views
360

Tôi khủng khiếp khi đặt tên và nhận ra rằng có một bộ tên tốt hơn cho các mô hình của tôi trong ứng dụng Rails của tôi.
Có cách nào để sử dụng di chuyển để đổi tên mô hình và bảng tương ứng của nó không?Làm thế nào để bạn viết di chuyển để đổi tên mô hình ActiveRecord và bảng của nó trong Rails?

+9

Tôi đã đề xuất thêm "ActiveRecord" vào câu hỏi này để cải thiện các kết quả của công cụ tìm kiếm. Tôi đã tìm kiếm điều này bằng cách sử dụng "bảng đổi tên ActiveRecord". –

+5

Nếu bạn đang sử dụng di chuyển, vấn đề này là phức tạp hơn có vẻ như. Giải pháp được chọn nói để quay lại và đổi tên thủ công mô hình, bộ điều khiển, v.v. sau khi bạn đã thay đổi tên bảng. Nếu bạn làm điều này, tất cả các di chuyển cũ hơn tham chiếu đến mô hình của bạn theo tên cũ của nó sẽ thất bại. Vì vậy, khi ai đó nhân bản repo của bạn và cố gắng chạy 'rake db: migrate', nó sẽ thất bại. Bạn có thể quay lại và thay đổi những tên đó trong quá trình di chuyển, nhưng điều đó sẽ trở nên lộn xộn. Bạn có thể tốt hơn là chỉ cần tạo một mô hình hoàn toàn mới thay vì đổi tên nó. – andrew

+4

@andrewhannigan: Không phải điểm của bạn là tranh luận nếu ai đó nhân bản repo của bạn và chỉ chạy 'rake db: schema: load'? – istrasci

Trả lời

518

Dưới đây là một ví dụ:

class RenameOldTableToNewTable < ActiveRecord::Migration 
    def self.up 
    rename_table :old_table_name, :new_table_name 
    end 

    def self.down 
    rename_table :new_table_name, :old_table_name 
    end 
end 

tôi phải đi và đổi tên các tập tin khai mô hình bằng tay.

Edit:

Trong Rails 3.1 & 4, ActiveRecord::Migration::CommandRecorder biết làm thế nào để đảo ngược sự di cư của rename_table, vì vậy bạn có thể làm điều này:

class RenameOldTableToNewTable < ActiveRecord::Migration 
    def change 
    rename_table :old_table_name, :new_table_name 
    end 
end 

(Bạn vẫn phải đi qua và tự đổi tên của bạn tệp.)

+0

Có nhưng điều này không thay đổi tên của mô hình, phải không? – ryeguy

+0

nó chỉ thay đổi tên bảng. –

+0

Điều này có nghĩa là bạn phải đổi tên Bộ điều khiển và Xem các thư mục/tập tin theo cách thủ công không? Tất cả những thứ đó có phải đổi tên theo cách thủ công không? – user5243421

39

Các câu trả lời và nhận xét khác bao gồm đổi tên bảng, đổi tên tệp và grepping thông qua mã của bạn.

Tôi muốn thêm một vài hãy cẩn thận hơn:

Hãy sử dụng một ví dụ thực tế tôi phải đối mặt ngày hôm nay: đổi tên một mô hình từ 'Merchant' thành 'Doanh nghiệp.'

  • Đừng quên thay đổi tên của các bảng và mô hình phụ thuộc trong cùng một di chuyển. Tôi đã thay đổi mô hình Merchant và MerchantStat của mình thành Business và BusinessStat cùng một lúc. Nếu không tôi đã phải làm theo cách quá nhiều chọn và chọn khi thực hiện tìm kiếm và thay thế.
  • Đối với bất kỳ mô hình nào khác phụ thuộc vào kiểu máy của bạn thông qua khóa ngoài, tên cột ngoài của bảng khác sẽ được lấy từ tên kiểu gốc của bạn. Vì vậy, bạn cũng sẽ muốn thực hiện một số cuộc gọi rename_column trên các mô hình phụ thuộc này. Ví dụ, tôi đã phải đổi tên cột 'merchant_id' thành 'business_id' trong các bảng nối khác nhau (cho mối quan hệ has_and_belongs_to_many) và các bảng phụ thuộc khác (đối với các mối quan hệ has_one và has_many bình thường). Nếu không, tôi đã kết thúc với các cột như 'business_stat.merchant_id' trỏ đến 'business.id'. Here's a good answer about doing column renames.
  • Khi truy cập, hãy nhớ tìm kiếm số ít, số nhiều, viết hoa, chữ thường và thậm chí là các phiên bản UPPERCASE (có thể xuất hiện trong nhận xét) của chuỗi của bạn.
  • Tốt nhất là nên tìm kiếm các phiên bản số nhiều trước, sau đó là số ít. Cách nếu bạn có số nhiều bất thường - chẳng hạn như trong các thương gia của tôi :: ví dụ về doanh nghiệp - bạn có thể nhận được tất cả các số nhiều bất thường chính xác. Nếu không, bạn có thể kết thúc bằng, ví dụ: 'doanh nghiệp' (3 s) là trạng thái trung gian , dẫn đến tìm kiếm và thay thế nhiều hơn.
  • Không được thay thế một cách mù quáng mọi lần xuất hiện. Nếu tên mô hình của bạn va chạm với thuật ngữ lập trình phổ biến, với các giá trị trong các mô hình khác hoặc với nội dung văn bản trong chế độ xem của bạn, bạn có thể sẽ quá quá háo hức. Trong ví dụ của tôi, tôi muốn thay đổi tên kiểu của mình thành 'Doanh nghiệp' nhưng vẫn gọi họ là 'người bán' trong nội dung trong giao diện người dùng của tôi. Tôi cũng có vai trò 'thương gia' cho người dùng ở CanCan - đó là sự nhầm lẫn giữa vai trò người bán và mô hình Merchant khiến tôi đổi tên mô hình ngay từ đầu.
21

Bạn cũng cần phải thay thế các chỉ số của bạn:

class RenameOldTableToNewTable< ActiveRecord:Migration 
    def self.up 
    remove_index :old_table_name, :column_name 
    rename_table :old_table_name, :new_table_name 
    add_index :new_table_name, :column_name 
    end 

    def self.down 
    remove_index :new_table_name, :column_name 
    rename_table :new_table_name, :old_table_name 
    add_index :old_table_name, :column_name 
    end 
end 

Và đổi tên tập tin của bạn vv, thủ công như câu trả lời khác ở đây mô tả.

Xem: http://api.rubyonrails.org/classes/ActiveRecord/Migration.html

Hãy chắc chắn rằng bạn có thể rollback và cuộn về phía trước sau khi bạn viết di cư này. Nó có thể trở nên khó khăn nếu bạn nhận được một cái gì đó sai và gặp khó khăn với một di cư cố gắng để có hiệu lực một cái gì đó mà không còn tồn tại. Tốt nhất là thùng rác toàn bộ cơ sở dữ liệu và bắt đầu lại nếu bạn không thể quay trở lại. Vì vậy, hãy lưu ý rằng bạn có thể cần phải sao lưu thứ gì đó.

Ngoài ra: hãy kiểm tra schema_db cho bất kỳ tên cột có liên quan nào trong các bảng khác được xác định bởi has_ ​​hoặc attribute_to hoặc một cái gì đó. Có thể bạn cũng sẽ cần phải chỉnh sửa chúng.

Và cuối cùng, làm điều này mà không có bộ kiểm tra hồi quy sẽ là các loại hạt.

+9

Đối với việc di chuyển đường ray 4.0.0.beta1, không cần cập nhật chỉ mục theo cách thủ công. AR tự cập nhật nó. – freemanoid

54

Trong Rails 4 tất cả tôi phải làm là thay đổi def

def change 
    rename_table :old_table_name, :new_table_name 
end 

Và tất cả các chỉ số của tôi đã được đưa về chăm sóc cho tôi. Tôi không cần cập nhật các chỉ mục theo cách thủ công bằng cách xóa các chỉ mục cũ và thêm các chỉ mục mới.

Và tính năng này cũng hoạt động bằng cách sử dụng thay đổi để tăng hoặc giảm liên quan đến các chỉ mục.

Các vấn đề liên quan