"Left outer join" very easy in Rails 5
Việc sử dụng "left outer join" để giải quyết các bài toán đã trở nên quen thuộc với chúng ta. Với Rails 4 và các phiên bản trở về trước, việc sử dụng "left outer join" khá là dài dòng, phức tạp khi ta phải tự tay viết từng dòng lệnh truy vấn. Trong version 5 này Rails đã thêm phương thức ...
Việc sử dụng "left outer join" để giải quyết các bài toán đã trở nên quen thuộc với chúng ta. Với Rails 4 và các phiên bản trở về trước, việc sử dụng "left outer join" khá là dài dòng, phức tạp khi ta phải tự tay viết từng dòng lệnh truy vấn. Trong version 5 này Rails đã thêm phương thức "left_outer_joins" giúp việc sử dụng "left outer join" trở nên đơn giản đi rất nhiều.
Lấy một ví dụ đơn giản:
Trong một ứng dụng blog có hai bảng là Authors và Posts. Một Post thuộc về một Author, trong khi Author lại có nhiều bài Post. Yêu cầu đặt ra ở đây là ứng dụng này cần hiển thị danh sách tất cả các Author cùng với các bài Post mà họ đã viết.
Đối với điều này, chúng ta cần phải Join hai bảng Author và bảng Post lại với nhau bằng "Left outer join". ( Các bạn có thể tìm hiểu thêm về "left outer join" ở đây và ở đây.
Trong Rails 4.x, chúng ta cần phải viết SQL cho kết nối "Left outer join" bằng tay vì Active Record không có hỗ trợ cho các "outer join". Ví dụ:
authors = Author.join('LEFT OUTER JOIN "posts" ON "posts"."author_id" = "authors"."id"') .uniq .select("authors.*, COUNT(posts.*) as posts_count") .group("authors.id")
Nhưng với Rails 5 việc sử dụng Left outer join dễ dàng hơn rất nhiểu, chỉ cần sử dụng như sau:
authors = Author.left_outer_joins(:posts) .uniq .select("authors.*, COUNT(posts.*) as posts_count") .group("authors.id")
Ở đây chúng ta chỉ mới join 2 bảng lại với nhau nên ta vẫn chưa thấy rõ ưu điểm của nó. Nhưng nếu ta join nhiều bảng hơn thì sao? Giả sử ta lấy thêm các Comment của Author thì như thế nào? Rails 4.x
authors = Author.join('LEFT OUTER JOIN "posts" ON "posts"."author_id" = "authors"."id" LEFT OUTER JOIN "comments" ON "comments"."author_id" = "authors"."id" ') .uniq .select("authors.*, COUNT(posts.*) as posts_count") .group("authors.id")
Với Rails 5 ta chỉ cần:
authors = Author.left_outer_joins :posts, :comments .uniq .select("authors.*, COUNT(posts.*) as posts_count") .group("authors.id")
Có sự khác biệt hơn rồi phải không ?
Kết luận
Trên đây là sự sơ lược của mình về phương thức left_outer_joins của Rails 5. Cảm ơn các bạn đã xem!