Consolidate account scopes for `LOWER` (index using) username/domain queries (#30451)
parent
32c30bf0fd
commit
4a77e477ee
|
@ -142,6 +142,8 @@ class Account < ApplicationRecord
|
||||||
scope :not_excluded_by_account, ->(account) { where.not(id: account.excluded_from_timeline_account_ids) }
|
scope :not_excluded_by_account, ->(account) { where.not(id: account.excluded_from_timeline_account_ids) }
|
||||||
scope :not_domain_blocked_by_account, ->(account) { where(arel_table[:domain].eq(nil).or(arel_table[:domain].not_in(account.excluded_from_timeline_domains))) }
|
scope :not_domain_blocked_by_account, ->(account) { where(arel_table[:domain].eq(nil).or(arel_table[:domain].not_in(account.excluded_from_timeline_domains))) }
|
||||||
scope :dormant, -> { joins(:account_stat).merge(AccountStat.without_recent_activity) }
|
scope :dormant, -> { joins(:account_stat).merge(AccountStat.without_recent_activity) }
|
||||||
|
scope :with_username, ->(value) { where arel_table[:username].lower.eq(value.to_s.downcase) }
|
||||||
|
scope :with_domain, ->(value) { where arel_table[:domain].lower.eq(value&.to_s&.downcase) }
|
||||||
|
|
||||||
after_update_commit :trigger_update_webhooks
|
after_update_commit :trigger_update_webhooks
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
class AccountSuggestions::SettingSource < AccountSuggestions::Source
|
class AccountSuggestions::SettingSource < AccountSuggestions::Source
|
||||||
def get(account, limit: DEFAULT_LIMIT)
|
def get(account, limit: DEFAULT_LIMIT)
|
||||||
if setting_enabled?
|
if setting_enabled?
|
||||||
base_account_scope(account).where(setting_to_where_condition).limit(limit).pluck(:id).zip([key].cycle)
|
base_account_scope(account).merge(setting_to_where_condition).limit(limit).pluck(:id).zip([key].cycle)
|
||||||
else
|
else
|
||||||
[]
|
[]
|
||||||
end
|
end
|
||||||
|
@ -25,11 +25,9 @@ class AccountSuggestions::SettingSource < AccountSuggestions::Source
|
||||||
|
|
||||||
def setting_to_where_condition
|
def setting_to_where_condition
|
||||||
usernames_and_domains.map do |(username, domain)|
|
usernames_and_domains.map do |(username, domain)|
|
||||||
Arel::Nodes::Grouping.new(
|
Account
|
||||||
Account.arel_table[:username].lower.eq(username.downcase).and(
|
.with_username(username)
|
||||||
Account.arel_table[:domain].lower.eq(domain&.downcase)
|
.with_domain(domain)
|
||||||
)
|
|
||||||
)
|
|
||||||
end.reduce(:or)
|
end.reduce(:or)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -25,42 +25,11 @@ module Account::FinderConcern
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_remote(username, domain)
|
def find_remote(username, domain)
|
||||||
AccountFinder.new(username, domain).account
|
Account
|
||||||
end
|
.with_username(username)
|
||||||
end
|
.with_domain(domain)
|
||||||
|
.order(id: :asc)
|
||||||
class AccountFinder
|
.take
|
||||||
attr_reader :username, :domain
|
|
||||||
|
|
||||||
def initialize(username, domain)
|
|
||||||
@username = username
|
|
||||||
@domain = domain
|
|
||||||
end
|
|
||||||
|
|
||||||
def account
|
|
||||||
scoped_accounts.order(id: :asc).take
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def scoped_accounts
|
|
||||||
Account.unscoped.tap do |scope|
|
|
||||||
scope.merge! with_usernames
|
|
||||||
scope.merge! matching_username
|
|
||||||
scope.merge! matching_domain
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def with_usernames
|
|
||||||
Account.where.not(Account.arel_table[:username].lower.eq '')
|
|
||||||
end
|
|
||||||
|
|
||||||
def matching_username
|
|
||||||
Account.where(Account.arel_table[:username].lower.eq username.to_s.downcase)
|
|
||||||
end
|
|
||||||
|
|
||||||
def matching_domain
|
|
||||||
Account.where(Account.arel_table[:domain].lower.eq(domain.nil? ? nil : domain.to_s.downcase))
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -22,7 +22,7 @@ module User::LdapAuthenticable
|
||||||
safe_username = safe_username.gsub(keys, replacement)
|
safe_username = safe_username.gsub(keys, replacement)
|
||||||
end
|
end
|
||||||
|
|
||||||
resource = joins(:account).merge(Account.where(Account.arel_table[:username].lower.eq safe_username.downcase)).take
|
resource = joins(:account).merge(Account.with_username(safe_username)).take
|
||||||
|
|
||||||
if resource.blank?
|
if resource.blank?
|
||||||
resource = new(
|
resource = new(
|
||||||
|
|
|
@ -81,7 +81,7 @@ class ReportService < BaseService
|
||||||
|
|
||||||
# If the account making reports is remote, it is likely anonymized so we have to relax the requirements for attaching statuses.
|
# If the account making reports is remote, it is likely anonymized so we have to relax the requirements for attaching statuses.
|
||||||
domain = @source_account.domain.to_s.downcase
|
domain = @source_account.domain.to_s.downcase
|
||||||
has_followers = @target_account.followers.where(Account.arel_table[:domain].lower.eq(domain)).exists?
|
has_followers = @target_account.followers.with_domain(domain).exists?
|
||||||
visibility = has_followers ? %i(public unlisted private) : %i(public unlisted)
|
visibility = has_followers ? %i(public unlisted private) : %i(public unlisted)
|
||||||
scope = @target_account.statuses.with_discarded
|
scope = @target_account.statuses.with_discarded
|
||||||
scope.merge!(scope.where(visibility: visibility).or(scope.where('EXISTS (SELECT 1 FROM mentions m JOIN accounts a ON m.account_id = a.id WHERE lower(a.domain) = ?)', domain)))
|
scope.merge!(scope.where(visibility: visibility).or(scope.where('EXISTS (SELECT 1 FROM mentions m JOIN accounts a ON m.account_id = a.id WHERE lower(a.domain) = ?)', domain)))
|
||||||
|
|
|
@ -6,10 +6,7 @@ class UniqueUsernameValidator < ActiveModel::Validator
|
||||||
def validate(account)
|
def validate(account)
|
||||||
return if account.username.blank?
|
return if account.username.blank?
|
||||||
|
|
||||||
normalized_username = account.username.downcase
|
scope = Account.with_username(account.username).with_domain(account.domain)
|
||||||
normalized_domain = account.domain&.downcase
|
|
||||||
|
|
||||||
scope = Account.where(Account.arel_table[:username].lower.eq normalized_username).where(Account.arel_table[:domain].lower.eq normalized_domain)
|
|
||||||
scope = scope.where.not(id: account.id) if account.persisted?
|
scope = scope.where.not(id: account.id) if account.persisted?
|
||||||
|
|
||||||
account.errors.add(:username, :taken) if scope.exists?
|
account.errors.add(:username, :taken) if scope.exists?
|
||||||
|
|
Loading…
Reference in New Issue