summaryrefslogtreecommitdiff
path: root/app/models/user.rb
diff options
context:
space:
mode:
authorYorick Peterse <yorickpeterse@gmail.com>2018-07-30 17:45:49 +0200
committerYorick Peterse <yorickpeterse@gmail.com>2018-08-20 13:53:00 +0200
commit6f3c490107f5fa7dd00bce0bbd89e4a0fa4d6389 (patch)
tree574fb9d604b8269846876430b9761f397e391d2b /app/models/user.rb
parent0a73c1c5833ac5a86289418e93b5d50aa8e89cbd (diff)
downloadgitlab-ce-6f3c490107f5fa7dd00bce0bbd89e4a0fa4d6389.tar.gz
Refactor AutocompleteControllerdefine-abstraction-levels
This refactors the AutocompleteController according to the guidelines and boundaries discussed in https://gitlab.com/gitlab-org/gitlab-ce/issues/49653. Specifically, ActiveRecord logic is moved to different finders, which are then used in the controller. View logic in turn is moved to presenters, instead of directly using ActiveRecord's "to_json" method. The finder MoveToProjectFinder is also adjusted according to the abstraction guidelines and boundaries, resulting in a much more simple finder. By using finders (and other abstractions) more actively, we can push a lot of logic out of the controller. We also remove the need for various "before_action" hooks, though this could be achieved without using finders as well. The various finders related to AutcompleteController have also been moved into a namespace. This removes the need for calling everything "AutocompleteSmurfFinder", instead you can use "Autocomplete::SmurfFinder".
Diffstat (limited to 'app/models/user.rb')
-rw-r--r--app/models/user.rb45
1 files changed, 44 insertions, 1 deletions
diff --git a/app/models/user.rb b/app/models/user.rb
index 13b04270a4a..a6ba90794d6 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -19,6 +19,7 @@ class User < ActiveRecord::Base
include BulkMemberAccessLoad
include BlocksJsonSerialization
include WithUploads
+ include OptionallySearch
DEFAULT_NOTIFICATION_LEVEL = :participating
@@ -253,11 +254,41 @@ class User < ActiveRecord::Base
scope :external, -> { where(external: true) }
scope :active, -> { with_state(:active).non_internal }
scope :without_projects, -> { joins('LEFT JOIN project_authorizations ON users.id = project_authorizations.user_id').where(project_authorizations: { user_id: nil }) }
- scope :todo_authors, ->(user_id, state) { where(id: Todo.where(user_id: user_id, state: state).select(:author_id)) }
scope :order_recent_sign_in, -> { reorder(Gitlab::Database.nulls_last_order('current_sign_in_at', 'DESC')) }
scope :order_oldest_sign_in, -> { reorder(Gitlab::Database.nulls_last_order('current_sign_in_at', 'ASC')) }
scope :confirmed, -> { where.not(confirmed_at: nil) }
+ # Limits the users to those that have TODOs, optionally in the given state.
+ #
+ # user - The user to get the todos for.
+ #
+ # with_todos - If we should limit the result set to users that are the
+ # authors of todos.
+ #
+ # todo_state - An optional state to require the todos to be in.
+ def self.limit_to_todo_authors(user: nil, with_todos: false, todo_state: nil)
+ if user && with_todos
+ where(id: Todo.where(user: user, state: todo_state).select(:author_id))
+ else
+ all
+ end
+ end
+
+ # Returns a relation that optionally includes the given user.
+ #
+ # user_id - The ID of the user to include.
+ def self.union_with_user(user_id = nil)
+ if user_id.present?
+ union = Gitlab::SQL::Union.new([all, User.unscoped.where(id: user_id)])
+
+ # We use "unscoped" here so that any inner conditions are not repeated for
+ # the outer query, which would be redundant.
+ User.unscoped.from("(#{union.to_sql}) #{User.table_name}")
+ else
+ all
+ end
+ end
+
def self.with_two_factor_indistinct
joins("LEFT OUTER JOIN u2f_registrations AS u2f ON u2f.user_id = users.id")
.where("u2f.id IS NOT NULL OR users.otp_required_for_login = ?", true)
@@ -365,6 +396,18 @@ class User < ActiveRecord::Base
).reorder(order % { query: ActiveRecord::Base.connection.quote(query) }, :name)
end
+ # Limits the result set to users _not_ in the given query/list of IDs.
+ #
+ # users - The list of users to ignore. This can be an
+ # `ActiveRecord::Relation`, or an Array.
+ def where_not_in(users = nil)
+ users ? where.not(id: users) : all
+ end
+
+ def reorder_by_name
+ reorder(:name)
+ end
+
# searches user by given pattern
# it compares name, email, username fields and user's secondary emails with given pattern
# This method uses ILIKE on PostgreSQL and LIKE on MySQL.