Merge pull request #5491 from consuldemocracy/use_rails7.0_methods

Use Rails 7.0 methods to simplify code
This commit is contained in:
Javi Martín
2024-07-22 18:50:41 +02:00
committed by GitHub
20 changed files with 86 additions and 83 deletions

View File

@@ -4,18 +4,18 @@ class Layout::CommonHtmlAttributesComponent < ApplicationComponent
private private
def attributes def attributes
sanitize([dir, lang, html_class].compact.join(" ")) tag.attributes(dir: dir, lang: lang, class: html_class)
end end
def dir def dir
'dir="rtl"' if rtl? "rtl" if rtl?
end end
def lang def lang
"lang=\"#{I18n.locale}\"" I18n.locale
end end
def html_class def html_class
"class=\"tenant-#{Tenant.current_schema}\"" if Rails.application.config.multitenancy "tenant-#{Tenant.current_schema}" if Rails.application.config.multitenancy
end end
end end

View File

@@ -164,7 +164,7 @@ class ProposalsController < ApplicationController
.sort_by_confidence_score .sort_by_confidence_score
.limit(Setting["featured_proposals_number"]) .limit(Setting["featured_proposals_number"])
if @featured_proposals.present? if @featured_proposals.present?
@resources = @resources.where.not(id: @featured_proposals) @resources = @resources.excluding(@featured_proposals)
end end
end end
end end

View File

@@ -24,12 +24,12 @@ module ShiftsHelper
end end
def start_date(polls) def start_date(polls)
start_date = polls.map(&:starts_at).min.to_date start_date = polls.minimum(:starts_at).to_date
[start_date, Date.current].max [start_date, Date.current].max
end end
def end_date(polls) def end_date(polls)
polls.map(&:ends_at).max.to_date polls.maximum(:ends_at).to_date
end end
def officer_select_options(officers) def officer_select_options(officers)

View File

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

View File

@@ -20,7 +20,7 @@ class Banner < ApplicationRecord
has_many :web_sections, through: :sections has_many :web_sections, through: :sections
scope :with_active, -> { where(post_started_at: ..Date.current, post_ended_at: 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 :with_inactive, -> { excluding(with_active) }
scope :in_section, ->(section_name) do scope :in_section, ->(section_name) do
joins(:web_sections, :sections).where("web_sections.name ilike ?", section_name) joins(:web_sections, :sections).where("web_sections.name ilike ?", section_name)
end end

View File

@@ -47,7 +47,7 @@ class Budget < ApplicationRecord
accepts_nested_attributes_for :phases accepts_nested_attributes_for :phases
scope :published, -> { where(published: true) } scope :published, -> { where(published: true) }
scope :drafting, -> { where.not(id: published) } scope :drafting, -> { excluding(published) }
scope :informing, -> { where(phase: "informing") } scope :informing, -> { where(phase: "informing") }
scope :accepting, -> { where(phase: "accepting") } scope :accepting, -> { where(phase: "accepting") }
scope :reviewing, -> { where(phase: "reviewing") } scope :reviewing, -> { where(phase: "reviewing") }

View File

@@ -73,7 +73,7 @@ class Budget
scope :valuation_open, -> { where(valuation_finished: false) } scope :valuation_open, -> { where(valuation_finished: false) }
scope :with_admin, -> { where.not(administrator_id: nil) } 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_group, -> { where(valuator_group_assignments_count: 0) }
scope :without_valuator, -> { without_valuator_group.where(valuator_assignments_count: 0) } scope :without_valuator, -> { without_valuator_group.where(valuator_assignments_count: 0) }
scope :under_valuation, -> { valuation_open.valuating.with_admin } 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 :valuation_finished_feasible, -> { where(valuation_finished: true, feasibility: "feasible") }
scope :feasible, -> { where(feasibility: "feasible") } scope :feasible, -> { where(feasibility: "feasible") }
scope :unfeasible, -> { where(feasibility: "unfeasible") } scope :unfeasible, -> { where(feasibility: "unfeasible") }
scope :not_unfeasible, -> { where.not(feasibility: "unfeasible") } scope :not_unfeasible, -> { excluding(unfeasible) }
scope :undecided, -> { where(feasibility: "undecided") } scope :undecided, -> { where(feasibility: "undecided") }
scope :with_supports, -> { where(cached_votes_up: 1..) } scope :with_supports, -> { where(cached_votes_up: 1..) }

View File

@@ -102,17 +102,11 @@ module Globalizable
translations_foreign_key = reflect_on_association(:translations).foreign_key translations_foreign_key = reflect_on_association(:translations).foreign_key
fallbacks = Globalize.fallbacks(Globalize.locale) fallbacks = Globalize.fallbacks(Globalize.locale)
fallbacks_with_order = fallbacks.map.with_index do |locale, order|
"('#{locale}', #{order})"
end.join(", ")
translations_ids = translation_class translations_ids = translation_class
.select("DISTINCT ON (#{translations_foreign_key}) id") .select("DISTINCT ON (#{translations_foreign_key}) id")
.where(locale: fallbacks) .where(locale: fallbacks)
.joins("LEFT JOIN (VALUES #{fallbacks_with_order}) " \ .order(translations_foreign_key)
"AS locales(name, ordering) " \ .in_order_of(:locale, fallbacks)
"ON locale = locales.name")
.order(translations_foreign_key, "locales.ordering")
with_translations(fallbacks).where("#{translations_table_name}.id": translations_ids) with_translations(fallbacks).where("#{translations_table_name}.id": translations_ids)
end end

View File

@@ -3,7 +3,7 @@ module Verification
included do included do
scope :residence_verified, -> { where.not(residence_verified_at: nil) } 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_and_phone_verified, -> { residence_verified.where.not(confirmed_phone: nil) }
scope :residence_or_phone_unverified, -> { residence_unverified.or(where(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)) } 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) } default_scope { order(created_at: :asc) }
scope :pending, -> { where(executed_at: nil) }
scope :done, -> { where.not(executed_at: nil) } scope :done, -> { where.not(executed_at: nil) }
scope :pending, -> { excluding(done) }
def title def title
"#{source.proposal.title} #{source.action.title}" "#{source.proposal.title} #{source.action.title}"

View File

@@ -54,7 +54,35 @@ class Legislation::Process < ApplicationRecord
validates :"#{phase_name}_end_date", presence: true, if: enabled_attribute validates :"#{phase_name}_end_date", presence: true, if: enabled_attribute
end end
validate :valid_date_ranges validates :end_date,
comparison: {
greater_than_or_equal_to: :start_date,
message: :invalid_date_range
},
allow_blank: true,
if: -> { start_date }
validates :debate_end_date,
comparison: {
greater_than_or_equal_to: :debate_start_date,
message: :invalid_date_range
},
allow_blank: true,
if: -> { debate_start_date }
validates :draft_end_date,
comparison: {
greater_than_or_equal_to: :draft_start_date,
message: :invalid_date_range
},
allow_blank: true,
if: -> { draft_start_date }
validates :allegations_end_date,
comparison: {
greater_than_or_equal_to: :allegations_start_date,
message: :invalid_date_range
},
allow_blank: true,
if: -> { allegations_start_date }
validates :background_color, format: { allow_blank: true, with: ->(*) { CSS_HEX_COLOR }} validates :background_color, format: { allow_blank: true, with: ->(*) { CSS_HEX_COLOR }}
validates :font_color, format: { allow_blank: true, with: ->(*) { CSS_HEX_COLOR }} validates :font_color, format: { allow_blank: true, with: ->(*) { CSS_HEX_COLOR }}
@@ -140,22 +168,4 @@ class Legislation::Process < ApplicationRecord
def self.search(terms) def self.search(terms)
pg_search(terms) pg_search(terms)
end end
private
def valid_date_ranges
if end_date && start_date && end_date < start_date
errors.add(:end_date, :invalid_date_range)
end
if debate_end_date && debate_start_date && debate_end_date < debate_start_date
errors.add(:debate_end_date, :invalid_date_range)
end
if draft_end_date && draft_start_date && draft_end_date < draft_start_date
errors.add(:draft_end_date, :invalid_date_range)
end
if allegations_end_date && allegations_start_date &&
allegations_end_date < allegations_start_date
errors.add(:allegations_end_date, :invalid_date_range)
end
end
end end

View File

@@ -33,10 +33,33 @@ class Poll < ApplicationRecord
belongs_to :budget belongs_to :budget
validates_translation :name, presence: true validates_translation :name, presence: true
validate :date_range
validate :start_date_is_not_past_date, on: :create validates :starts_at, presence: true
validates :ends_at, presence: true
validates :starts_at,
comparison: {
less_than_or_equal_to: :ends_at,
message: ->(*) { I18n.t("errors.messages.invalid_date_range") }
},
allow_blank: true,
if: -> { ends_at }
validates :starts_at,
comparison: {
greater_than_or_equal_to: ->(*) { Time.current },
message: ->(*) { I18n.t("errors.messages.past_date") }
},
allow_blank: true,
on: :create
validates :ends_at,
comparison: {
greater_than_or_equal_to: ->(*) { Time.current },
message: ->(*) { I18n.t("errors.messages.past_date") }
},
on: :update,
if: -> { will_save_change_to_ends_at? }
validate :start_date_change, on: :update validate :start_date_change, on: :update
validate :end_date_is_not_past_date, on: :update
validate :end_date_change, on: :update validate :end_date_change, on: :update
validate :only_one_active, unless: :public? validate :only_one_active, unless: :public?
@@ -80,7 +103,7 @@ class Poll < ApplicationRecord
where("? < ends_at and ? >= starts_at", where("? < ends_at and ? >= starts_at",
poll.starts_at.beginning_of_day, poll.starts_at.beginning_of_day,
poll.ends_at.end_of_day) poll.ends_at.end_of_day)
.where.not(id: poll.id) .excluding(poll)
.where(related: poll.related) .where(related: poll.related)
end end
@@ -162,18 +185,6 @@ class Poll < ApplicationRecord
Poll::Voter.where(poll: self, user: user, origin: "web").exists? Poll::Voter.where(poll: self, user: user, origin: "web").exists?
end end
def date_range
if starts_at.blank? || ends_at.blank? || starts_at > ends_at
errors.add(:starts_at, I18n.t("errors.messages.invalid_date_range"))
end
end
def start_date_is_not_past_date
if starts_at.present? && starts_at < Time.current
errors.add(:starts_at, I18n.t("errors.messages.past_date"))
end
end
def start_date_change def start_date_change
if will_save_change_to_starts_at? if will_save_change_to_starts_at?
if starts_at_in_database < Time.current if starts_at_in_database < Time.current
@@ -184,12 +195,6 @@ class Poll < ApplicationRecord
end end
end end
def end_date_is_not_past_date
if will_save_change_to_ends_at? && ends_at < Time.current
errors.add(:ends_at, I18n.t("errors.messages.past_date"))
end
end
def end_date_change def end_date_change
if will_save_change_to_ends_at? && ends_at_in_database < Time.current if will_save_change_to_ends_at? && ends_at_in_database < Time.current
errors.add(:ends_at, I18n.t("errors.messages.cannot_change_date.poll_ended")) errors.add(:ends_at, I18n.t("errors.messages.cannot_change_date.poll_ended"))

View File

@@ -20,7 +20,7 @@ class Poll::Question::Option < ApplicationRecord
validates_translation :title, presence: true validates_translation :title, presence: true
validates :given_order, presence: true, uniqueness: { scope: :question_id } 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 scope :without_content, -> do
where(description: "") where(description: "")
.where.missing(:images) .where.missing(:images)

View File

@@ -79,14 +79,14 @@ class Proposal < ApplicationRecord
scope :not_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 :last_week, -> { where(created_at: 7.days.ago..) }
scope :retired, -> { where.not(retired_at: nil) } 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 :successful, -> { where(cached_votes_up: Proposal.votes_needed_for_success..) }
scope :unsuccessful, -> { 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 :public_for_api, -> { all }
scope :selected, -> { where(selected: true) } scope :selected, -> { where(selected: true) }
scope :not_selected, -> { where(selected: false) } scope :not_selected, -> { where(selected: false) }
scope :published, -> { where.not(published_at: nil) } 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 :not_supported_by_user, ->(user) { where.not(id: user.find_voted_items(votable_type: "Proposal")) }
scope :created_by, ->(author) { where(author: author) } scope :created_by, ->(author) { where(author: author) }
@@ -108,15 +108,11 @@ class Proposal < ApplicationRecord
tagged_with(user.interests, any: true) tagged_with(user.interests, any: true)
.where.not(author_id: user.id) .where.not(author_id: user.id)
.unsuccessful .unsuccessful
.not_followed_by_user(user) .excluding(followed_by_user(user))
.not_archived .not_archived
.not_supported_by_user(user) .not_supported_by_user(user)
end end
def self.not_followed_by_user(user)
where.not(id: followed_by_user(user).ids)
end
def to_param def to_param
"#{id}-#{title}".parameterize "#{id}-#{title}".parameterize
end end

View File

@@ -16,7 +16,7 @@ class ProposalNotification < ApplicationRecord
scope :sort_by_moderated, -> { reorder(moderated: :desc) } scope :sort_by_moderated, -> { reorder(moderated: :desc) }
scope :moderated, -> { where(moderated: true) } 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 :pending_review, -> { moderated.where(ignored_at: nil) }
scope :ignored, -> { moderated.where.not(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) where(document_type: document_type, document_number: document_number)
end end
scope :email_digest, -> { where(email_digest: true) } scope :email_digest, -> { where(email_digest: true) }
scope :active, -> { where(erased_at: nil) }
scope :erased, -> { where.not(erased_at: nil) } scope :erased, -> { where.not(erased_at: nil) }
scope :active, -> { excluding(erased) }
scope :public_for_api, -> { all } scope :public_for_api, -> { all }
scope :by_authors, ->(author_ids) { where(id: author_ids) } scope :by_authors, ->(author_ids) { where(id: author_ids) }
scope :by_comments, ->(commentables) do scope :by_comments, ->(commentables) do

View File

@@ -1,19 +1,19 @@
section "Flagging Debates & Comments" do section "Flagging Debates & Comments" do
40.times do 40.times do
debate = Debate.sample debate = Debate.sample
flagger = User.where.not(id: debate.author_id).sample flagger = User.excluding(debate.author).sample
Flag.flag(flagger, debate) Flag.flag(flagger, debate)
end end
40.times do 40.times do
comment = Comment.sample comment = Comment.sample
flagger = User.where.not(id: comment.user_id).sample flagger = User.excluding(comment.user).sample
Flag.flag(flagger, comment) Flag.flag(flagger, comment)
end end
40.times do 40.times do
proposal = Proposal.sample proposal = Proposal.sample
flagger = User.where.not(id: proposal.author_id).sample flagger = User.excluding(proposal.author).sample
Flag.flag(flagger, proposal) Flag.flag(flagger, proposal)
end end
end end

View File

@@ -1,5 +1,5 @@
section "Voting Debates, Proposals & Comments" do 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 100.times do
voter = not_org_users.level_two_or_three_verified.sample voter = not_org_users.level_two_or_three_verified.sample
vote = [true, false].sample vote = [true, false].sample

View File

@@ -11,11 +11,7 @@ module FactoryBot
build_class = evaluation.instance_variable_get(:@attribute_assigner) build_class = evaluation.instance_variable_get(:@attribute_assigner)
.instance_variable_get(:@build_class) .instance_variable_get(:@build_class)
timestamps = { created_at: Time.current, updated_at: Time.current }.select do |attribute, _| build_class.insert!(@strategy.result(evaluation))
build_class.has_attribute?(attribute)
end
build_class.insert!(timestamps.merge(@strategy.result(evaluation)))
end end
end end

View File

@@ -24,12 +24,14 @@ describe Poll do
poll.starts_at = nil poll.starts_at = nil
expect(poll).not_to be_valid expect(poll).not_to be_valid
expect(poll.errors[:starts_at]).to eq ["Invalid date range"] expect(poll.errors[:starts_at]).to eq ["can't be blank"]
end end
it "is not valid without an end date" do it "is not valid without an end date" do
poll.ends_at = nil poll.ends_at = nil
expect(poll).not_to be_valid expect(poll).not_to be_valid
expect(poll.errors[:ends_at]).to eq ["can't be blank"]
end end
it "is not valid without a proper start/end date range" do it "is not valid without a proper start/end date range" do