Active Record Joins
Mình sẽ đi thẳng vào vấn đề chính . Chúng ta có thể sử dụng query method Joins để query data từ các table quan hệ với nhau . Ví dụ ta có 1 categories ứng với nhiều products Ta có Models như sau : class Category < ActiveRecord::Base has_many :products end class Product < ...
Mình sẽ đi thẳng vào vấn đề chính . Chúng ta có thể sử dụng query method Joins để query data từ các table quan hệ với nhau . Ví dụ ta có 1 categories ứng với nhiều products
Ta có Models như sau :
class Category < ActiveRecord::Base has_many :products end class Product < ActiveRecord::Base belongs_to :category has_many :likes end class User < ActiveRecord::Base has_many :likes has_many :liked_products, through: :likes, source: :product end class Like < ActiveRecord::Base belongs_to :user belongs_to :product end
Và đây là dữ liệu cơ bản :
Chúng ta sẽ bắt đầu bằng những JOINS đơn giản
Category.joins(:products)
Nó tương ứng với câu query sau : SQL: SELECT "categories".* FROM "categories" INNER JOIN "products" ON "products"."category_id" = "categories"."id" Và đây là kết quả :
Nhứ bạn thấy , có nhiều records đang trùng nhau , đơn giản chúng ta chỉ cần thêm vào câu lệnh dưới để loại bỏ các records trùng.
Category.joins(:products).uniq
Để nâng cao hơn chúng ta sẽ thêm 2 table vào :
Product.joins(:category, :likes).uniq
Chúng ta chỉ đơn giản là thêm tên table dưới hình thức số nhiều vào để query Dòng lệnh trên tương tự câu query sau :
SELECT DISTINCT "products". FROM "products" INNER JOIN "categories" ON "categories"."id" = "products"."categoryid" INNER JOIN "likes" ON "likes"."productid" = "products"."id"
Và các bạn có thể hình dung tổng thể các loại joins trên product như sau :
Hơn thế nữa bạn có thể query kiểu như này :
Category.joins(products: [:reviews, :likes]).uniq
Rất tiện lợi đúng không ? Chúng ta còn có thể thêm các điều kiện vào theo cấu trúc như sau (1 trong 3 cách viết đều đúng ):
Product.where(quantity: 0) Product.where(quantity: 2..5) Product.where('quantity > 3')
Và để kết hợp với joins :
Category.joins(:products).where(products: {quantity: 0}) *OR * Category.joins(:products).where('products.quantity > 3').uniq
Kết Thúc
Cảm ơn các bạn đã đọc viblo của mình, mong những thông tin trong này sẽ làm bạn viết được những method, scope vừa ý mình và hiệu quả nhất .
Nguồn : https://www.learneroo.com/modules/137/nodes/768