Back to Course

Practice · SOLID · SRP · Card 6

Where does this query belong?

A class method on User that does complex finder logic. It grew over time. It's still on the model. Should it stay?

The code

A class method on User. Five filters, an order, a limit, two joins.

class User < ApplicationRecord
  has_many :orders
  has_many :payments

  def self.churn_risks(since: 30.days.ago, min_spend_cents: 50_00, segment: :all)
    base = active.joins(:orders, :payments)

    base = base.where(orders: { created_at: since.. })
    base = base.where("payments.amount_cents >= ?", min_spend_cents)
    base = base.where(segment: segment) unless segment == :all
    base = base.where("users.last_login_at < ?", 14.days.ago)
    base = base.where.not(id: NotificationLog.recent_recipient_ids)

    base.group("users.id")
        .order("MAX(orders.created_at) ASC")
        .limit(500)
  end
end

The question

This works. Tests pass. It belongs to the User model. What's the SRP-shaped problem, and where should this logic actually live?

Take a moment. Ask: is this code about a User, or about a specific business question that happens to start with User? The answer tells you where it belongs.