From 8e2bd12c7e65f7fb6519de6bb3ee98a8803efa99 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jul 2024 15:02:48 +0000 Subject: [PATCH 1/3] Bump rubocop-rails from 2.23.1 to 2.25.1 Bumps [rubocop-rails](https://github.com/rubocop/rubocop-rails) from 2.23.1 to 2.25.1. - [Release notes](https://github.com/rubocop/rubocop-rails/releases) - [Changelog](https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop-rails/compare/v2.23.1...v2.25.1) --- updated-dependencies: - dependency-name: rubocop-rails dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index 4f9a7b634..43d0c2236 100644 --- a/Gemfile +++ b/Gemfile @@ -102,7 +102,7 @@ group :development do gem "rubocop-capybara", "~> 2.21.0", require: false gem "rubocop-factory_bot", "~> 2.26.1", require: false gem "rubocop-performance", "~> 1.21.1", require: false - gem "rubocop-rails", "~> 2.23.1", require: false + gem "rubocop-rails", "~> 2.25.1", require: false gem "rubocop-rspec", "~> 2.27.0", require: false gem "rvm1-capistrano3", "~> 1.4.0", require: false gem "spring", "~> 4.2.1" diff --git a/Gemfile.lock b/Gemfile.lock index c54aa8c78..69fd3f656 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -556,11 +556,11 @@ GEM rubocop-performance (1.21.1) rubocop (>= 1.48.1, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) - rubocop-rails (2.23.1) + rubocop-rails (2.25.1) activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 1.33.0, < 2.0) - rubocop-ast (>= 1.30.0, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) rubocop-rspec (2.27.0) rubocop (~> 1.40) rubocop-capybara (~> 2.17) @@ -769,7 +769,7 @@ DEPENDENCIES rubocop-capybara (~> 2.21.0) rubocop-factory_bot (~> 2.26.1) rubocop-performance (~> 1.21.1) - rubocop-rails (~> 2.23.1) + rubocop-rails (~> 2.25.1) rubocop-rspec (~> 2.27.0) rvm1-capistrano3 (~> 1.4.0) sassc-embedded (~> 1.70.1) From fb0c087f95bc474e3fbd17b5b717fc7f690fd3ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Tue, 2 Jul 2024 17:00:29 +0200 Subject: [PATCH 2/3] Add and apply Rails/WhereRange rubocop rule This rule was added in rubocop-rails 2.25.0. Applying it allows us to simplify the code a little bit. For example, now there's no need to specify the `proposals` table in proposal scopes, which was actually causing a bug in the `Legislation::Proposal` model, which was using the `proposals` table instead of the `legislation_proposals` table (but, since we don't use this scope, it didn't affect the application). --- .rubocop.yml | 3 +++ app/lib/score_calculator.rb | 4 ++-- app/models/budget/investment.rb | 2 +- app/models/dashboard/action.rb | 10 +++++----- app/models/debate.rb | 2 +- app/models/legislation/process.rb | 4 ++-- app/models/legislation/proposal.rb | 2 +- app/models/milestone.rb | 2 +- app/models/poll.rb | 2 +- app/models/proposal.rb | 8 ++++---- app/models/user.rb | 12 ++++++------ lib/tasks/files.rake | 4 +--- 12 files changed, 28 insertions(+), 27 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index e6ef500dc..38df2c729 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -517,6 +517,9 @@ Rails/WhereNot: Rails/WhereNotWithMultipleConditions: Enabled: true +Rails/WhereRange: + Enabled: true + RSpec/AroundBlock: Enabled: true diff --git a/app/lib/score_calculator.rb b/app/lib/score_calculator.rb index 179a1efae..71d477e77 100644 --- a/app/lib/score_calculator.rb +++ b/app/lib/score_calculator.rb @@ -4,8 +4,8 @@ module ScoreCalculator period = [1, [max_period, resource_age(resource)].min].max - votes_total = resource.votes_for.where("created_at >= ?", period.days.ago).count - votes_up = resource.get_upvotes.where("created_at >= ?", period.days.ago).count + votes_total = resource.votes_for.where(created_at: period.days.ago..).count + votes_up = resource.get_upvotes.where(created_at: period.days.ago..).count votes_down = votes_total - votes_up votes_score = votes_up - votes_down diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index 5f323b27c..d059d1b37 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -96,7 +96,7 @@ class Budget scope :incompatible, -> { where(incompatible: true) } scope :winners, -> { selected.compatible.where(winner: true) } scope :unselected, -> { not_unfeasible.where(selected: false) } - scope :last_week, -> { where("created_at >= ?", 7.days.ago) } + scope :last_week, -> { where(created_at: 7.days.ago..) } scope :sort_by_flags, -> { order(flags_count: :desc, updated_at: :desc) } scope :sort_by_created_at, -> { reorder(created_at: :desc) } scope :sort_by_ballot_lines, -> { order(:"budget_ballot_lines.created_at") } diff --git a/app/models/dashboard/action.rb b/app/models/dashboard/action.rb index fe29b3649..cfac18315 100644 --- a/app/models/dashboard/action.rb +++ b/app/models/dashboard/action.rb @@ -39,8 +39,8 @@ class Dashboard::Action < ApplicationRecord def self.active_for(proposal) published_at = proposal.published_at&.to_date || Date.current - active.where("required_supports <= ?", proposal.cached_votes_up) - .where("day_offset <= ?", (Date.current - published_at).to_i) + active.where(required_supports: ..proposal.cached_votes_up) + .where(day_offset: ..(Date.current - published_at).to_i) .by_proposal(proposal) end @@ -105,12 +105,12 @@ class Dashboard::Action < ApplicationRecord def self.calculate_actions(proposal_votes, day_offset, proposal) Dashboard::Action.active - .where("required_supports <= ?", proposal_votes) - .where("day_offset <= ?", day_offset) + .where(required_supports: ..proposal_votes) + .where(day_offset: ..day_offset) .by_published_proposal(proposal.published?) end def self.calculate_votes(proposal, date) - Vote.where(votable: proposal).where("created_at <= ?", date).count + Vote.where(votable: proposal).where(created_at: ..date).count end end diff --git a/app/models/debate.rb b/app/models/debate.rb index a6185beac..7cba511d8 100644 --- a/app/models/debate.rb +++ b/app/models/debate.rb @@ -42,7 +42,7 @@ class Debate < ApplicationRecord scope :sort_by_relevance, -> { all } scope :sort_by_flags, -> { order(flags_count: :desc, updated_at: :desc) } scope :sort_by_recommendations, -> { order(cached_votes_total: :desc) } - scope :last_week, -> { where("created_at >= ?", 7.days.ago) } + scope :last_week, -> { where(created_at: 7.days.ago..) } scope :featured, -> { where.not(featured_at: nil) } scope :public_for_api, -> { all } diff --git a/app/models/legislation/process.rb b/app/models/legislation/process.rb index 48c41a894..85fc943d8 100644 --- a/app/models/legislation/process.rb +++ b/app/models/legislation/process.rb @@ -60,8 +60,8 @@ class Legislation::Process < ApplicationRecord class << self; undef :open; end scope :open, -> { where("start_date <= ? and end_date >= ?", Date.current, Date.current) } - scope :active, -> { where("end_date >= ?", Date.current) } - scope :past, -> { where("end_date < ?", Date.current) } + scope :active, -> { where(end_date: Date.current..) } + scope :past, -> { where(end_date: ...Date.current) } scope :published, -> { where(published: true) } diff --git a/app/models/legislation/proposal.rb b/app/models/legislation/proposal.rb index 497cea5db..d1765e503 100644 --- a/app/models/legislation/proposal.rb +++ b/app/models/legislation/proposal.rb @@ -48,7 +48,7 @@ class Legislation::Proposal < ApplicationRecord scope :sort_by_id, -> { reorder(id: :asc) } scope :sort_by_supports, -> { reorder(cached_votes_score: :desc) } scope :sort_by_flags, -> { order(flags_count: :desc, updated_at: :desc) } - scope :last_week, -> { where("proposals.created_at >= ?", 7.days.ago) } + scope :last_week, -> { where(created_at: 7.days.ago..) } scope :selected, -> { where(selected: true) } scope :winners, -> { selected.sort_by_confidence_score } diff --git a/app/models/milestone.rb b/app/models/milestone.rb index 0498d24c4..47d2d2d03 100644 --- a/app/models/milestone.rb +++ b/app/models/milestone.rb @@ -14,7 +14,7 @@ class Milestone < ApplicationRecord validates_translation :description, presence: true, unless: -> { status_id.present? } scope :order_by_publication_date, -> { order(publication_date: :asc, created_at: :asc) } - scope :published, -> { where("publication_date <= ?", Date.current.end_of_day) } + scope :published, -> { where(publication_date: ..Date.current.end_of_day) } scope :with_status, -> { where.not(status_id: nil) } def self.title_max_length diff --git a/app/models/poll.rb b/app/models/poll.rb index 847eacf35..a1b294592 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -44,7 +44,7 @@ class Poll < ApplicationRecord scope :for, ->(element) { where(related: element) } scope :current, -> { where("starts_at <= :time and ends_at >= :time", time: Time.current) } - scope :expired, -> { where("ends_at < ?", Time.current) } + scope :expired, -> { where(ends_at: ...Time.current) } scope :recounting, -> { where(ends_at: (RECOUNT_DURATION.ago)...Time.current) } scope :published, -> { where(published: true) } scope :by_geozone_id, ->(geozone_id) { where(geozones: { id: geozone_id }.joins(:geozones)) } diff --git a/app/models/proposal.rb b/app/models/proposal.rb index ca4518b07..3a4849d44 100644 --- a/app/models/proposal.rb +++ b/app/models/proposal.rb @@ -75,13 +75,13 @@ class Proposal < ApplicationRecord scope :sort_by_archival_date, -> { archived.sort_by_confidence_score } scope :sort_by_recommendations, -> { order(cached_votes_up: :desc) } - scope :archived, -> { where("proposals.created_at <= ?", Setting.archived_proposals_date_limit) } + scope :archived, -> { where(created_at: ..Setting.archived_proposals_date_limit) } scope :not_archived, -> { where("proposals.created_at > ?", Setting.archived_proposals_date_limit) } - scope :last_week, -> { where("proposals.created_at >= ?", 7.days.ago) } + scope :last_week, -> { where(created_at: 7.days.ago..) } scope :retired, -> { where.not(retired_at: nil) } scope :not_retired, -> { where(retired_at: nil) } - scope :successful, -> { where("cached_votes_up >= ?", Proposal.votes_needed_for_success) } - scope :unsuccessful, -> { where("cached_votes_up < ?", Proposal.votes_needed_for_success) } + 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) } diff --git a/app/models/user.rb b/app/models/user.rb index dd24f20f6..2c1104e39 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -233,13 +233,13 @@ class User < ApplicationRecord def full_restore ActiveRecord::Base.transaction do - Debate.restore_all debates.where("hidden_at >= ?", hidden_at) - Comment.restore_all comments.where("hidden_at >= ?", hidden_at) - Legislation::Proposal.restore_all legislation_proposals.only_hidden.where("hidden_at >= ?", hidden_at) - Proposal.restore_all proposals.where("hidden_at >= ?", hidden_at) - Budget::Investment.restore_all budget_investments.where("hidden_at >= ?", hidden_at) + Debate.restore_all debates.where(hidden_at: hidden_at..) + Comment.restore_all comments.where(hidden_at: hidden_at..) + Legislation::Proposal.restore_all legislation_proposals.only_hidden.where(hidden_at: hidden_at..) + Proposal.restore_all proposals.where(hidden_at: hidden_at..) + Budget::Investment.restore_all budget_investments.where(hidden_at: hidden_at..) ProposalNotification.restore_all( - ProposalNotification.only_hidden.where("hidden_at >= ?", hidden_at).where(author_id: id) + ProposalNotification.only_hidden.where(hidden_at: hidden_at..).where(author_id: id) ) restore diff --git a/lib/tasks/files.rake b/lib/tasks/files.rake index 929eaa951..f1ecd10d2 100644 --- a/lib/tasks/files.rake +++ b/lib/tasks/files.rake @@ -2,9 +2,7 @@ namespace :files do desc "Removes cached attachments which weren't deleted for some reason" task remove_old_cached_attachments: :environment do Tenant.run_on_each do - ActiveStorage::Blob.unattached - .where("active_storage_blobs.created_at <= ?", 1.day.ago) - .find_each(&:purge_later) + ActiveStorage::Blob.unattached.where(created_at: ..1.day.ago).find_each(&:purge_later) end end end From 2abe9f27b50353bc4d99aa22e0bb92ed1117224e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Tue, 2 Jul 2024 17:23:34 +0200 Subject: [PATCH 3/3] Use ranges instead of comparisons in SQL queries These cases aren't covered by the `Rails/WhereRange` rubocop rule, but IMHO using ranges makes them more consistent. Besides, they generate SQL which is more consistent with what Rails usually generates. For example, `Poll.where("starts_at <= :time and ends_at >= :time", time: Time.current)` generates: ``` SELECT \"polls\".\"id\", (...) WHERE \"polls\".\"hidden_at\" IS NULL AND (starts_at <= '2024-07-(...)' and ends_at >= '2024-07-(...)') ``` And `Poll.where(starts_at: ..Time.current, ends_at: Time.current..)` generates: ``` SELECT \"polls\".\"id\", (...) WHERE \"polls\".\"hidden_at\" IS NULL AND \"polls\".\"starts_at\" <= '2024-07-(...)' AND \"polls\".\"ends_at\" >= '2024-07-(...)'" ``` Note that the `not_archived` scope in proposals slightly changes, since we were using `>` and now we use the equivalent of `>=`. However, since the `created_at` field is a time, this will only mean that a proposal will be archived about one microsecond later. For consistency, we're also changing the `archived` scope, so a proposal is never archived and not archived at the same time (not even for a microsecond). --- app/models/banner.rb | 2 +- app/models/budget/investment.rb | 6 +++--- app/models/budget/stats.rb | 2 +- app/models/concerns/flaggable.rb | 2 +- app/models/concerns/verification.rb | 2 +- app/models/legislation/process.rb | 2 +- app/models/poll.rb | 2 +- app/models/proposal.rb | 4 ++-- app/models/user.rb | 2 +- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/models/banner.rb b/app/models/banner.rb index 9a8a1ebe4..ea3a9b513 100644 --- a/app/models/banner.rb +++ b/app/models/banner.rb @@ -19,7 +19,7 @@ class Banner < ApplicationRecord has_many :sections has_many :web_sections, through: :sections - scope :with_active, -> { where("post_started_at <= :date and post_ended_at >= :date", date: Date.current) } + scope :with_active, -> { where(post_started_at: ..Date.current, post_ended_at: Date.current..) } scope :with_inactive, -> { where.not(id: with_active) } scope :in_section, ->(section_name) do joins(:web_sections, :sections).where("web_sections.name ilike ?", section_name) diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index d059d1b37..53b8c196c 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -78,8 +78,8 @@ class Budget scope :without_valuator, -> { without_valuator_group.where(valuator_assignments_count: 0) } scope :under_valuation, -> { valuation_open.valuating.with_admin } scope :managed, -> { valuation_open.where(valuator_assignments_count: 0).with_admin } - scope :with_valuator_assignments, -> { where("valuator_assignments_count > 0") } - scope :with_group_assignments, -> { where("valuator_group_assignments_count > 0") } + scope :with_valuator_assignments, -> { where(valuator_assignments_count: 1..) } + scope :with_group_assignments, -> { where(valuator_group_assignments_count: 1..) } scope :with_valuation_assignments, -> { with_valuator_assignments.or(with_group_assignments) } scope :valuating, -> { valuation_open.with_valuation_assignments } scope :visible_to_valuators, -> { where(visible_to_valuators: true) } @@ -90,7 +90,7 @@ class Budget scope :not_unfeasible, -> { where.not(feasibility: "unfeasible") } scope :undecided, -> { where(feasibility: "undecided") } - scope :with_supports, -> { where("cached_votes_up > 0") } + scope :with_supports, -> { where(cached_votes_up: 1..) } scope :selected, -> { feasible.where(selected: true) } scope :compatible, -> { where(incompatible: false) } scope :incompatible, -> { where(incompatible: true) } diff --git a/app/models/budget/stats.rb b/app/models/budget/stats.rb index d03e4edd3..33e45b211 100644 --- a/app/models/budget/stats.rb +++ b/app/models/budget/stats.rb @@ -131,7 +131,7 @@ class Budget::Stats end def balloters - @balloters ||= budget.ballots.where("ballot_lines_count > ?", 0).distinct.pluck(:user_id).compact + @balloters ||= budget.ballots.where(ballot_lines_count: 1..).distinct.pluck(:user_id).compact end def poll_ballot_voters diff --git a/app/models/concerns/flaggable.rb b/app/models/concerns/flaggable.rb index 650f679a0..8ca668dc7 100644 --- a/app/models/concerns/flaggable.rb +++ b/app/models/concerns/flaggable.rb @@ -3,7 +3,7 @@ module Flaggable included do has_many :flags, as: :flaggable, inverse_of: :flaggable - scope :flagged, -> { where("flags_count > 0") } + scope :flagged, -> { where(flags_count: 1..) } scope :pending_flag_review, -> { flagged.where(ignored_flag_at: nil, hidden_at: nil) } scope :with_ignored_flag, -> { flagged.where.not(ignored_flag_at: nil).where(hidden_at: nil) } end diff --git a/app/models/concerns/verification.rb b/app/models/concerns/verification.rb index 563f2b6bb..298c44b4d 100644 --- a/app/models/concerns/verification.rb +++ b/app/models/concerns/verification.rb @@ -17,7 +17,7 @@ module Verification residence_or_phone_unverified.where(verified_at: nil, level_two_verified_at: nil) end scope :incomplete_verification, -> do - residence_unverified.where("failed_census_calls_count > ?", 0) + residence_unverified.where(failed_census_calls_count: 1..) .or(residence_verified.phone_not_fully_confirmed) end end diff --git a/app/models/legislation/process.rb b/app/models/legislation/process.rb index 85fc943d8..a57f53564 100644 --- a/app/models/legislation/process.rb +++ b/app/models/legislation/process.rb @@ -59,8 +59,8 @@ class Legislation::Process < ApplicationRecord validates :font_color, format: { allow_blank: true, with: ->(*) { CSS_HEX_COLOR }} class << self; undef :open; end - scope :open, -> { where("start_date <= ? and end_date >= ?", Date.current, Date.current) } scope :active, -> { where(end_date: Date.current..) } + scope :open, -> { active.where(start_date: ..Date.current) } scope :past, -> { where(end_date: ...Date.current) } scope :published, -> { where(published: true) } diff --git a/app/models/poll.rb b/app/models/poll.rb index a1b294592..18c78a77d 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -43,7 +43,7 @@ class Poll < ApplicationRecord accepts_nested_attributes_for :questions, reject_if: :all_blank, allow_destroy: true scope :for, ->(element) { where(related: element) } - scope :current, -> { where("starts_at <= :time and ends_at >= :time", time: Time.current) } + scope :current, -> { where(starts_at: ..Time.current, ends_at: Time.current..) } scope :expired, -> { where(ends_at: ...Time.current) } scope :recounting, -> { where(ends_at: (RECOUNT_DURATION.ago)...Time.current) } scope :published, -> { where(published: true) } diff --git a/app/models/proposal.rb b/app/models/proposal.rb index 3a4849d44..634077fe0 100644 --- a/app/models/proposal.rb +++ b/app/models/proposal.rb @@ -75,8 +75,8 @@ class Proposal < ApplicationRecord scope :sort_by_archival_date, -> { archived.sort_by_confidence_score } scope :sort_by_recommendations, -> { order(cached_votes_up: :desc) } - scope :archived, -> { where(created_at: ..Setting.archived_proposals_date_limit) } - scope :not_archived, -> { where("proposals.created_at > ?", Setting.archived_proposals_date_limit) } + scope :archived, -> { where(created_at: ...Setting.archived_proposals_date_limit) } + 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) } diff --git a/app/models/user.rb b/app/models/user.rb index 2c1104e39..07c05dd05 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -95,7 +95,7 @@ class User < ApplicationRecord scope :moderators, -> { joins(:moderator) } scope :organizations, -> { joins(:organization) } scope :sdg_managers, -> { joins(:sdg_manager) } - scope :officials, -> { where("official_level > 0") } + scope :officials, -> { where(official_level: 1..) } scope :male, -> { where(gender: "male") } scope :female, -> { where(gender: "female") } scope :newsletter, -> { where(newsletter: true) }