I have been trying to optimize a query. I have a model named Issue and a model named Labels they have a many to many relationship.
To get a list of issues that has labels with names that match every item in a given array, I'm using:
Issue.select('issues.id, count(labels.id) as matching_label_count')
.joins(:labels)
.where(labels: { name: [*labels] })
.having("matching_label_count = #{labels.size}")
.group('issues.id')
Using pry, I see that the query returns an Issue::ActiveRecord_Relation as expected and that it responds to ActiveRecord::Calculations methods. However, when I call count on the result I get a syntax error:
pry(main)> Issue.select('issues.id, count(labels.id) as
matching_label_count').includes(:labels).where(labels: { name: labels
}).having("matching_label_count = #{labels.size}").group('issues.id').count
(0.9ms) SELECT COUNT(DISTINCT issues.id, count(labels.id) as
matching_label_count) AS
count_issues_id_count_labels_id_as_matching_label_count, issues.id,
count(labels.id) as matching_label_count, issues.id AS issues_id FROM "issues"
LEFT OUTER JOIN "tags" ON "tags"."issue_id" = "issues"."id" LEFT OUTER JOIN
"labels" ON "labels"."id" = "tags"."label_id" WHERE "labels"."name" IN (?, ?)
GROUP BY issues.id HAVING (matching_label_count = 2) ORDER BY
"issues"."created_at" DESC [["name", "bug"], ["name", "enhancement"]]
ActiveRecord::StatementInvalid: SQLite3::SQLException: near "as": syntax error:
SELECT COUNT(DISTINCT issues.id, count(labels.id) as matching_label_count) AS
count_issues_id_count_labels_id_as_matching_label_count, issues.id,
count(labels.id) as matching_label_count, issues.id AS issues_id FROM "issues"
LEFT OUTER JOIN "tags" ON "tags"."issue_id" = "issues"."id" LEFT OUTER JOIN
"labels" ON "labels"."id" = "tags"."label_id" WHERE "labels"."name" IN (?, ?)
GROUP BY issues.id HAVING (matching_label_count = 2) ORDER BY
"issues"."created_at" DESC from /Users/Arnould/.rvm/gems/ruby-2.6.0/gems/sqlite3-1
.3.13/lib/sqlite3/database.rb:91:in `initialize' Caused by
SQLite3::SQLException: near "as": syntax error from /Users/Arnould/.rvm/gems/ruby-
2.6.0/gems/sqlite3-1.3.13/lib/sqlite3/database.rb:91:in `initialize'
It does however work fine with length. size returns a hash with a count (label_name_count) as the value and the issue id as the key.
I already have half a dozen tests calling count on the result I want to know why it doesn't work before I consider changing them.
What is causing #count to fail and how can I fix it my query to ensure it works?