Reputation: 125
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
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