Xây dựng ứng dụng Rails với cơ sở dữ liệu sẵn có
Không phải tất cả các ứng dụng đều được bắt đầu từ đầu, đôi khi bạn phải bắt đầu với một cơ sở dữ liệu có sẵn. Xây dựng ứng dụng Rails theo chuẩn như chúng ta được biết thực sự dễ dàng, và có một nhận thức rằng ra khỏi con đường đó là vô cùng khó khăn. Nhận thức ấy không đúng. Nếu cơ sở dữ liệu ...
Không phải tất cả các ứng dụng đều được bắt đầu từ đầu, đôi khi bạn phải bắt đầu với một cơ sở dữ liệu có sẵn. Xây dựng ứng dụng Rails theo chuẩn như chúng ta được biết thực sự dễ dàng, và có một nhận thức rằng ra khỏi con đường đó là vô cùng khó khăn.
Nhận thức ấy không đúng. Nếu cơ sở dữ liệu của bạn được thiết kế tốt, nhưng không theo quy ước đặt tên của Rails, thật dễ dàng để làm cho chúng kết hợp được với nhau. Tuy nhiên, nếu cấu trúc dữ liệu của bạn không chuẩn thì thực sự không có nhiều điều để Rails có thể làm cho bạn.
Lý thuyết
Trong một ứng dụng được thiết kế theo chuẩn, ActiveRecord và cơ sở dữ liệu tương thích với nhau:
+---------------+ | Active Record | | | +---------------| | | | Database | +---------------+
Nhưng khi chúng không tương thích, chúng ta cần phải chèn một adapter. Có một vài lựa chọn để làm cho các thành phần của chúng tương thích với nhau.
Tuỳ chọn 1: Database Views
Nếu bạn sử dụng một hệ quản trị cơ sở dữ liệu mạnh, nó sẽ hỗ trợ tạo ra các Views. Các Views được thiết kế như 1 lớp phiên dịch cho dữ liệu của bạn. Từ bên ngoài, các ứng dụng Rails sẽ tương tác với Views và coi chúng như một bảng thực sự. Chúng ta đóng gói sự phức tạp ở tầng database và không cần sửa đổi gì ở ứng dụng Rails.
Bạn có thể thấy mô hình trên như sau
+---------------+ | Active Record | | | +---------------+ | Data Views | | ------------- | | Real Data | +---------------+
Đây là tuỳ chọn tốt nhất trong các trường hợp:
- Ứng dụng Rails là ứng dụng duy nhất sử dụng cơ sở dữ liệu đó
- Cơ sở dữ liệu có thể thay đổi, thiết kế lại để phù hợp với quy tắc của Rails
- Bạn có một hệ quản trị cơ sở dữ liệu đầy đủ chức năng tiên tiến
- Hiệu suất của cơ sở dữ liệu không phải là một trở ngại lớn (thông thường thì nó lại không phải như vậy)
Tuỳ chọn 2: Overriding Defaults
Việc tạo ra các View không phải khi nào cũng thực hiện được, ví dụ trong các trường hợp:
- Bạn chỉ muốn ghi đè một cài tên cột, tên bảng,... - không thay đổi cấu trúc quan trọng
- Bạn không có quyền truy cập/điều khiển cấu trúc bên trong của cơ sở dữ liệu
- Bạn không thực sự tự tin với SQL
Trong trường hợp đó, tuỳ chọn thích hợp nhất của bạn là để ActiveRecord xử lý việc biên dịch này:
+---------------+ | Active Record | | ------------- | | AR Overrides | +---------------+ | | | Database | +---------------+
Giả sử cấu trúc cơ sở dữ liệu của chúng ta là tốt nhưng không theo quy ước của Rails, các ghi đè điển hình bao gồm:
- Ghi đè tên bảng
- Ghi đè tên khoá chính
- Ghi đè tên khoá ngoại
Xác định tên bảng
Giả định chúng ta có một model là Customer. Theo mặc định, Rails sẽ lưu dữ liệu trong một bảng tên là customers, nhưng thực tế dữ liệu lại được lưu trong bảng tên là existing_customers. Để thực hiện việc ghi đè, chúng ta chỉ cần thêm code trong model Customer như sau:
class Customer < ActiveRecord::Base set_table_name 'existing_customers' set_primary_key 'customer_id' end
Như vậy là đủ, không có gì khác trong mô hình hoặc ứng dụng cần thay đổi.
Xác định khoá chính
Giả định bảng existing_customers không sử dụng khoá chính là id, thay vào đó lại dùng customer_id. Không vấn đề:
class Customer < ActiveRecord::Base set_table_name 'existing_customers' set_primary_key 'customer_id' end
Khoá ngoại
Vậy còn quan hệ giữa các model thì sao? Giả định có một model là Order có quan hệ với model Customer là Customer has_many Orders. Thông thường, Rails thường thêm vào bảng orders một cột là customer_id, nhưng trong trường hợp này, cơ sở dữ liệu của chúng ta lại là existing_customer_id:
class Customer < ActiveRecord::Base set_table_name 'existing_customers' set_primary_key 'customer_id' has_many :orders, foreign_key: 'existing_customer_id' end
Và chúng ta làm tương tự trong model Order:
class Order < ActiveRecord::Base belongs_to :customer, foreign_key: 'existing_customer_id' end
Các mô hình tương tự được áp dụng cho quan hệ has_one /belong_to.
Như vậy chúng ta đã tìm hiểu qua một vài cách để có thể xây dựng ứng dụng Rails với 1 cơ sở dữ liệu sẵn có. Có 1 vài cách khác nữa xong yêu cầu kỹ năng cao hơn về SQL hoặc ít khả thi hơn nên chưa được trình bày ở đây. Hy vọng bài viết sẽ giúp ích cho các bạn trong quá trình tìm hiểu về Ruby on Rails.