Mike Tallerico
Mike Tallerico

Reputation: 125

Query associated tables in ruby on rails

So I am working to understand ruby on rails. I have 3 tables with the below associations. I want to query all of the items on the product table and each products associated data.

For instance I want to render in my react component:

Product Name comes from product table

Product UPC comes from product table

Product Availiable on date comes from product table

Property Name(Ex. Material) comes from property table

Property Value(Ex. Cotton) comes from product_property table

class Property < ApplicationRecord
  has_many :product_properties
  has_many :products, through: :product_properties
  accepts_nested_attributes_for :product_properties
end

class Product < ApplicationRecord
  has_many :product_properties
  has_many :properties, through: :product_properties
end

class ProductProperty < ApplicationRecord
  belongs_to :property, required: false
  belongs_to :product, required: false
end

Right now I understand getting all of the products using:

Product.all

What I am not understanding is how to get each product and the associated property and product property.

I can see here where they use this method but I am unable to implement this.

Author.joins(:articles).where(articles: { author: author })

Thanks for any help you can give me.

Upvotes: 0

Views: 62

Answers (1)

Marcin Kołodziej
Marcin Kołodziej

Reputation: 5313

For eager-loading, you should generally use

Product.includes(:properties)

However, the general approach ActiveRecord uses is to use separate queries to load association data which results in these queries:

> products = Product.includes(:properties).to_a
  Product Load (0.2ms)  SELECT "products".* FROM "products"
  ProductProperty Load (0.2ms)  SELECT "product_properties".* FROM "product_properties" WHERE "product_properties"."product_id" = ?  [["product_id", 1]]
  Property Load (0.2ms)  SELECT "properties".* FROM "properties" WHERE "properties"."id" = ?  [["id", 1]]
 => [#<Product id: 1, name: "product">] 
> products.first.properties.to_a
 => [#<Property id: 1, name: "property">] 

If you know your records can be loaded with one query only, you can use

Product.eager_load(:properties)

which will translate to

SELECT "products"."id" AS t0_r0, "products"."name" AS t0_r1, "properties"."id" AS t1_r0, "properties"."name" AS t1_r1 FROM "products" LEFT OUTER JOIN "product_properties" ON "product_properties"."product_id" = "products"."id" LEFT OUTER JOIN "properties" ON "properties"."id" = "product_properties"."property_id"

Upvotes: 1

Related Questions