I have two models, Keyword and Company, associated using has_and_belongs_to_many.
On the Keyword model, there is a boolean field included. If this is set to true, any Company associated with that Keyword should be considered included, unless it has any associated Keywords with included set to false. included can also be set to nil which I consider a state of "empty".
To summarize:
CompanyA has 2 associatedKeywords, 1included = trueand 1included = nil. This company is INCLUDED.CompanyB has 2 associatedKeywords, 1included = falseand 1included = true. This company is EXCLUDED.CompanyC has 2 associatedKeywords, bothincluded = nil. This company is EMPTY.
What is the best way to 1) count the number of Included, Excluded, and Empty companies, and 2) query/scope the Company model to Included, Excluded, or Empty?
The current solution I have hacked together is causing expensive queries that are resulting (usually) in request timeouts. Models follow:
class Company < ApplicationRecord
has_and_belongs_to_many :keywords
scope :included, -> { joins(:keywords).merge(Keyword.included).group('id').reorder('') }
scope :excluded, -> { joins(:keywords).merge(Keyword.excluded).group('id').reorder('') }
scope :empty, -> { joins(:keywords).merge(Keyword.empty).group('id').reorder('') }
end
class Keyword < ApplicationRecord
has_and_belongs_to_many :companies
scope :excluded, -> { where(included: false) }
scope :included, -> { where(included: true) }
scope :empty, -> { where(included: nil) }
end
(reorder is included in Company model to resolve a quirk with pg_search gem and grouping)