author avatar

ayushsrivastava

Tue May 21 2024

Scoped Associations with Joins

Let's consider the following models:
Author with attributes id, name
Book with attributes id, title, published, author_id
The association is that an Author has many Books, and a Book belongs to an Author.

Defining Scoped Associations
First, let's define a scope on the Book model to filter only published books:


class Book < ApplicationRecord 
  belongs_to :author 
  scope :published, -> { where(published: true) } 
end 


Next, let's use this scope in the Author model to create a scoped association:



class Author < ApplicationRecord 
  has_many :books 
  has_many :published_books, -> { published }, class_name: 'Book' 
end 


Now, Author has an association called published_books, which only includes books that are published.

Using Scoped Associations with Joins

We can now use the scoped association in joins to fetch authors and their published books.
Example 1: Fetch Authors with Published Books
To fetch authors along with their published books:



@authors_with_published_books = Author.joins(:published_books).select('authors.*, books.title as book_title') 


This query joins the authors table with the books table but only includes books that are published, thanks to the scoped association published_books.

As a result, each Author object in @authors_with_published_books will have:
• All attributes of the Author model.
• An additional attribute called book_title representing the title of each associated book.
#rails #scoped_associations_with_joins