12/08/2018, 15:18

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

0