From 38ad65605ec946d3dc8267720b215acdb03aa14f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Sat, 6 Apr 2024 18:51:52 +0200 Subject: [PATCH] Use `excluding` instead of `where.not(id:` This method was added in Rails 7.0 and makes the code slihgtly more readable. The downside is that it generates two queries instead of one, so it might generate some confusion when debugging SQL queries. Its impact on performance is probably negligible. --- app/controllers/proposals_controller.rb | 2 +- app/lib/acts_as_paranoid_aliases.rb | 2 +- app/models/banner.rb | 2 +- app/models/budget.rb | 2 +- app/models/budget/investment.rb | 4 ++-- app/models/concerns/verification.rb | 2 +- app/models/dashboard/administrator_task.rb | 2 +- app/models/poll.rb | 2 +- app/models/poll/question/option.rb | 2 +- app/models/proposal.rb | 10 +++------- app/models/proposal_notification.rb | 2 +- app/models/user.rb | 2 +- db/dev_seeds/flags.rb | 6 +++--- db/dev_seeds/votes.rb | 2 +- 14 files changed, 19 insertions(+), 23 deletions(-) diff --git a/app/controllers/proposals_controller.rb b/app/controllers/proposals_controller.rb index d22836066..7a27f7d3f 100644 --- a/app/controllers/proposals_controller.rb +++ b/app/controllers/proposals_controller.rb @@ -164,7 +164,7 @@ class ProposalsController < ApplicationController .sort_by_confidence_score .limit(Setting["featured_proposals_number"]) if @featured_proposals.present? - @resources = @resources.where.not(id: @featured_proposals) + @resources = @resources.excluding(@featured_proposals) end end end diff --git a/app/lib/acts_as_paranoid_aliases.rb b/app/lib/acts_as_paranoid_aliases.rb index 76afbbdf0..f8a44f766 100644 --- a/app/lib/acts_as_paranoid_aliases.rb +++ b/app/lib/acts_as_paranoid_aliases.rb @@ -43,7 +43,7 @@ module ActsAsParanoidAliases end def without_confirmed_hide - where(confirmed_hide_at: nil) + excluding(with_confirmed_hide) end def with_hidden diff --git a/app/models/banner.rb b/app/models/banner.rb index ea3a9b513..8d0513a21 100644 --- a/app/models/banner.rb +++ b/app/models/banner.rb @@ -20,7 +20,7 @@ class Banner < ApplicationRecord has_many :web_sections, through: :sections scope :with_active, -> { where(post_started_at: ..Date.current, post_ended_at: Date.current..) } - scope :with_inactive, -> { where.not(id: with_active) } + scope :with_inactive, -> { excluding(with_active) } scope :in_section, ->(section_name) do joins(:web_sections, :sections).where("web_sections.name ilike ?", section_name) end diff --git a/app/models/budget.rb b/app/models/budget.rb index 319f02d4b..894519282 100644 --- a/app/models/budget.rb +++ b/app/models/budget.rb @@ -47,7 +47,7 @@ class Budget < ApplicationRecord accepts_nested_attributes_for :phases scope :published, -> { where(published: true) } - scope :drafting, -> { where.not(id: published) } + scope :drafting, -> { excluding(published) } scope :informing, -> { where(phase: "informing") } scope :accepting, -> { where(phase: "accepting") } scope :reviewing, -> { where(phase: "reviewing") } diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index 53b8c196c..b6b2ae6be 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -73,7 +73,7 @@ class Budget scope :valuation_open, -> { where(valuation_finished: false) } scope :with_admin, -> { where.not(administrator_id: nil) } - scope :without_admin, -> { where(administrator_id: nil) } + scope :without_admin, -> { excluding(with_admin) } scope :without_valuator_group, -> { where(valuator_group_assignments_count: 0) } scope :without_valuator, -> { without_valuator_group.where(valuator_assignments_count: 0) } scope :under_valuation, -> { valuation_open.valuating.with_admin } @@ -87,7 +87,7 @@ class Budget scope :valuation_finished_feasible, -> { where(valuation_finished: true, feasibility: "feasible") } scope :feasible, -> { where(feasibility: "feasible") } scope :unfeasible, -> { where(feasibility: "unfeasible") } - scope :not_unfeasible, -> { where.not(feasibility: "unfeasible") } + scope :not_unfeasible, -> { excluding(unfeasible) } scope :undecided, -> { where(feasibility: "undecided") } scope :with_supports, -> { where(cached_votes_up: 1..) } diff --git a/app/models/concerns/verification.rb b/app/models/concerns/verification.rb index 298c44b4d..e72ba0ab8 100644 --- a/app/models/concerns/verification.rb +++ b/app/models/concerns/verification.rb @@ -3,7 +3,7 @@ module Verification included do scope :residence_verified, -> { where.not(residence_verified_at: nil) } - scope :residence_unverified, -> { where(residence_verified_at: nil) } + scope :residence_unverified, -> { excluding(residence_verified) } scope :residence_and_phone_verified, -> { residence_verified.where.not(confirmed_phone: nil) } scope :residence_or_phone_unverified, -> { residence_unverified.or(where(confirmed_phone: nil)) } scope :phone_not_fully_confirmed, -> { where(unconfirmed_phone: nil).or(where(confirmed_phone: nil)) } diff --git a/app/models/dashboard/administrator_task.rb b/app/models/dashboard/administrator_task.rb index e0091d0a4..d0682c99d 100644 --- a/app/models/dashboard/administrator_task.rb +++ b/app/models/dashboard/administrator_task.rb @@ -6,8 +6,8 @@ class Dashboard::AdministratorTask < ApplicationRecord default_scope { order(created_at: :asc) } - scope :pending, -> { where(executed_at: nil) } scope :done, -> { where.not(executed_at: nil) } + scope :pending, -> { excluding(done) } def title "#{source.proposal.title} #{source.action.title}" diff --git a/app/models/poll.rb b/app/models/poll.rb index 18c78a77d..8f5da2b3e 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -80,7 +80,7 @@ class Poll < ApplicationRecord where("? < ends_at and ? >= starts_at", poll.starts_at.beginning_of_day, poll.ends_at.end_of_day) - .where.not(id: poll.id) + .excluding(poll) .where(related: poll.related) end diff --git a/app/models/poll/question/option.rb b/app/models/poll/question/option.rb index c191c5923..299e764bb 100644 --- a/app/models/poll/question/option.rb +++ b/app/models/poll/question/option.rb @@ -20,7 +20,7 @@ class Poll::Question::Option < ApplicationRecord validates_translation :title, presence: true validates :given_order, presence: true, uniqueness: { scope: :question_id } - scope :with_content, -> { where.not(id: without_content) } + scope :with_content, -> { excluding(without_content) } scope :without_content, -> do where(description: "") .where.missing(:images) diff --git a/app/models/proposal.rb b/app/models/proposal.rb index 634077fe0..6cdcc5979 100644 --- a/app/models/proposal.rb +++ b/app/models/proposal.rb @@ -79,14 +79,14 @@ class Proposal < ApplicationRecord scope :not_archived, -> { where(created_at: Setting.archived_proposals_date_limit..) } scope :last_week, -> { where(created_at: 7.days.ago..) } scope :retired, -> { where.not(retired_at: nil) } - scope :not_retired, -> { where(retired_at: nil) } + scope :not_retired, -> { excluding(retired) } scope :successful, -> { where(cached_votes_up: Proposal.votes_needed_for_success..) } scope :unsuccessful, -> { where(cached_votes_up: ...Proposal.votes_needed_for_success) } scope :public_for_api, -> { all } scope :selected, -> { where(selected: true) } scope :not_selected, -> { where(selected: false) } scope :published, -> { where.not(published_at: nil) } - scope :draft, -> { where(published_at: nil) } + scope :draft, -> { excluding(published) } scope :not_supported_by_user, ->(user) { where.not(id: user.find_voted_items(votable_type: "Proposal")) } scope :created_by, ->(author) { where(author: author) } @@ -108,15 +108,11 @@ class Proposal < ApplicationRecord tagged_with(user.interests, any: true) .where.not(author_id: user.id) .unsuccessful - .not_followed_by_user(user) + .excluding(followed_by_user(user)) .not_archived .not_supported_by_user(user) end - def self.not_followed_by_user(user) - where.not(id: followed_by_user(user).ids) - end - def to_param "#{id}-#{title}".parameterize end diff --git a/app/models/proposal_notification.rb b/app/models/proposal_notification.rb index 5579fd728..7cad3c705 100644 --- a/app/models/proposal_notification.rb +++ b/app/models/proposal_notification.rb @@ -16,7 +16,7 @@ class ProposalNotification < ApplicationRecord scope :sort_by_moderated, -> { reorder(moderated: :desc) } scope :moderated, -> { where(moderated: true) } - scope :not_moderated, -> { where(moderated: false) } + scope :not_moderated, -> { excluding(moderated) } scope :pending_review, -> { moderated.where(ignored_at: nil) } scope :ignored, -> { moderated.where.not(ignored_at: nil) } diff --git a/app/models/user.rb b/app/models/user.rb index 07c05dd05..8ba6d0f4c 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -104,8 +104,8 @@ class User < ApplicationRecord where(document_type: document_type, document_number: document_number) end scope :email_digest, -> { where(email_digest: true) } - scope :active, -> { where(erased_at: nil) } scope :erased, -> { where.not(erased_at: nil) } + scope :active, -> { excluding(erased) } scope :public_for_api, -> { all } scope :by_authors, ->(author_ids) { where(id: author_ids) } scope :by_comments, ->(commentables) do diff --git a/db/dev_seeds/flags.rb b/db/dev_seeds/flags.rb index 582bd088f..dc5db86ab 100644 --- a/db/dev_seeds/flags.rb +++ b/db/dev_seeds/flags.rb @@ -1,19 +1,19 @@ section "Flagging Debates & Comments" do 40.times do debate = Debate.sample - flagger = User.where.not(id: debate.author_id).sample + flagger = User.excluding(debate.author).sample Flag.flag(flagger, debate) end 40.times do comment = Comment.sample - flagger = User.where.not(id: comment.user_id).sample + flagger = User.excluding(comment.user).sample Flag.flag(flagger, comment) end 40.times do proposal = Proposal.sample - flagger = User.where.not(id: proposal.author_id).sample + flagger = User.excluding(proposal.author).sample Flag.flag(flagger, proposal) end end diff --git a/db/dev_seeds/votes.rb b/db/dev_seeds/votes.rb index eb7711136..a91b6d315 100644 --- a/db/dev_seeds/votes.rb +++ b/db/dev_seeds/votes.rb @@ -1,5 +1,5 @@ section "Voting Debates, Proposals & Comments" do - not_org_users = User.where.not(id: User.organizations) + not_org_users = User.excluding(User.organizations) 100.times do voter = not_org_users.level_two_or_three_verified.sample vote = [true, false].sample