0
0
RailsHow-ToBeginner · 3 min read

How to Use HAVING in Rails ActiveRecord Queries

In Rails, you use the having method with ActiveRecord to filter results after grouping with group. It works like SQL's HAVING clause, letting you specify conditions on aggregated data.
📐

Syntax

The having method is used after group in an ActiveRecord query to filter grouped records based on aggregate conditions.

Basic pattern:

  • Model.group(:column).having('aggregate_condition')
  • aggregate_condition is a SQL string like COUNT(column) > 1
ruby
Model.group(:column_name).having('COUNT(column_name) > 1')
💻

Example

This example finds authors who have written more than 2 books using group and having.

ruby
class Author < ApplicationRecord
  has_many :books
end

class Book < ApplicationRecord
  belongs_to :author
end

# Query to find authors with more than 2 books
authors = Author.joins(:books)
                .group('authors.id')
                .having('COUNT(books.id) > 2')
                .select('authors.*, COUNT(books.id) as books_count')

authors.each do |author|
  puts "#{author.name} has #{author.books_count} books"
end
Output
John Doe has 3 books Jane Smith has 5 books
⚠️

Common Pitfalls

Common mistakes when using having in Rails include:

  • Using where instead of having for aggregate conditions, which filters before grouping and gives wrong results.
  • Not including the grouped columns in select, causing errors or missing data.
  • Writing raw SQL without sanitizing inputs, risking SQL injection.
ruby
## Wrong: Using where instead of having
Author.joins(:books)
      .group('authors.id')
      .where('COUNT(books.id) > 2') # This will raise an error

## Right: Using having
Author.joins(:books)
      .group('authors.id')
      .having('COUNT(books.id) > 2')
📊

Quick Reference

MethodPurposeExample
groupGroups records by column(s)Model.group(:category)
havingFilters grouped records by aggregate conditionModel.group(:category).having('COUNT(id) > 1')
selectSelects columns including aggregatesModel.select('category, COUNT(id) as count')

Key Takeaways

Use having after group to filter grouped query results in Rails.
Never use where for aggregate conditions; it filters before grouping.
Always include grouped columns and aggregates in select to avoid missing data.
Sanitize raw SQL in having to prevent SQL injection.
Combine joins, group, and having for powerful aggregate queries.