[Active Record]Rails associations and the use of the `joins` method.
In this blog post, we will explore the power of Active Record Rails associations and delve into the versatile `joins` method. Through the lens of three vital models — `User`, `Book`, and `Novelty` — we will create records and master the art of connecting and querying data.
Understanding the Models & Creating the Models:
Our journey begins with the creation of models and the establishment of their associations using Rails’ robust Active Record capabilities.
rails generate model User name email
rails generate model Book title author user:references
rails generate model Novelty name description:text book:references
These models serve as the building blocks of our Rails application, and we will define their associations in their respective model files.
User Model:
At the core of our application lies the `User` model, which wields the power to author books.
class User < ApplicationRecord
has_many :books
end
Book Model:
Books belong to users and act as a canvas for novelties. Each book has the potential to house multiple novelties.
class Book < ApplicationRecord
belongs_to :user
has_many :novelties
end
Novelty Model:
Within books reside the creative gems known as novelties. The `Novelty` model forms the link between books and their imaginative contents.
class Novelty < ApplicationRecord
belongs_to :book
end
Creating Records:
With our models and associations in place, let’s bring our application to life by creating records for users, books, and novelties. using rails c
# Creating Users
user1 = User.create(name: ‘User 1’, email: ‘user1@example.com’)
user2 = User.create(name: ‘User 2’, email: ‘user2@example.com’)
# Creating Books Associated with Users
book1 = user1.books.create(title: 'Book Title 1', author: 'Author 1')
book2 = user2.books.create(title: 'Book Title 2', author: 'Author 2')
# Creating Novelties Associated with Books
book1.novelties.create(name: 'Novelty 1', description: 'Description of Novelty 1')
book2.novelties.create(name: 'Novelty 2', description: 'Description of Novelty 2')
Our database is now teeming with users, books, and novelties, all intricately connected through associations.
The Power of the `Joins` Method
The true magic of Rails associations unfolds as we explore how to employ the `joins` method to seamlessly connect our models and execute data queries.
Joining Users and Books:
Our initial feat is to join the `User` and `Book` models to embark on a literary adventure and discover users who have ventured into the world of authorship.
users_with_books = User.joins(:books)
users_with_books = User.joins(:books)
User Load (0.1ms) SELECT "users".* FROM "users" INNER JOIN "books" ON "books"."user_id" = "users"."id"
=>
[#<User:0x00007f4448674ce0
...
3.0.0 :014 > users_with_books_count = User.joins(:books).count
User Count (0.1ms) SELECT COUNT(*) FROM "users" INNER JOIN "books" ON "books"."user_id" = "users"."id"
=> 2
This query retrieves all users who have embarked on the literary journey by creating books. The `joins` method elegantly merges these two models, opening up a world of possibilities.
Filtering by Book Title:
Suppose we wish to find users associated with books bearing a specific title, such as “Book Title 1” This is where the true power of associations shines.
users_with_specific_book = User.joins(:books).where(books: { title: "Book Title 1" })
User Load (0.1ms) SELECT "users".* FROM "users" INNER JOIN "books" ON "books"."user_id" = "users"."id" WHERE "books"."title" = ? [["title", "Book Title 1"]]
=>
[#<User:0x000055bf2aae7268
...
3.0.0 :005 > users_with_specific_book_count = User.joins(:books).where(books: { title: "Book Title 1" }).count
User Count (0.1ms) SELECT COUNT(*) FROM "users" INNER JOIN "books" ON "books"."user_id" = "users"."id" WHERE "books"."title" = ? [["title", "Book Title 1"]]
=> 1
By utilizing the `joins` method to connect users and books and employing the `where` method to filter results by book title, we can tailor our insights to meet our requirements with unmatched flexibility.
Navigating Complex Associations:
We venture further by joining the `User`, `Book`, and `Novelty` models to unearth the creative gems residing within our application.
users_with_books_and_novelties = User.joins(books: :novelties).where(novelties: { name: "Novelty 2" })
User Load (0.2ms) SELECT "users".* FROM "users" INNER JOIN "books" ON "books"."user_id" = "users"."id" INNER JOIN "novelties" ON "novelties"."book_id" = "books"."id" WHERE "novelties"."name" = ? [["name", "Novelty 2"]]
=>
[#<User:0x000055bf2a40ef68
...
users_with_books_and_novelties_count = User.joins(books: :novelties).where(novelties: { name: "Novelty 2" }).count
User Count (0.1ms) SELECT COUNT(*) FROM "users" INNER JOIN "books" ON "books"."user_id" = "users"."id" INNER JOIN "novelties" ON "novelties"."book_id" = "books"."id" WHERE "novelties"."name" = ? [["name", "Novelty 2"]]
=> 1
This query reveals users who have not only authored books but have also penned novelties with the name “self.” The `joins` method empowers us to traverse the intricate web of associations effortlessly.
Filtering by User Name:
Finally, we set our sights on novelties, seeking to uncover those crafted by a user with a specific name, such as “igaiga.”
novelties_created_by_specific_user = Novelty.joins(book: :user).where(users: { name: "igaiga" })
Novelty Load (0.2ms) SELECT "novelties".* FROM "novelties" INNER JOIN "books" ON "books"."id" = "novelties"."book_id" INNER JOIN "users" ON "users"."id" = "books"."user_id" WHERE "users"."name" = ? [["name", "igaiga"]]
=> []
3.0.0 :011 > novelties_created_by_specific_user = Novelty.joins(book: :user).where(users: { name: "User 1" })
Novelty Load (0.1ms) SELECT "novelties".* FROM "novelties" INNER JOIN "books" ON "books"."id" = "novelties"."book_id" INNER JOIN "users" ON "users"."id" = "books"."user_id" WHERE "users"."name" = ? [["name", "User 1"]]
=>
[#<Novelty:0x000055bf2afd39c0
...
3.0.0 :012 > novelties_created_by_specific_user = Novelty.joins(book: :user).where(users: { name: "User 1" }).count
Novelty Count (0.1ms) SELECT COUNT(*) FROM "novelties" INNER JOIN "books" ON "books"."id" = "novelties"."book_id" INNER JOIN "users" ON "users"."id" = "books"."user_id" WHERE "users"."name" = ? [["name", "User 1"]]
=> 1
In this blog post, we embarked on a journey into the heart of Active Record Rails associations, exploring the setup of models, creation of records, and mastery of the `joins` method to connect and query data effortlessly.
these associations are the backbone of Rails, offering a seamless way to work with your data. Embrace the possibilities, and let associations unlock the full potential of your Rails applications.
Follow the BharteeTechRoR, explore the stories, and happy coding!