'Eager load extended has_many association

Couldn't find anything about how to specify extended association with arguments in includes. Condsider:

Class Author < ActiveRecord::Base
  has_many :books do
    def of_genre(genre)
       where(genre: genre)
    end
  end
end

This can be used like: Aurhor.first.books.of_genre('horror'). I want to use this with includes: Author.where(...).includes(:books).where(books: ...) This will generate a left join, but due to the nature of my specific use case, I don't want it to join to books table, but rather an already filtered books table (hence the extension). Is this possible in some way?



Solution 1:[1]

One possible way is to create scopes on Book and then associations for them on Author, it will allow you to eager_load them but unfortunately create some overhead.

class Book < ApplicationRecord
    scope :horror, -> { where(genre: "horror") } 
    scope :fantasy, -> { where(genre: "fantasy") }
 end

 class Author < ApplicationRecord
    has_many :horror_books, -> { horror }
    has_many :fantasy_books, -> { fantasy }
 end

 Author.first.includes(:horror_books)
 Author.first.includes(:fantasy_books)

   

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1