user3186332
user3186332

Reputation: 370

Return Every Parent Relationship and filter children in where clause active record

I have a relationship of a Parent, Child, Skills. Each Parent can have several children and each child has one skill.

I want to return all Parents from the database and include the children that belong to them if they have a certain skill.

At the end of the query we will have several parents with possibly 0 children. I'm trying something like this Parent.includes(children: [:skill]).where(skill: {skill_type: type}) but this doesn't return all the Parents. Is this possible to do through ActiveRecord?

Upvotes: 1

Views: 1338

Answers (1)

max
max

Reputation: 101811

class Parent < ActiveRecord::Base
  has_many :children
  has_many :skills, through: :children
  def self.with_skill(skill_type)
    children = Child.joins(:skills).where(skills: { skill_type: skill_type } )
    Parent.all.map do |parent|
      children = children.select { |c| c.parent_id == parent.id }
      # This marks the association as loaded so that rails does not issue a n+1 query
      association = parent.association(:children)
      association.loaded!
      association.target.concat(children)
      children.each { |c| association.set_inverse_instance(c) }
      parent.readonly! # because we dont want to accidentally set the children to []
      parent
    end
  end
end

Here we use two queries, the first fetches all the children with the selected skill and the skill. The second gets all the parents.

We then manually setup the relation between Parent and Child so that it parent.children does not cause ActiveRecord to query the database for children.

We also mark the record as read-only since if one of these records was saved it could remove the parent_id from the associated children.

All in all this is a bit of a work-around which will work well for displaying the records. Rails does not really let you pick and choose exactly what associations should be preloaded in the way you would desire here.

Upvotes: 1

Related Questions