Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Joining Nested Associations (Multiple Level)

I have the following models and relationships:

Picture of models

A User has many Offers (where he/she is the seller), an Offer has many Purchases, a Purchase has many Accbooks

Models and associations:

class User < ApplicationRecord
  has_many :offers, foreign_key: :seller_id
  has_many :purchases, foreign_key: :buyer_id
end

class Offer < ApplicationRecord
  has_many :purchases
  belongs_to :seller, class_name: 'User'
end

class Purchase < ApplicationRecord
  belongs_to :offer
  belongs_to :buyer, class_name: 'User'
  has_one :seller, through: :offer
  has_many :accbooks,  class_name: 'Admin::Accbook', foreign_key: 'purchase_id' 
end

module Admin
  class Accbook < ApplicationRecord
    belongs_to :purchase
  end
end  

I want to get all the Accbooks of any given user (as a seller). The equivalent SQL statement would look like this:

SELECT  "accbooks".* 
FROM "accbooks" 
INNER JOIN "purchases" ON "purchases"."id" = "accbooks"."purchase_id"
INNER JOIN "offers" ON "offers"."id" = "purchases"."offer_id"
INNER JOIN "users" ON "users"."id" = "offers"."seller_id"
WHERE "users"."id" = ?

So far I've tried this:

Admin::Accbook.joins( {purchase: :offer} )

Which gives me this SQL as a result:

SELECT  "accbooks".*
FROM "accbooks"
INNER JOIN "purchases" ON "purchases"."id" = "accbooks"."purchase_id"
INNER JOIN "offers" ON "offers"."id" = "purchases"."offer_id"

Now I don´t know how to add the join to the User model, and then how to add the Where condition.

Thanks for any insight.

like image 641
Eduardo Álvarez Avatar asked May 17 '18 23:05

Eduardo Álvarez


2 Answers

You can joins the relations together and apply where clause on the joined relations:

Admin::Accbook
  .joins(purchase: :offer)
  .where(offers: { seller_id: 123 })

A thing to know, where uses the DB table's name. joins (and includes, eager_load, etc) uses the relation name. This is why we have:

Admin::Accbook
  .joins(purchase: :offer)
  #                 ^^^^^ relation name
  .where(offers: { seller_id: 123 })
  #      ^^^^^^ table name
like image 185
MrYoshiji Avatar answered Oct 05 '22 22:10

MrYoshiji


Try Adding following association in users.rb

has_many :accbooks, through: :purchases

like image 39
Nimish Gupta Avatar answered Oct 06 '22 00:10

Nimish Gupta