12/08/2018, 14:43

Tạo một liên kết nhiều-nhiều ActiveRecord trong Ruby on Rails với has_many: through và has_and_belongs_to_many

Một trở ngại thường gặp khi xây dựng các ứng dụng web là các cơ sở dữ liệu quan hệ. Nếu không có nó sẽ rất khó để giảm số lượng dữ liệu trùng lặp cũng như tăng hiệu quả cơ sở dữ liệu tổng thể. Các mối quan hệ phổ biến nhất là: một-một, một-nhiều và nhiều-nhiều. Rails cung cấp hai cách khác nhau để ...

Một trở ngại thường gặp khi xây dựng các ứng dụng web là các cơ sở dữ liệu quan hệ. Nếu không có nó sẽ rất khó để giảm số lượng dữ liệu trùng lặp cũng như tăng hiệu quả cơ sở dữ liệu tổng thể. Các mối quan hệ phổ biến nhất là: một-một, một-nhiều và nhiều-nhiều. Rails cung cấp hai cách khác nhau để khai báo một mối quan hệ nhiều-nhiều giữa các model. Cách đơn giản là sử dụng has_and_belongs_to_many, mà cho phép bạn tạo liên kết trực tiếp. Trong bài viết này mình sẽ giới thiệu qua việc tạo ra một mối quan hệ nhiều-nhiều với Ruby on Rails ActiveRecord, has_many: through và has_and_belongs_to_many . Ngoài ra, sự khác biệt cụ thể giữa hai sẽ được giới thiệu.

Bước đầu tiên để thực hiện một quan hệ has_many: through chạy rails generator model để tạo ra các model và các migrate file. Tiếp theo, chúng ta sẽ cần hình dung với những phương pháp liên kết Rails thích hợp để sử dụng. Phần này là dễ dàng hơn khi chúng phát biểu ra khi bạn tạo ra các sơ đồ cơ sở dữ liệu ban đầu.

  • "Một lập trình có nhiều dự án."
  • "Một khách hàng có nhiều dự án."
  • "Một dự án thuộc một lập trình."
  • "Một dự án thuộc về một khách hàng."
  • "Một lập trình có nhiều khách hàng thông qua một dự án."
  • "Một khách hàng có nhiều lập trình thông qua một dự án." Tạo một đối tượng Liệt kê các danh sách Activerecord

Một cách khác để tạo quan hệ nhiều-nhiều trong Rails, là sử dụng các liên kết hoặc has_and_belongs_to_many (HABTM cho ngắn). Thiết lập này là tương tự với những has_many: through. Sự chuyển đổi là khác, do đó bạn sẽ cần phải chắc chắn rằng bạn chạy lại cơ sở dữ liệu. Một trong những khác biệt đầu tiên nhận thấy là chúng ta không tạo ra một model cho bảng tham gia (dự án). has_and_belongs_to_many không yêu cầu bạn phải tạo ra một model cho bảng này.

Vì vậy, một lần nữa chúng ta cần phải tạo ra các quan hệ thích hợp trong model của chúng ta.Để dễ hình dung ta có thể xem phát biểu như sau:

  • "Một lập trình có nhiều khách hàng"
  • "Một Lập trình viên có thể thuộc về một khách hàng"
  • "Một khách hàng có nhiều lập trình viên"
  • "Một khách hàng có thể thuộc về một lập trình" Mô tả tương ứng với code Tạo một đối tượng Liệt kê các danh sách Activerecord Bây giờ, bạn có thể bạn sẽ tự hỏi "Tại sao ta lại sử dụng quan hệ has_many :through khi has_and_belongs_to_many: là dễ dàng hơn nhiều để thiết lập". Phần tiếp theo sẽ giải thích những nhược điểm của nó và tại sao thường sử dụng has_many: through là tốt nhất.

Validations

Hãy tưởng tượng bạn xây dựng một hệ thống với quan hệ HABTM . Một ngày khách hàng yêu cầu các bảng dự án phải luôn luôn có dữ liệu cho các trường hoặc nếu không nó sẽ là không hợp lệ. Với quan hệ HABTM không có một model để đặt mã xác nhận. Trong khi với has_many:through bạn có một model sẵn sàng để sử dụng mà sẽ cho phép bạn viết một cái gì đó như thế này:

chia sẻ hàm

Hơn nữa, giả sử rằng khách hàng này yêu cầu rằng bất cứ lúc nào ngày hết hạn của một của dự án là ít hơn so với ngày hiện tại mà hệ thống sẽ tự động thiết lập các dự án đóng cửa. Với một quan hệ HABTM bạn sẽ cần phải tạo ra một lớp hoặc có khả năng là một mối quan tâm đến gói chức năng này. Trong khi với has_many: through việc model có sẵn mang đến cho bạn một địa điểm hợp lý để viết các phương thức chia sẻ.

Dưới đây là một ví dụ về các phương thức chia sẻ khi xây dựng dựa trên model kiểm chứng như ví dụ trên: Không có bất cứ nơi nào để đặt mà không cần tạo nhiều tập tin với một quan hệ HABTM. Điều này cho đến nay là nhược điểm lớn nhất. has_many:through mặt khác cung cấp cho bạn một model cho bảng trung gian của bạn, cho phép bạn xác nhận các lĩnh vực và thêm chức năng chia sẻ thông qua các phương thức.

Sự khác biệt trong tạo đối tượng

Dưới đây là một ví dụ về sự khác biệt trong một số phương pháp xây dựng trong đó được tạo ra khi bạn sử dụng một trong những quan hệ .Đối với has_many: through bạn có thể tạo ra các đối tượng định dạng sau: Đối với quan hệ HABTM, vì chúng ta có thể tạo đối tượng bằng như sau : Chú ý đối với HABTM, chúng ta sử dụng programmer.clients.create (client_attribute: value) , không giống như một has_many: through, nơi chúng tôi có thể sử dụng các model trung gian như vậy: programmer.projects.create (client: client_object). Chỉ một sự khác biệt giữa hai phương pháp liên kết.

Đa phần mà bạn thường dùng quan hệ has_many: through . Nó cho bạn một mô hình được gắn với việc join bảng của cơ sở dữ liệu của bạn.

phần ít thời gian, has_and_belongs_to_many: là rất hữu ích cho các di sản schemas cơ sở dữ liệu quan hệ cũng như các hệ thống cũ. Đôi khi HABTM có rất nhiều ý nghĩa đối với những tình huống này.

Trong khi has_and_belongs_to_many: là nhanh hơn để thiết lập có xu hướng không quy mô cũng như các ứng dụng của bạn yêu cầu nhiều chức năng hơn. has_many: through mặt khác là rất linh hoạt và cung cấp thêm lợi ích của việc có một mô hình ánh xạ trực tiếp join bảng của bạn.

Cả hai loại quan hệ nhiều-nhiều yêu cầu tạo ra một sự chuyển đổi cho một bảng tham gia, một bảng mà ngồi giữa hai bảng khác và giúp liên kết chúng với nhau. Bảng này được ánh xạ trực tiếp đến một mô hình khi sử dụng một has_many: through. nguồn : http://joshfrankel.me/blog/2016/how-to/create-a-many-to-many-activerecord-association-in-ruby-on-rails/ http://edgeguides.rubyonrails.org/association_basics.html

0