Jacob Kopczynski
Jacob Kopczynski

Reputation: 412

Empty? fails on ActiveRecord with a default_scope( :order)

Occasionally I want to check whether a Person model has any organizations. Straightforward enough; use @person.organizations.empty?. However, coupled with my default_scope (default_scope { order(:name) }), I get this error:

ActiveRecord::StatementInvalid (PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list LINE 1: ... WHERE "relationships"."person_id" = $1 ORDER BY "organizat... ^

: SELECT DISTINCT 1 AS one FROM "organizations" INNER JOIN "contracts" ON "organizations"."id" = "contracts"."organization_id" INNER JOIN "relationships" ON "contracts"."id" = "relationships"."contract_id" WHERE "relationships"."person_id" = $1 ORDER BY "organizations"."name" ASC LIMIT 1):

I'm using a Postgres DB and my (abbreviated) model setup looks as follows:

class Organization < ActiveRecord::Base
  has_many :contracts
  has_many :people, -> { uniq }, :through => :contracts

  default_scope { order(:name) }
end

class Person < ActiveRecord::Base
  has_many :relationships, :inverse_of => :person
  has_many :contracts, :through => :relationships
  has_many :organizations, -> { uniq }, :through => :contracts
end

class Contract < ActiveRecord::Base
  belongs_to :organization, touch: true

  has_many :relationships, :inverse_of => :contract
  has_many :people, :through => :relationships
end

Things I have tried so far:

  has_many :organizations, -> { order(:name).uniq }, :through => :contracts

Which supposedly would make activerecord see what was coming in advance (it didn't) and

  has_many :organizations, -> { includes(:name).uniq }, :through => :contracts

which fixes the problem when I put it in manually in the console, but does not help in the app itself. How do I coerce ActiveRecord into formatting the empty? query differently or dropping the order whenever I am using empty??

EDIT: To be clear, I am perfectly aware that using @person.organizations.count == 0 will work, and there are probably other one-off solutions. But I'm looking for a general one so I don't have to keep repeating myself.

Upvotes: 1

Views: 114

Answers (1)

Thomas Walpole
Thomas Walpole

Reputation: 49870

@person.organizations.reorder('').empty? 

should work

Upvotes: 0

Related Questions