Last Updated: February 25, 2016
·
978
· jamesbrooks

Rails - filter using join model on has_many through

So you want to filter using a scope through an association (not just for use on has_many through, but I feel this example really shows how #merge shines!).

Given the following models:

class Person
  has_many :accounts
  has_many :computers, through: :accounts
end

class Account
  belongs_to :person
  belongs_to :computer
  scope :administrators, -> { where(role: 'administrator') }
end

class Computer
  has_many :accounts
  has_many :people, through: :accounts
end

Filtering using a join model on a has_many through can be naively accomplished with the following. Here assume we have a person instance and want to find all computers where they are an administrator.

person.accounts.administrators.map(&:computer)  # ewww

We can do this better using ActiveRecord::SpawnMethods#merge!

person.computers.merge(Account.administrators)  # very nice!

Cleaner syntax, claner query. Win win