Skip to content

Commit

Permalink
Refactor vote query
Browse files Browse the repository at this point in the history
  • Loading branch information
rossta committed Dec 21, 2024
1 parent ea9b0a9 commit 6f6a995
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 25 deletions.
5 changes: 4 additions & 1 deletion app/controllers/share/polls/votes_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ def create
flash.now[:notice] = "Thank you for voting!".emojoy
render turbo_stream: [
turbo_stream.prepend("flash", partial: "application/flash"),
turbo_stream.replace(@poll, renderable: Share::Polls::PollComponent.new(@poll, device_uuid: ensure_device_uuid, completed: @poll.completed?(device_uuid: ensure_device_uuid)))
turbo_stream.replace(
@poll,
renderable: Share::Polls::PollComponent.new(@poll, completed: @poll.voted_all?(device_uuid: ensure_device_uuid))
)
]
end
end
Expand Down
16 changes: 12 additions & 4 deletions app/models/poll.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,17 @@ def self.generate_for(
poll
end

def completed?(device_uuid)
questions.all? do |question|
question.voted?(device_uuid: device_uuid)
end
def voted_all?(vote_conditions)
counts = questions
.select(:id)
.left_joins(:votes)
.where(votes: vote_conditions)
.group(:id)
.count # {question_id => votes_count}

# Check if all questions have at least one vote We might expect counts to
# include zeros for questions without votes but the left join appears to
# exclude them, so we fetch(id, 0) to default to 0.
question_ids.all? { |id| counts.fetch(id, 0).positive? }
end
end
4 changes: 0 additions & 4 deletions app/models/polls/question.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,4 @@ class Polls::Question < ApplicationRecord
def votes_count
answers.sum(&:votes_count)
end

def voted?(**conditions)
votes.where(**conditions).count.positive?
end
end
2 changes: 1 addition & 1 deletion app/views/share/polls/_poll.html.erb
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<%= render Share::Polls::PollComponent.new(poll, device_uuid: ensure_device_uuid, completed: poll.completed?(ensure_device_uuid)) %>
<%= render Share::Polls::PollComponent.new(poll, completed: poll.voted_all?(device_uuid: ensure_device_uuid)) %>
19 changes: 7 additions & 12 deletions app/views/share/polls/poll_component.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
class Share::Polls::PollComponent < ApplicationComponent
include Phlex::Rails::Helpers::TurboFrameTag

attr_accessor :poll, :device_uuid
attr_accessor :poll

def initialize(poll, device_uuid:, completed: false)
def initialize(poll, completed: false)
@poll = poll
@completed = completed
@device_uuid = device_uuid
end

def view_template
Expand All @@ -18,10 +17,7 @@ def view_template
end

div(class: "p-4 flex flex-col gap-2") do
poll
.questions
.includes(:answers)
.ordered
questions
.each do |question|
render Share::Polls::QuestionComponent.new(
poll,
Expand All @@ -33,10 +29,9 @@ def view_template
end
end

def completed?
@completed ||
poll.questions.all? do |question|
question.voted?(device_uuid: device_uuid)
end
def questions
@questions ||= poll.questions.includes(:answers).ordered
end

def completed? = !!@completed
end
6 changes: 3 additions & 3 deletions spec/models/poll_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
end
end

describe "#completed?" do
describe "#voted_all?" do
it "returns true if all questions have been voted on" do
poll = FactoryBot.create(:poll)
q1 = FactoryBot.create(:polls_question, poll: poll)
Expand All @@ -70,11 +70,11 @@
FactoryBot.create(:polls_vote, answer: a1_q1, device_uuid: uuid)
FactoryBot.create(:polls_vote, answer: a2_q2, device_uuid: uuid)

expect(poll.completed?(uuid)).to eq(false)
expect(poll.voted_all?(device_uuid: uuid)).to eq(false)

FactoryBot.create(:polls_vote, answer: a2_q3, device_uuid: uuid)

expect(poll.completed?(uuid)).to eq(true)
expect(poll.voted_all?(device_uuid: uuid)).to eq(true)
end
end
end

0 comments on commit 6f6a995

Please sign in to comment.