* Bump rubocop from 1.18.1 to 1.18.3 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.18.1 to 1.18.3. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.18.1...v1.18.3) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * Fix violations * Commit pundit-matchers gemfile for build Container builds failed because this was not checked in. For some reason my Gemfile.lock relaxed the version restriction from `~> 1.7` to `~> 1.6` but the resolved version is still 1.7.0 Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: rhymes <github@rhymes.dev> Co-authored-by: Dan Uber <dan@forem.com>
72 lines
2.4 KiB
Ruby
72 lines
2.4 KiB
Ruby
module Search
|
|
class User
|
|
ATTRIBUTES = %i[
|
|
id
|
|
name
|
|
profile_image
|
|
username
|
|
].freeze
|
|
|
|
DEFAULT_PER_PAGE = 60
|
|
MAX_PER_PAGE = 100
|
|
|
|
# User.search_score used to take employer related fields into account, but they have since been moved to profile
|
|
# and removed from fields that are searched against.
|
|
HOTNESS_SCORE_ORDER = Arel.sql(%{
|
|
(((articles_count + comments_count + reactions_count + badge_achievements_count) * 10) * reputation_modifier)
|
|
DESC
|
|
}.squish).freeze
|
|
|
|
def self.search_documents(term: nil, sort_by: :nil, sort_direction: :desc, page: 0, per_page: DEFAULT_PER_PAGE)
|
|
# NOTE: we should eventually update the frontend
|
|
# to start from page 1
|
|
page = page.to_i + 1
|
|
per_page = [(per_page || DEFAULT_PER_PAGE).to_i, MAX_PER_PAGE].min
|
|
|
|
relation = ::User
|
|
|
|
relation = filter_suspended_users(relation)
|
|
|
|
relation = relation.search_by_name_and_username(term) if term.present?
|
|
|
|
relation = relation.select(*ATTRIBUTES)
|
|
|
|
relation = sort(relation, sort_by, sort_direction)
|
|
|
|
relation = relation.page(page).per(per_page)
|
|
|
|
serialize(relation)
|
|
end
|
|
|
|
# `User.without_role` generates a subquery + 2 inner joins.
|
|
# Given that the number of suspended users will, hopefully, be a tiny percentage
|
|
# of regular users, and the `rolify`'s gem approach is not particularly efficient,
|
|
# we simplified the subquery and added a precondition to skip that query entirely,
|
|
# when a community has no suspended users.
|
|
# NOTE: An alternative approach that could be explored is to
|
|
# preload the user ids of all suspended users and use those with `.where.not(id: ...)`
|
|
def self.filter_suspended_users(relation)
|
|
suspended = UserRole.joins(:role).where(roles: { name: :suspended })
|
|
|
|
return relation unless suspended.exists?
|
|
|
|
relation.where.not(id: suspended.select(:user_id))
|
|
end
|
|
private_class_method :filter_suspended_users
|
|
|
|
def self.sort(relation, sort_by, sort_direction)
|
|
return relation.reorder(sort_by => sort_direction) if sort_by&.to_sym == :created_at
|
|
|
|
relation.reorder(HOTNESS_SCORE_ORDER)
|
|
end
|
|
private_class_method :sort
|
|
|
|
def self.serialize(users)
|
|
Search::SimpleUserSerializer
|
|
.new(users, is_collection: true)
|
|
.serializable_hash[:data]
|
|
.pluck(:attributes)
|
|
end
|
|
private_class_method :serialize
|
|
end
|
|
end
|