Skip to content

Instantly share code, notes, and snippets.

@sauloperez
Created January 7, 2021 11:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sauloperez/8fbcedd7824ec39af7631fa061e16a7c to your computer and use it in GitHub Desktop.
Save sauloperez/8fbcedd7824ec39af7631fa061e16a7c to your computer and use it in GitHub Desktop.
commit b5680a7effab8bb9f1b1542366b6dad36fe23611
Author: Pau Perez <saulopefa@gmail.com>
Date: Thu Jan 7 11:21:00 2021 +0100
Turn to 2 queries into one with another INNER JOIN
There's no need to fetch the votes' authors first if we can scope the
query to the votes' records we care about in a single statement.
Letting the DB do its job results in less code on our side and better
performance. We skip Ruby CPU cycles and a network round trip for each
query.
diff --git a/app/queries/decidim/action_delegator/delegates_votes.rb b/app/queries/decidim/action_delegator/delegates_votes.rb
index 9035a27..1a04a59 100644
--- a/app/queries/decidim/action_delegator/delegates_votes.rb
+++ b/app/queries/decidim/action_delegator/delegates_votes.rb
@@ -3,17 +3,12 @@
module Decidim
module ActionDelegator
class DelegatesVotes < Rectify::Query
- def initialize(authors_ids_votes = nil)
- @authors_ids_votes = authors_ids_votes
- end
-
def query
Decidim::User
.joins("INNER JOIN decidim_action_delegator_delegations
ON decidim_users.id = decidim_action_delegator_delegations.granter_id
INNER JOIN decidim_consultations_votes
ON decidim_consultations_votes.decidim_author_id = decidim_action_delegator_delegations.granter_id")
- .where(decidim_action_delegator_delegations: { granter_id: authors_ids_votes })
end
private
diff --git a/app/queries/decidim/action_delegator/delegates_votes_by_consultation.rb b/app/queries/decidim/action_delegator/delegates_votes_by_consultation.rb
index 2ef72b6..56405b5 100644
--- a/app/queries/decidim/action_delegator/delegates_votes_by_consultation.rb
+++ b/app/queries/decidim/action_delegator/delegates_votes_by_consultation.rb
@@ -3,25 +3,27 @@
module Decidim
module ActionDelegator
class DelegatesVotesByConsultation < Rectify::Query
- def initialize(consultation, relation = nil)
- @relation = relation.presence || Decidim::ActionDelegator::DelegatesVotes
+ def initialize(consultation, relation = Decidim::ActionDelegator::DelegatesVotes)
+ @relation = relation
@consultation = consultation
end
def query
- authors_ids_votes = Decidim::Consultations::Vote
- .joins("INNER JOIN decidim_consultations_questions
- ON decidim_consultations_votes.decidim_consultation_question_id = decidim_consultations_questions.id
- INNER JOIN decidim_consultations
- ON decidim_consultations.id = decidim_consultations_questions.decidim_consultation_id")
- .where(decidim_consultations: { id: consultation.id })
- .pluck(:decidim_author_id)
- relation.new(authors_ids_votes).query.count
+ relation.new.query.merge(consultation_votes).count
end
private
attr_reader :consultation, :relation
+
+ def consultation_votes
+ Decidim::Consultations::Vote
+ .joins("INNER JOIN decidim_consultations_questions
+ ON decidim_consultations_votes.decidim_consultation_question_id = decidim_consultations_questions.id
+ INNER JOIN decidim_consultations
+ ON decidim_consultations.id = decidim_consultations_questions.decidim_consultation_id")
+ .where(decidim_consultations: { id: consultation.id })
+ end
end
end
end
diff --git a/app/queries/decidim/action_delegator/delegates_votes_by_question.rb b/app/queries/decidim/action_delegator/delegates_votes_by_question.rb
index 256c8d2..27f6c23 100644
--- a/app/queries/decidim/action_delegator/delegates_votes_by_question.rb
+++ b/app/queries/decidim/action_delegator/delegates_votes_by_question.rb
@@ -3,18 +3,18 @@
module Decidim
module ActionDelegator
class DelegatesVotesByQuestion < Rectify::Query
- def initialize(question, relation = nil)
- @authors_ids_votes = question.votes.pluck(:decidim_author_id)
- @relation = relation.presence || Decidim::ActionDelegator::DelegatesVotes
+ def initialize(question, relation = Decidim::ActionDelegator::DelegatesVotes)
+ @question = question
+ @relation = relation
end
def query
- relation.new(authors_ids_votes).query.distinct.count
+ relation.new.query.merge(question.votes).distinct.count
end
private
- attr_reader :authors_ids_votes, :relation
+ attr_reader :question, :relation
end
end
end
diff --git a/spec/queries/decidim/action_delegator/delegates_votes_by_consultation_spec.rb b/spec/queries/decidim/action_delegator/delegates_votes_by_consultation_spec.rb
index 602621f..b07e52d 100644
--- a/spec/queries/decidim/action_delegator/delegates_votes_by_consultation_spec.rb
+++ b/spec/queries/decidim/action_delegator/delegates_votes_by_consultation_spec.rb
@@ -14,9 +14,13 @@ describe Decidim::ActionDelegator::DelegatesVotesByConsultation do
let!(:delegation) { create(:delegation, setting: setting, granter: granter) }
let!(:delegated_vote) { create(:vote, author: granter, question: question) }
+ let(:another_granter) { create(:user, organization: organization) }
+ let!(:another_delegation) { create(:delegation, setting: setting, granter: another_granter) }
+ let!(:another_delegated_vote) { create(:vote, author: another_granter, question: question) }
+
describe "#query" do
it "total votes count is correct" do
- expect(subject.query).to eq(1)
+ expect(subject.query).to eq(2)
end
end
end
diff --git a/spec/queries/decidim/action_delegator/delegates_votes_by_question_spec.rb b/spec/queries/decidim/action_delegator/delegates_votes_by_question_spec.rb
index bd8a87a..af727eb 100644
--- a/spec/queries/decidim/action_delegator/delegates_votes_by_question_spec.rb
+++ b/spec/queries/decidim/action_delegator/delegates_votes_by_question_spec.rb
@@ -14,9 +14,13 @@ describe Decidim::ActionDelegator::DelegatesVotesByQuestion do
let!(:delegation) { create(:delegation, setting: setting, granter: granter) }
let!(:delegated_vote) { create(:vote, author: granter, question: question) }
+ let(:another_granter) { create(:user, organization: organization) }
+ let!(:another_delegation) { create(:delegation, setting: setting, granter: another_granter) }
+ let!(:another_delegated_vote) { create(:vote, author: another_granter, question: question) }
+
describe "#query" do
it "total votes count is correct" do
- expect(subject.query).to eq(1)
+ expect(subject.query).to eq(2)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment