mirror of
https://github.com/wahyd4/gitlabhq.git
synced 2026-08-10 05:06:46 +10:00
Turn Group#owners into a has_many association ## What does this MR do? This turns the regular method `Group#owners` into a `has_many` association. ## Are there points in the code the reviewer needs to double check? As far as I can tell there's no way to do this without using an intermediate association, but perhaps I'm missing something. The reason an intermediate association is needed is because the supplied Proc is applied to the _final_ association (the one returning users), this means that when using a single `has_many` you can't filter out any intermediate rows (e.g. group members). ## Why was this MR needed? This code being a regular method would prevent eager loading of the owners of a Group, turning it into a `has_many` association resolves this problem. This was discovered in !4410. ## What are the relevant issue numbers? None. ## Does this MR meet the acceptance criteria? - [x] [CHANGELOG](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CHANGELOG) entry added - [x] ~~[Documentation created/updated](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/development/doc_styleguide.md)~~ - [x] ~~API support added~~ - [ ] Tests - [x] Added for this feature/bug - [ ] All builds are passing - [x] Conform by the [style guides](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#style-guides) - [ ] Branch has no merge conflicts with `master` (if you do - rebase it please) - [x] [Squashed related commits together](https://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits) See merge request !4676
161 lines
3.9 KiB
Ruby
161 lines
3.9 KiB
Ruby
require 'carrierwave/orm/activerecord'
|
|
|
|
class Group < Namespace
|
|
include Gitlab::ConfigHelper
|
|
include Gitlab::VisibilityLevel
|
|
include AccessRequestable
|
|
include Referable
|
|
|
|
has_many :group_members, dependent: :destroy, as: :source, class_name: 'GroupMember'
|
|
alias_method :members, :group_members
|
|
has_many :users, -> { where(members: { requested_at: nil }) }, through: :group_members
|
|
|
|
has_many :owners,
|
|
-> { where(members: { access_level: Gitlab::Access::OWNER }) },
|
|
through: :group_members,
|
|
source: :user
|
|
|
|
has_many :project_group_links, dependent: :destroy
|
|
has_many :shared_projects, through: :project_group_links, source: :project
|
|
has_many :notification_settings, dependent: :destroy, as: :source
|
|
|
|
validate :avatar_type, if: ->(user) { user.avatar.present? && user.avatar_changed? }
|
|
validate :visibility_level_allowed_by_projects
|
|
|
|
validates :avatar, file_size: { maximum: 200.kilobytes.to_i }
|
|
|
|
mount_uploader :avatar, AvatarUploader
|
|
|
|
after_create :post_create_hook
|
|
after_destroy :post_destroy_hook
|
|
|
|
class << self
|
|
# Searches for groups matching the given query.
|
|
#
|
|
# This method uses ILIKE on PostgreSQL and LIKE on MySQL.
|
|
#
|
|
# query - The search query as a String
|
|
#
|
|
# Returns an ActiveRecord::Relation.
|
|
def search(query)
|
|
table = Namespace.arel_table
|
|
pattern = "%#{query}%"
|
|
|
|
where(table[:name].matches(pattern).or(table[:path].matches(pattern)))
|
|
end
|
|
|
|
def sort(method)
|
|
order_by(method)
|
|
end
|
|
|
|
def reference_prefix
|
|
User.reference_prefix
|
|
end
|
|
|
|
def reference_pattern
|
|
User.reference_pattern
|
|
end
|
|
|
|
def visible_to_user(user)
|
|
where(id: user.authorized_groups.select(:id).reorder(nil))
|
|
end
|
|
end
|
|
|
|
def to_reference(_from_project = nil)
|
|
"#{self.class.reference_prefix}#{name}"
|
|
end
|
|
|
|
def web_url
|
|
Gitlab::Routing.url_helpers.group_url(self)
|
|
end
|
|
|
|
def human_name
|
|
name
|
|
end
|
|
|
|
def visibility_level_field
|
|
visibility_level
|
|
end
|
|
|
|
def visibility_level_allowed_by_projects
|
|
allowed_by_projects = self.projects.where('visibility_level > ?', self.visibility_level).none?
|
|
|
|
unless allowed_by_projects
|
|
level_name = Gitlab::VisibilityLevel.level_name(visibility_level).downcase
|
|
self.errors.add(:visibility_level, "#{level_name} is not allowed since there are projects with higher visibility.")
|
|
end
|
|
|
|
allowed_by_projects
|
|
end
|
|
|
|
def avatar_url(size = nil)
|
|
if avatar.present?
|
|
[gitlab_config.url, avatar.url].join
|
|
end
|
|
end
|
|
|
|
def add_users(user_ids, access_level, current_user = nil)
|
|
user_ids.each do |user_id|
|
|
Member.add_user(self.group_members, user_id, access_level, current_user)
|
|
end
|
|
end
|
|
|
|
def add_user(user, access_level, current_user = nil)
|
|
add_users([user], access_level, current_user)
|
|
end
|
|
|
|
def add_guest(user, current_user = nil)
|
|
add_user(user, Gitlab::Access::GUEST, current_user)
|
|
end
|
|
|
|
def add_reporter(user, current_user = nil)
|
|
add_user(user, Gitlab::Access::REPORTER, current_user)
|
|
end
|
|
|
|
def add_developer(user, current_user = nil)
|
|
add_user(user, Gitlab::Access::DEVELOPER, current_user)
|
|
end
|
|
|
|
def add_master(user, current_user = nil)
|
|
add_user(user, Gitlab::Access::MASTER, current_user)
|
|
end
|
|
|
|
def add_owner(user, current_user = nil)
|
|
add_user(user, Gitlab::Access::OWNER, current_user)
|
|
end
|
|
|
|
def has_owner?(user)
|
|
owners.include?(user)
|
|
end
|
|
|
|
def has_master?(user)
|
|
members.masters.where(user_id: user).any?
|
|
end
|
|
|
|
def last_owner?(user)
|
|
has_owner?(user) && owners.size == 1
|
|
end
|
|
|
|
def avatar_type
|
|
unless self.avatar.image?
|
|
self.errors.add :avatar, "only images allowed"
|
|
end
|
|
end
|
|
|
|
def post_create_hook
|
|
Gitlab::AppLogger.info("Group \"#{name}\" was created")
|
|
|
|
system_hook_service.execute_hooks_for(self, :create)
|
|
end
|
|
|
|
def post_destroy_hook
|
|
Gitlab::AppLogger.info("Group \"#{name}\" was removed")
|
|
|
|
system_hook_service.execute_hooks_for(self, :destroy)
|
|
end
|
|
|
|
def system_hook_service
|
|
SystemHooksService.new
|
|
end
|
|
end
|