about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/controllers/activitypub/inboxes_controller.rb10
-rw-r--r--app/controllers/api/v1/accounts_controller.rb2
-rw-r--r--app/controllers/api/v1/crypto/keys/claims_controller.rb2
-rw-r--r--app/controllers/api/v1/crypto/keys/queries_controller.rb2
-rw-r--r--app/controllers/concerns/cache_concern.rb2
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js2
-rw-r--r--app/javascript/mastodon/features/ui/components/focal_point_modal.js2
-rw-r--r--app/lib/activitypub/activity/flag.rb4
-rw-r--r--app/lib/entity_cache.rb2
-rw-r--r--app/lib/spam_check.rb4
-rw-r--r--app/models/account.rb36
-rw-r--r--app/models/concerns/status_threading_concern.rb2
-rw-r--r--app/models/custom_filter.rb2
-rw-r--r--app/models/home_feed.rb5
-rw-r--r--app/models/list_feed.rb3
-rw-r--r--app/models/notification.rb2
-rw-r--r--app/models/poll.rb10
-rw-r--r--app/models/public_feed.rb26
-rw-r--r--app/models/status.rb4
-rw-r--r--app/models/tag_feed.rb11
-rw-r--r--app/presenters/status_relationships_presenter.rb2
-rw-r--r--app/services/activitypub/fetch_featured_collection_service.rb3
-rw-r--r--app/services/activitypub/process_collection_service.rb2
-rw-r--r--app/services/activitypub/process_poll_service.rb2
-rw-r--r--app/services/activitypub/synchronize_followers_service.rb2
-rw-r--r--app/services/fetch_link_card_service.rb2
-rw-r--r--app/services/import_service.rb4
-rw-r--r--app/services/keys/claim_service.rb12
-rw-r--r--app/services/keys/query_service.rb18
-rw-r--r--app/validators/existing_username_validator.rb2
30 files changed, 90 insertions, 92 deletions
diff --git a/app/controllers/activitypub/inboxes_controller.rb b/app/controllers/activitypub/inboxes_controller.rb
index d3044f180..92dcb5ac7 100644
--- a/app/controllers/activitypub/inboxes_controller.rb
+++ b/app/controllers/activitypub/inboxes_controller.rb
@@ -5,7 +5,7 @@ class ActivityPub::InboxesController < ActivityPub::BaseController
   include JsonLdHelper
   include AccountOwnedConcern
 
-  before_action :skip_unknown_actor_delete
+  before_action :skip_unknown_actor_activity
   before_action :require_signature!
   skip_before_action :authenticate_user!
 
@@ -18,13 +18,13 @@ class ActivityPub::InboxesController < ActivityPub::BaseController
 
   private
 
-  def skip_unknown_actor_delete
-    head 202 if unknown_deleted_account?
+  def skip_unknown_actor_activity
+    head 202 if unknown_affected_account?
   end
 
-  def unknown_deleted_account?
+  def unknown_affected_account?
     json = Oj.load(body, mode: :strict)
-    json.is_a?(Hash) && json['type'] == 'Delete' && json['actor'].present? && json['actor'] == value_or_id(json['object']) && !Account.where(uri: json['actor']).exists?
+    json.is_a?(Hash) && %w(Delete Update).include?(json['type']) && json['actor'].present? && json['actor'] == value_or_id(json['object']) && !Account.where(uri: json['actor']).exists?
   rescue Oj::ParseError
     false
   end
diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb
index 3e66ff212..953874e1a 100644
--- a/app/controllers/api/v1/accounts_controller.rb
+++ b/app/controllers/api/v1/accounts_controller.rb
@@ -42,7 +42,7 @@ class Api::V1::AccountsController < Api::BaseController
   end
 
   def mute
-    MuteService.new.call(current_user.account, @account, notifications: truthy_param?(:notifications), duration: (params[:duration] || 0))
+    MuteService.new.call(current_user.account, @account, notifications: truthy_param?(:notifications), duration: (params[:duration]&.to_i || 0))
     render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships
   end
 
diff --git a/app/controllers/api/v1/crypto/keys/claims_controller.rb b/app/controllers/api/v1/crypto/keys/claims_controller.rb
index 34b21a380..f9d202d67 100644
--- a/app/controllers/api/v1/crypto/keys/claims_controller.rb
+++ b/app/controllers/api/v1/crypto/keys/claims_controller.rb
@@ -12,7 +12,7 @@ class Api::V1::Crypto::Keys::ClaimsController < Api::BaseController
   private
 
   def set_claim_results
-    @claim_results = devices.map { |device_params| ::Keys::ClaimService.new.call(current_account, device_params[:account_id], device_params[:device_id]) }.compact
+    @claim_results = devices.filter_map { |device_params| ::Keys::ClaimService.new.call(current_account, device_params[:account_id], device_params[:device_id]) }
   end
 
   def resource_params
diff --git a/app/controllers/api/v1/crypto/keys/queries_controller.rb b/app/controllers/api/v1/crypto/keys/queries_controller.rb
index 0851d797d..e6ce9f919 100644
--- a/app/controllers/api/v1/crypto/keys/queries_controller.rb
+++ b/app/controllers/api/v1/crypto/keys/queries_controller.rb
@@ -17,7 +17,7 @@ class Api::V1::Crypto::Keys::QueriesController < Api::BaseController
   end
 
   def set_query_results
-    @query_results = @accounts.map { |account| ::Keys::QueryService.new.call(account) }.compact
+    @query_results = @accounts.filter_map { |account| ::Keys::QueryService.new.call(account) }
   end
 
   def account_ids
diff --git a/app/controllers/concerns/cache_concern.rb b/app/controllers/concerns/cache_concern.rb
index abbdb410a..8d82eda5c 100644
--- a/app/controllers/concerns/cache_concern.rb
+++ b/app/controllers/concerns/cache_concern.rb
@@ -45,7 +45,7 @@ module CacheConcern
       end
     end
 
-    raw.map { |item| cached_keys_with_value[item.id] || uncached[item.id] }.compact
+    raw.filter_map { |item| cached_keys_with_value[item.id] || uncached[item.id] }
   end
 
   def cache_collection_paginated_by_id(raw, klass, limit, options)
diff --git a/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js b/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js
index 87a7de851..915e26718 100644
--- a/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js
+++ b/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js
@@ -227,7 +227,7 @@ class FocalPointModal extends ImmutablePureComponent {
       const worker = createWorker({
         workerPath: tesseractWorkerPath,
         corePath: tesseractCorePath,
-        langPath: assetHost,
+        langPath: `${assetHost}/ocr/lang-data/`,
         logger: ({ status, progress }) => {
           if (status === 'recognizing text') {
             this.setState({ ocrStatus: 'detecting', progress });
diff --git a/app/javascript/mastodon/features/ui/components/focal_point_modal.js b/app/javascript/mastodon/features/ui/components/focal_point_modal.js
index 578375a7f..ffa783e3b 100644
--- a/app/javascript/mastodon/features/ui/components/focal_point_modal.js
+++ b/app/javascript/mastodon/features/ui/components/focal_point_modal.js
@@ -227,7 +227,7 @@ class FocalPointModal extends ImmutablePureComponent {
       const worker = createWorker({
         workerPath: tesseractWorkerPath,
         corePath: tesseractCorePath,
-        langPath: assetHost,
+        langPath: `${assetHost}/ocr/lang-data/`,
         logger: ({ status, progress }) => {
           if (status === 'recognizing text') {
             this.setState({ ocrStatus: 'detecting', progress });
diff --git a/app/lib/activitypub/activity/flag.rb b/app/lib/activitypub/activity/flag.rb
index 1659bc61f..8dfc76f0a 100644
--- a/app/lib/activitypub/activity/flag.rb
+++ b/app/lib/activitypub/activity/flag.rb
@@ -4,8 +4,8 @@ class ActivityPub::Activity::Flag < ActivityPub::Activity
   def perform
     return if skip_reports?
 
-    target_accounts            = object_uris.map { |uri| account_from_uri(uri) }.compact.select(&:local?)
-    target_statuses_by_account = object_uris.map { |uri| status_from_uri(uri) }.compact.select(&:local?).group_by(&:account_id)
+    target_accounts            = object_uris.filter_map { |uri| account_from_uri(uri) }.select(&:local?)
+    target_statuses_by_account = object_uris.filter_map { |uri| status_from_uri(uri) }.select(&:local?).group_by(&:account_id)
 
     target_accounts.each do |target_account|
       target_statuses = target_statuses_by_account[target_account.id]
diff --git a/app/lib/entity_cache.rb b/app/lib/entity_cache.rb
index 89cbf8d2c..e38a3adcd 100644
--- a/app/lib/entity_cache.rb
+++ b/app/lib/entity_cache.rb
@@ -29,7 +29,7 @@ class EntityCache
       uncached.each_value { |item| Rails.cache.write(to_key(:emoji, item.shortcode, domain), item, expires_in: MAX_EXPIRATION) }
     end
 
-    shortcodes.map { |shortcode| cached[to_key(:emoji, shortcode, domain)] || uncached[shortcode] }.compact
+    shortcodes.filter_map { |shortcode| cached[to_key(:emoji, shortcode, domain)] || uncached[shortcode] }
   end
 
   def to_key(type, *ids)
diff --git a/app/lib/spam_check.rb b/app/lib/spam_check.rb
index 652d03615..68e586d00 100644
--- a/app/lib/spam_check.rb
+++ b/app/lib/spam_check.rb
@@ -186,9 +186,9 @@ class SpamCheck
 
   def matching_status_ids
     if nilsimsa?
-      other_digests.select { |record| record.start_with?('nilsimsa') && nilsimsa_compare_value(digest, record.split(':')[1]) >= NILSIMSA_COMPARE_THRESHOLD }.map { |record| record.split(':')[2] }.compact
+      other_digests.select { |record| record.start_with?('nilsimsa') && nilsimsa_compare_value(digest, record.split(':')[1]) >= NILSIMSA_COMPARE_THRESHOLD }.filter_map { |record| record.split(':')[2] }
     else
-      other_digests.select { |record| record.start_with?('md5') && record.split(':')[1] == digest }.map { |record| record.split(':')[2] }.compact
+      other_digests.select { |record| record.start_with?('md5') && record.split(':')[1] == digest }.filter_map { |record| record.split(':')[2] }
     end
   end
 
diff --git a/app/models/account.rb b/app/models/account.rb
index f6aba74c6..15bd8a917 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -387,15 +387,17 @@ class Account < ApplicationRecord
   end
 
   class Field < ActiveModelSerializers::Model
-    attributes :name, :value, :verified_at, :account, :errors
+    attributes :name, :value, :verified_at, :account
 
     def initialize(account, attributes)
-      @account     = account
-      @attributes  = attributes
-      @name        = attributes['name'].strip[0, string_limit]
-      @value       = attributes['value'].strip[0, string_limit]
-      @verified_at = attributes['verified_at']&.to_datetime
-      @errors      = {}
+      @original_field = attributes
+      string_limit = account.local? ? 255 : 2047
+      super(
+        account:     account,
+        name:        attributes['name'].strip[0, string_limit],
+        value:       attributes['value'].strip[0, string_limit],
+        verified_at: attributes['verified_at']&.to_datetime,
+      )
     end
 
     def verified?
@@ -417,22 +419,12 @@ class Account < ApplicationRecord
     end
 
     def mark_verified!
-      @verified_at = Time.now.utc
-      @attributes['verified_at'] = @verified_at
+      self.verified_at = Time.now.utc
+      @original_field['verified_at'] = verified_at
     end
 
     def to_h
-      { name: @name, value: @value, verified_at: @verified_at }
-    end
-
-    private
-
-    def string_limit
-      if account.local?
-        255
-      else
-        2047
-      end
+      { name: name, value: value, verified_at: verified_at }
     end
   end
 
@@ -518,7 +510,7 @@ class Account < ApplicationRecord
     def from_text(text)
       return [] if text.blank?
 
-      text.scan(MENTION_RE).map { |match| match.first.split('@', 2) }.uniq.map do |(username, domain)|
+      text.scan(MENTION_RE).map { |match| match.first.split('@', 2) }.uniq.filter_map do |(username, domain)|
         domain = begin
           if TagManager.instance.local_domain?(domain)
             nil
@@ -527,7 +519,7 @@ class Account < ApplicationRecord
           end
         end
         EntityCache.instance.mention(username, domain)
-      end.compact
+      end
     end
 
     private
diff --git a/app/models/concerns/status_threading_concern.rb b/app/models/concerns/status_threading_concern.rb
index a0ead1995..5c04108e4 100644
--- a/app/models/concerns/status_threading_concern.rb
+++ b/app/models/concerns/status_threading_concern.rb
@@ -83,7 +83,7 @@ module StatusThreadingConcern
   def find_statuses_from_tree_path(ids, account, promote: false)
     statuses    = Status.with_accounts(ids).to_a
     account_ids = statuses.map(&:account_id).uniq
-    domains     = statuses.map(&:account_domain).compact.uniq
+    domains     = statuses.filter_map(&:account_domain).uniq
     relations   = relations_map_for_account(account, account_ids, domains)
 
     statuses.reject! { |status| StatusFilter.new(status, account, relations).filtered? }
diff --git a/app/models/custom_filter.rb b/app/models/custom_filter.rb
index 8df8a4fbf..9d0f3729b 100644
--- a/app/models/custom_filter.rb
+++ b/app/models/custom_filter.rb
@@ -46,7 +46,7 @@ class CustomFilter < ApplicationRecord
   private
 
   def clean_up_contexts
-    self.context = Array(context).map(&:strip).map(&:presence).compact
+    self.context = Array(context).map(&:strip).filter_map(&:presence)
   end
 
   def remove_cache
diff --git a/app/models/home_feed.rb b/app/models/home_feed.rb
index 0fe9dae46..d6ebb5fa6 100644
--- a/app/models/home_feed.rb
+++ b/app/models/home_feed.rb
@@ -2,12 +2,11 @@
 
 class HomeFeed < Feed
   def initialize(account)
-    @type    = :home
-    @id      = account.id
     @account = account
+    super(:home, account.id)
   end
 
   def regenerating?
-    redis.exists?("account:#{@id}:regeneration")
+    redis.exists?("account:#{@account.id}:regeneration")
   end
 end
diff --git a/app/models/list_feed.rb b/app/models/list_feed.rb
index f371e4ed9..47b9281b8 100644
--- a/app/models/list_feed.rb
+++ b/app/models/list_feed.rb
@@ -2,7 +2,6 @@
 
 class ListFeed < Feed
   def initialize(list)
-    @type    = :list
-    @id      = list.id
+    super(:list, list.id)
   end
 end
diff --git a/app/models/notification.rb b/app/models/notification.rb
index e83123c97..b6db37d6d 100644
--- a/app/models/notification.rb
+++ b/app/models/notification.rb
@@ -92,7 +92,7 @@ class Notification < ApplicationRecord
     end
 
     def reload_stale_associations!(cached_items)
-      account_ids = (cached_items.map(&:from_account_id) + cached_items.map { |item| item.target_status&.account_id }.compact).uniq
+      account_ids = (cached_items.map(&:from_account_id) + cached_items.filter_map { |item| item.target_status&.account_id }).uniq
 
       return if account_ids.empty?
 
diff --git a/app/models/poll.rb b/app/models/poll.rb
index e1ca55252..d2a17277b 100644
--- a/app/models/poll.rb
+++ b/app/models/poll.rb
@@ -73,10 +73,12 @@ class Poll < ApplicationRecord
     attributes :id, :title, :votes_count, :poll
 
     def initialize(poll, id, title, votes_count)
-      @poll        = poll
-      @id          = id
-      @title       = title
-      @votes_count = votes_count
+      super(
+        poll:        poll,
+        id:          id,
+        title:       title,
+        votes_count: votes_count,
+      )
     end
   end
 
diff --git a/app/models/public_feed.rb b/app/models/public_feed.rb
index 2839da5cb..2528ef1b6 100644
--- a/app/models/public_feed.rb
+++ b/app/models/public_feed.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-class PublicFeed < Feed
+class PublicFeed
   # @param [Account] account
   # @param [Hash] options
   # @option [Boolean] :with_replies
@@ -35,36 +35,38 @@ class PublicFeed < Feed
 
   private
 
+  attr_reader :account, :options
+
   def allow_local_only?
-    local_account? && (local_only? || @options[:allow_local_only])
+    local_account? && (local_only? || options[:allow_local_only])
   end
 
   def with_reblogs?
-    @options[:with_reblogs]
+    options[:with_reblogs]
   end
 
   def with_replies?
-    @options[:with_replies]
+    options[:with_replies]
   end
 
   def local_only?
-    @options[:local]
+    options[:local]
   end
 
   def remote_only?
-    @options[:remote]
+    options[:remote]
   end
 
   def account?
-    @account.present?
+    account.present?
   end
 
   def local_account?
-    @account&.local?
+    account&.local?
   end
 
   def media_only?
-    @options[:only_media]
+    options[:only_media]
   end
 
   def public_scope
@@ -96,9 +98,9 @@ class PublicFeed < Feed
   end
 
   def account_filters_scope
-    Status.not_excluded_by_account(@account).tap do |scope|
-      scope.merge!(Status.not_domain_blocked_by_account(@account)) unless local_only?
-      scope.merge!(Status.in_chosen_languages(@account)) if @account.chosen_languages.present?
+    Status.not_excluded_by_account(account).tap do |scope|
+      scope.merge!(Status.not_domain_blocked_by_account(account)) unless local_only?
+      scope.merge!(Status.in_chosen_languages(account)) if account.chosen_languages.present?
     end
   end
 end
diff --git a/app/models/status.rb b/app/models/status.rb
index 0d15304b6..766c13a40 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -387,7 +387,7 @@ class Status < ApplicationRecord
     def from_text(text)
       return [] if text.blank?
 
-      text.scan(FetchLinkCardService::URL_PATTERN).map(&:first).uniq.map do |url|
+      text.scan(FetchLinkCardService::URL_PATTERN).map(&:first).uniq.filter_map do |url|
         status = begin
           if TagManager.instance.local_url?(url)
             ActivityPub::TagManager.instance.uri_to_resource(url, Status)
@@ -396,7 +396,7 @@ class Status < ApplicationRecord
           end
         end
         status&.distributable? ? status : nil
-      end.compact
+      end
     end
   end
 
diff --git a/app/models/tag_feed.rb b/app/models/tag_feed.rb
index a7d583a7e..fbbdbaae2 100644
--- a/app/models/tag_feed.rb
+++ b/app/models/tag_feed.rb
@@ -13,9 +13,8 @@ class TagFeed < PublicFeed
   # @option [Boolean] :remote
   # @option [Boolean] :only_media
   def initialize(tag, account, options = {})
-    @tag     = tag
-    @account = account
-    @options = options
+    @tag = tag
+    super(account, options)
   end
 
   # @param [Integer] limit
@@ -41,15 +40,15 @@ class TagFeed < PublicFeed
   private
 
   def tagged_with_any_scope
-    Status.group(:id).tagged_with(tags_for(Array(@tag.name) | Array(@options[:any])))
+    Status.group(:id).tagged_with(tags_for(Array(@tag.name) | Array(options[:any])))
   end
 
   def tagged_with_all_scope
-    Status.group(:id).tagged_with_all(tags_for(@options[:all]))
+    Status.group(:id).tagged_with_all(tags_for(options[:all]))
   end
 
   def tagged_with_none_scope
-    Status.group(:id).tagged_with_none(tags_for(@options[:none]))
+    Status.group(:id).tagged_with_none(tags_for(options[:none]))
   end
 
   def tags_for(names)
diff --git a/app/presenters/status_relationships_presenter.rb b/app/presenters/status_relationships_presenter.rb
index 3cc905a75..f4849d245 100644
--- a/app/presenters/status_relationships_presenter.rb
+++ b/app/presenters/status_relationships_presenter.rb
@@ -14,7 +14,7 @@ class StatusRelationshipsPresenter
     else
       statuses            = statuses.compact
       status_ids          = statuses.flat_map { |s| [s.id, s.reblog_of_id] }.uniq.compact
-      conversation_ids    = statuses.map(&:conversation_id).compact.uniq
+      conversation_ids    = statuses.filter_map(&:conversation_id).uniq
       pinnable_status_ids = statuses.map(&:proper).select { |s| s.account_id == current_account_id && %w(public unlisted).include?(s.visibility) }.map(&:id)
 
       @reblogs_map     = Status.reblogs_map(status_ids, current_account_id).merge(options[:reblogs_map] || {})
diff --git a/app/services/activitypub/fetch_featured_collection_service.rb b/app/services/activitypub/fetch_featured_collection_service.rb
index 2c2770466..82c861f5b 100644
--- a/app/services/activitypub/fetch_featured_collection_service.rb
+++ b/app/services/activitypub/fetch_featured_collection_service.rb
@@ -24,8 +24,7 @@ class ActivityPub::FetchFeaturedCollectionService < BaseService
   def process_items(items)
     status_ids = items.map { |item| value_or_id(item) }
                       .reject { |uri| ActivityPub::TagManager.instance.local_uri?(uri) }
-                      .map { |uri| ActivityPub::FetchRemoteStatusService.new.call(uri) }
-                      .compact
+                      .filter_map { |uri| ActivityPub::FetchRemoteStatusService.new.call(uri) }
                       .select { |status| status.account_id == @account.id }
                       .map(&:id)
 
diff --git a/app/services/activitypub/process_collection_service.rb b/app/services/activitypub/process_collection_service.rb
index f1d175dac..170e6709c 100644
--- a/app/services/activitypub/process_collection_service.rb
+++ b/app/services/activitypub/process_collection_service.rb
@@ -37,7 +37,7 @@ class ActivityPub::ProcessCollectionService < BaseService
   end
 
   def process_items(items)
-    items.reverse_each.map { |item| process_item(item) }.compact
+    items.reverse_each.filter_map { |item| process_item(item) }
   end
 
   def supported_context?
diff --git a/app/services/activitypub/process_poll_service.rb b/app/services/activitypub/process_poll_service.rb
index 903b6a78a..d83e614d8 100644
--- a/app/services/activitypub/process_poll_service.rb
+++ b/app/services/activitypub/process_poll_service.rb
@@ -30,7 +30,7 @@ class ActivityPub::ProcessPollService < BaseService
 
     voters_count = @json['votersCount']
 
-    latest_options = items.map { |item| item['name'].presence || item['content'] }.compact
+    latest_options = items.filter_map { |item| item['name'].presence || item['content'] }
 
     # If for some reasons the options were changed, it invalidates all previous
     # votes, so we need to remove them
diff --git a/app/services/activitypub/synchronize_followers_service.rb b/app/services/activitypub/synchronize_followers_service.rb
index d83fcf55e..93cd60253 100644
--- a/app/services/activitypub/synchronize_followers_service.rb
+++ b/app/services/activitypub/synchronize_followers_service.rb
@@ -14,7 +14,7 @@ class ActivityPub::SynchronizeFollowersService < BaseService
     # should never happen in practice, since in almost all cases we keep an
     # Account record, and should we not do that, we should have sent a Delete.
     # In any case there is not much we can do if that occurs.
-    @expected_followers = items.map { |uri| ActivityPub::TagManager.instance.uri_to_resource(uri, Account) }.compact
+    @expected_followers = items.filter_map { |uri| ActivityPub::TagManager.instance.uri_to_resource(uri, Account) }
 
     remove_unexpected_local_followers!
     handle_unexpected_outgoing_follows!
diff --git a/app/services/fetch_link_card_service.rb b/app/services/fetch_link_card_service.rb
index 7efa31054..255490d5c 100644
--- a/app/services/fetch_link_card_service.rb
+++ b/app/services/fetch_link_card_service.rb
@@ -67,7 +67,7 @@ class FetchLinkCardService < BaseService
     else
       html  = Nokogiri::HTML(@status.text)
       links = html.css('a')
-      urls  = links.map { |a| Addressable::URI.parse(a['href']) unless skip_link?(a) }.compact.map(&:normalize).compact
+      urls  = links.filter_map { |a| Addressable::URI.parse(a['href']) unless skip_link?(a) }.filter_map(&:normalize)
     end
 
     urls.reject { |uri| bad_url?(uri) }.first
diff --git a/app/services/import_service.rb b/app/services/import_service.rb
index 0c6ef2238..b11532283 100644
--- a/app/services/import_service.rb
+++ b/app/services/import_service.rb
@@ -107,12 +107,12 @@ class ImportService < BaseService
       end
     end
 
-    statuses = items.map do |uri|
+    statuses = items.filter_map do |uri|
       status = ActivityPub::TagManager.instance.uri_to_resource(uri, Status)
       next if status.nil? && ActivityPub::TagManager.instance.local_uri?(uri)
 
       status || ActivityPub::FetchRemoteStatusService.new.call(uri)
-    end.compact
+    end
 
     account_ids         = statuses.map(&:account_id)
     preloaded_relations = relations_map_for_account(@account, account_ids)
diff --git a/app/services/keys/claim_service.rb b/app/services/keys/claim_service.rb
index 672119130..69568a0d1 100644
--- a/app/services/keys/claim_service.rb
+++ b/app/services/keys/claim_service.rb
@@ -8,11 +8,13 @@ class Keys::ClaimService < BaseService
                :key, :signature
 
     def initialize(account, device_id, key_attributes = {})
-      @account   = account
-      @device_id = device_id
-      @key_id    = key_attributes[:key_id]
-      @key       = key_attributes[:key]
-      @signature = key_attributes[:signature]
+      super(
+        account:   account,
+        device_id: device_id,
+        key_id:    key_attributes[:key_id],
+        key:       key_attributes[:key],
+        signature: key_attributes[:signature],
+      )
     end
   end
 
diff --git a/app/services/keys/query_service.rb b/app/services/keys/query_service.rb
index 286fbd834..ac3388bdc 100644
--- a/app/services/keys/query_service.rb
+++ b/app/services/keys/query_service.rb
@@ -7,8 +7,10 @@ class Keys::QueryService < BaseService
     attributes :account, :devices
 
     def initialize(account, devices)
-      @account = account
-      @devices = devices || []
+      super(
+        account: account,
+        devices: devices || [],
+      )
     end
 
     def find(device_id)
@@ -20,11 +22,13 @@ class Keys::QueryService < BaseService
     attributes :device_id, :name, :identity_key, :fingerprint_key
 
     def initialize(attributes = {})
-      @device_id       = attributes[:device_id]
-      @name            = attributes[:name]
-      @identity_key    = attributes[:identity_key]
-      @fingerprint_key = attributes[:fingerprint_key]
-      @claim_url       = attributes[:claim_url]
+      super(
+        device_id:       attributes[:device_id],
+        name:            attributes[:name],
+        identity_key:    attributes[:identity_key],
+        fingerprint_key: attributes[:fingerprint_key],
+      )
+      @claim_url = attributes[:claim_url]
     end
 
     def valid_claim_url?
diff --git a/app/validators/existing_username_validator.rb b/app/validators/existing_username_validator.rb
index b31d09827..723302ec9 100644
--- a/app/validators/existing_username_validator.rb
+++ b/app/validators/existing_username_validator.rb
@@ -5,7 +5,7 @@ class ExistingUsernameValidator < ActiveModel::EachValidator
     return if value.blank?
 
     if options[:multiple]
-      missing_usernames = value.split(',').map { |username| username.strip.gsub(/\A@/, '') }.map { |username| username unless Account.find_local(username) }.compact
+      missing_usernames = value.split(',').map { |username| username.strip.gsub(/\A@/, '') }.filter_map { |username| username unless Account.find_local(username) }
       record.errors.add(attribute, I18n.t('existing_username_validator.not_found_multiple', usernames: missing_usernames.join(', '))) if missing_usernames.any?
     else
       record.errors.add(attribute, I18n.t('existing_username_validator.not_found')) unless Account.find_local(value.strip.gsub(/\A@/, ''))