Commit f6bc8fd9 authored by Corinna Wiesner's avatar Corinna Wiesner

Introduce database table for user highest roles

The table stores the highest role for each User they have in a Group
or a Project. If a User has an open invite or pending access request or
no membership the highest role will be set to nil.
parent 469e2348
...@@ -164,6 +164,7 @@ class User < ApplicationRecord ...@@ -164,6 +164,7 @@ class User < ApplicationRecord
has_one :status, class_name: 'UserStatus' has_one :status, class_name: 'UserStatus'
has_one :user_preference has_one :user_preference
has_one :user_detail has_one :user_detail
has_one :user_highest_role
# #
# Validations # Validations
......
# frozen_string_literal: true
class UserHighestRole < ApplicationRecord
belongs_to :user, optional: false
validates :highest_access_level, allow_nil: true, inclusion: { in: Gitlab::Access.all_values }
end
---
title: Introduce database table for user highest roles
merge_request: 26987
author:
type: added
# frozen_string_literal: true
class CreateUserHighestRoles < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
def up
with_lock_retries do
create_table :user_highest_roles, id: false do |t|
t.datetime_with_timezone :updated_at, null: false
t.references :user, primary_key: true, default: nil, index: false, foreign_key: { on_delete: :cascade }
t.integer :highest_access_level
t.index [:user_id, :highest_access_level]
end
end
end
def down
with_lock_retries do
drop_table :user_highest_roles
end
end
end
...@@ -4251,6 +4251,12 @@ ActiveRecord::Schema.define(version: 2020_03_11_165635) do ...@@ -4251,6 +4251,12 @@ ActiveRecord::Schema.define(version: 2020_03_11_165635) do
t.index ["user_id"], name: "index_user_details_on_user_id", unique: true t.index ["user_id"], name: "index_user_details_on_user_id", unique: true
end end
create_table "user_highest_roles", primary_key: "user_id", id: :bigint, default: nil, force: :cascade do |t|
t.datetime_with_timezone "updated_at", null: false
t.integer "highest_access_level"
t.index ["user_id", "highest_access_level"], name: "index_user_highest_roles_on_user_id_and_highest_access_level"
end
create_table "user_interacted_projects", id: false, force: :cascade do |t| create_table "user_interacted_projects", id: false, force: :cascade do |t|
t.integer "user_id", null: false t.integer "user_id", null: false
t.integer "project_id", null: false t.integer "project_id", null: false
...@@ -5135,6 +5141,7 @@ ActiveRecord::Schema.define(version: 2020_03_11_165635) do ...@@ -5135,6 +5141,7 @@ ActiveRecord::Schema.define(version: 2020_03_11_165635) do
add_foreign_key "user_callouts", "users", on_delete: :cascade add_foreign_key "user_callouts", "users", on_delete: :cascade
add_foreign_key "user_custom_attributes", "users", on_delete: :cascade add_foreign_key "user_custom_attributes", "users", on_delete: :cascade
add_foreign_key "user_details", "users", on_delete: :cascade add_foreign_key "user_details", "users", on_delete: :cascade
add_foreign_key "user_highest_roles", "users", on_delete: :cascade
add_foreign_key "user_interacted_projects", "projects", name: "fk_722ceba4f7", on_delete: :cascade add_foreign_key "user_interacted_projects", "projects", name: "fk_722ceba4f7", on_delete: :cascade
add_foreign_key "user_interacted_projects", "users", name: "fk_0894651f08", on_delete: :cascade add_foreign_key "user_interacted_projects", "users", name: "fk_0894651f08", on_delete: :cascade
add_foreign_key "user_preferences", "users", on_delete: :cascade add_foreign_key "user_preferences", "users", on_delete: :cascade
......
# frozen_string_literal: true
FactoryBot.define do
factory :user_highest_role do
user
end
end
# frozen_string_literal: true
require 'spec_helper'
describe UserHighestRole do
describe 'associations' do
it { is_expected.to belong_to(:user).required }
end
describe 'validations' do
it { is_expected.to validate_inclusion_of(:highest_access_level).in_array([nil, *Gitlab::Access.all_values]) }
end
end
...@@ -30,6 +30,7 @@ describe User, :do_not_mock_admin_mode do ...@@ -30,6 +30,7 @@ describe User, :do_not_mock_admin_mode do
it { is_expected.to have_one(:status) } it { is_expected.to have_one(:status) }
it { is_expected.to have_one(:max_access_level_membership) } it { is_expected.to have_one(:max_access_level_membership) }
it { is_expected.to have_one(:user_detail) } it { is_expected.to have_one(:user_detail) }
it { is_expected.to have_one(:user_highest_role) }
it { is_expected.to have_many(:snippets).dependent(:destroy) } it { is_expected.to have_many(:snippets).dependent(:destroy) }
it { is_expected.to have_many(:members) } it { is_expected.to have_many(:members) }
it { is_expected.to have_many(:project_members) } it { is_expected.to have_many(:project_members) }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment