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.
This commit is contained in:
Javi Martín
2024-04-06 18:51:52 +02:00
parent 9841a9b03a
commit 38ad65605e
14 changed files with 19 additions and 23 deletions

View File

@@ -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

View File

@@ -43,7 +43,7 @@ module ActsAsParanoidAliases
end
def without_confirmed_hide
where(confirmed_hide_at: nil)
excluding(with_confirmed_hide)
end
def with_hidden

View File

@@ -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

View File

@@ -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") }

View File

@@ -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..) }

View File

@@ -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)) }

View File

@@ -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}"

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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) }

View File

@@ -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

View File

@@ -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

View File

@@ -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