diff --git a/ee/spec/requests/api/composer_packages_spec.rb b/ee/spec/requests/api/composer_packages_spec.rb
index 0cef6934c52bb795658817b90e361f6ef28a3824..b68e4ef83b58dcd1e66def453fe29149d69e8c13 100644
--- a/ee/spec/requests/api/composer_packages_spec.rb
+++ b/ee/spec/requests/api/composer_packages_spec.rb
@@ -6,7 +6,7 @@
   include HttpBasicAuthHelpers
 
   let_it_be(:user) { create(:user) }
-  let_it_be(:group) { create(:group) }
+  let_it_be(:group) { create(:group, maintainers: user) }
   let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
   let_it_be(:package_name) { 'package-name' }
   let_it_be(:project) do
@@ -21,10 +21,6 @@
 
   subject { get api(url), headers: headers, params: params }
 
-  before do
-    group.add_maintainer(user)
-  end
-
   describe 'GET /api/v4/projects/:id/packages/composer/archives/*package_name?sha=:sha' do
     let(:url) { "/projects/#{project.id}/packages/composer/archives/#{package_name}.zip" }
     let(:params) { { sha: project.repository.find_branch('master').target } }
diff --git a/ee/spec/requests/api/conan_project_packages_spec.rb b/ee/spec/requests/api/conan_project_packages_spec.rb
index da72025bdb618f687a7f2d177f6fc13e5c4683bf..7829a2bbb78d9abace2335d0aa55ebadf058361b 100644
--- a/ee/spec/requests/api/conan_project_packages_spec.rb
+++ b/ee/spec/requests/api/conan_project_packages_spec.rb
@@ -6,7 +6,7 @@
   include HttpBasicAuthHelpers
 
   let_it_be(:user) { create(:user) }
-  let_it_be(:group) { create(:group) }
+  let_it_be(:group) { create(:group, maintainers: user) }
   let_it_be(:project) { create(:project, group: group) }
   let_it_be(:package) { create(:conan_package, project: project) }
   let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
@@ -15,10 +15,6 @@
 
   let(:headers) { basic_auth_header(user.username, personal_access_token.token) }
 
-  before do
-    group.add_maintainer(user)
-  end
-
   describe 'GET /api/v4/projects/:id/packages/conan/v1/files/:package_name/package_version/:package_username/:package_channel/:recipe_revision/package/:conan_package_reference/:package_revision/:file_name' do # rubocop:disable Layout/LineLength
     let(:url) { "/projects/#{project.id}/packages/conan/v1/files/#{package.conan_recipe_path}/#{metadata.recipe_revision}/package/#{metadata.conan_package_reference}/#{metadata.package_revision}/#{package_file.file_name}" } # rubocop:disable Layout/LineLength
 
diff --git a/ee/spec/requests/api/debian_group_packages_spec.rb b/ee/spec/requests/api/debian_group_packages_spec.rb
index 384fc5830193edc7a5763142ae74d5b82467aae8..dfe90efdb4c8631e21b65da291edb76dc18a2e3f 100644
--- a/ee/spec/requests/api/debian_group_packages_spec.rb
+++ b/ee/spec/requests/api/debian_group_packages_spec.rb
@@ -7,7 +7,7 @@
 
   let_it_be(:user) { create(:user) }
   let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
-  let_it_be(:group) { create(:group) }
+  let_it_be(:group) { create(:group, maintainers: user) }
   let_it_be(:project) { create(:project, group: group) }
   let_it_be(:distribution) { create(:debian_project_distribution, container: project, codename: 'existing-codename') }
   let_it_be(:package) { create(:debian_package, project: project, published_in: distribution) }
@@ -15,10 +15,6 @@
   let(:letter) { package.name[0..2] == 'lib' ? package.name[0..3] : package.name[0] }
   let(:headers) { basic_auth_header(user.username, personal_access_token.token) }
 
-  before do
-    group.add_maintainer(user)
-  end
-
   describe 'GET groups/:id/-/packages/debian/pool/:codename/:project_id/:letter/:package_name/:package_version/:file_name' do # rubocop:disable convention:Layout/LineLength
     let(:url) { "/groups/#{group.id}/-/packages/debian/pool/#{package.debian_distribution.codename}/#{project.id}/#{letter}/#{package.name}/#{package.version}/#{file_name}" } # rubocop:disable convention:Layout/LineLength
     let(:file_name) { 'sample_1.2.3~alpha2.tar.xz' }
diff --git a/ee/spec/requests/api/debian_project_packages_spec.rb b/ee/spec/requests/api/debian_project_packages_spec.rb
index ad74130b305495a8a0a90503eefc21800d5c9c3c..4068447c0bf9af0bf1df737228c480951e954cc5 100644
--- a/ee/spec/requests/api/debian_project_packages_spec.rb
+++ b/ee/spec/requests/api/debian_project_packages_spec.rb
@@ -7,7 +7,7 @@
 
   let_it_be(:user) { create(:user) }
   let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
-  let_it_be(:group) { create(:group) }
+  let_it_be(:group) { create(:group, maintainers: user) }
   let_it_be(:project) { create(:project, group: group) }
   let_it_be(:distribution) { create(:debian_project_distribution, :with_file, container: project, codename: 'existing-codename') } # rubocop:disable convention:Layout/LineLength
   let_it_be(:package) { create(:debian_package, project: project, published_in: distribution) }
@@ -15,10 +15,6 @@
   let(:letter) { package.name[0..2] == 'lib' ? package.name[0..3] : package.name[0] }
   let(:headers) { basic_auth_header(user.username, personal_access_token.token) }
 
-  before do
-    group.add_maintainer(user)
-  end
-
   describe 'GET projects/:id/packages/debian/pool/:codename/:letter/:package_name/:package_version/:file_name' do
     let(:url) { "/projects/#{project.id}/packages/debian/pool/#{package.debian_distribution.codename}/#{letter}/#{package.name}/#{package.version}/#{file_name}" } # rubocop:disable convention:Layout/LineLength
     let(:file_name) { 'sample_1.2.3~alpha2.tar.xz' }
diff --git a/ee/spec/requests/api/epic_boards_spec.rb b/ee/spec/requests/api/epic_boards_spec.rb
index b9ea6a2f8eec4585c3da556bd2e8324a3d226fb3..7eb800619d4bdcd89e1d2bf5dde0ebe9404ae8fc 100644
--- a/ee/spec/requests/api/epic_boards_spec.rb
+++ b/ee/spec/requests/api/epic_boards_spec.rb
@@ -6,7 +6,7 @@
   let_it_be(:non_member) { create(:user) }
   let_it_be(:guest) { create(:user) }
 
-  let_it_be(:group, reload: true) { create(:group, :private) }
+  let_it_be(:group, reload: true) { create(:group, :private, guests: guest) }
   let_it_be(:development) { create(:group_label, group: group, name: 'Development') }
   let_it_be(:testing) { create(:group_label, group: group, name: 'Testing') }
   let_it_be(:feature) { create(:group_label, group: group, name: 'Feature') }
@@ -26,10 +26,6 @@
 
   let(:params) { nil }
 
-  before do
-    group.add_guest(guest)
-  end
-
   shared_examples 'request with epics unavailable' do
     it 'returns 403 forbidden error' do
       get api(url, guest)
diff --git a/ee/spec/requests/api/generic_packages_spec.rb b/ee/spec/requests/api/generic_packages_spec.rb
index 76bb4ae8a5e92472af7fe140d4bc770ae99bd64b..a1dcf02a6d024465f60efeea2c67527c3e2c50ff 100644
--- a/ee/spec/requests/api/generic_packages_spec.rb
+++ b/ee/spec/requests/api/generic_packages_spec.rb
@@ -7,17 +7,13 @@
 
   let_it_be(:user) { create(:user) }
   let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
-  let_it_be(:group) { create(:group) }
+  let_it_be(:group) { create(:group, maintainers: user) }
   let_it_be(:project) { create(:project, group: group) }
   let_it_be(:package) { create(:generic_package, project: project) }
   let_it_be(:package_file) { create(:package_file, :generic, package: package) }
 
   let(:headers) { basic_auth_header(user.username, personal_access_token.token) }
 
-  before do
-    group.add_maintainer(user)
-  end
-
   describe 'GET /api/v4/projects/:id/packages/generic/:package_name/:package_version/:file_name' do
     let(:url) do
       "/projects/#{project.id}/packages/generic/#{package.name}/#{package.version}/#{package_file.file_name}"
diff --git a/ee/spec/requests/api/graphql/iterations/cadences_spec.rb b/ee/spec/requests/api/graphql/iterations/cadences_spec.rb
index 2357b57b2061974929c7581bd954b6193d88433f..9628f0d7c1cddb8a6e2fcd45e38ea13b33921018 100644
--- a/ee/spec/requests/api/graphql/iterations/cadences_spec.rb
+++ b/ee/spec/requests/api/graphql/iterations/cadences_spec.rb
@@ -7,15 +7,11 @@
 
   let_it_be(:now) { Time.now }
   let_it_be(:user) { create(:user) }
-  let_it_be(:group) { create(:group) }
+  let_it_be(:group) { create(:group, developers: user) }
   let_it_be(:project) { create(:project, group: group) }
   let_it_be(:iteration_cadence1) { create(:iterations_cadence, group: group, active: true, duration_in_weeks: 1, title: 'one week iterations') }
   let_it_be(:iteration_cadence2) { create(:iterations_cadence, group: group, active: true, duration_in_weeks: 2, title: 'two week iterations') }
 
-  before do
-    group.add_developer(user)
-  end
-
   describe 'query for iteration cadence' do
     shared_examples 'returns cadence by id' do
       it 'returns cadence' do
diff --git a/ee/spec/requests/api/graphql/iterations/iterations_spec.rb b/ee/spec/requests/api/graphql/iterations/iterations_spec.rb
index f14a03184846445e48bab91abfd7308a90808dfe..b1778492db9b60f924751e6c68ca5a138e6de82c 100644
--- a/ee/spec/requests/api/graphql/iterations/iterations_spec.rb
+++ b/ee/spec/requests/api/graphql/iterations/iterations_spec.rb
@@ -7,7 +7,7 @@
 
   let_it_be(:now) { Time.now }
   let_it_be(:user) { create(:user) }
-  let_it_be(:group) { create(:group) }
+  let_it_be(:group) { create(:group, maintainers: user) }
   let_it_be(:iteration_cadence1) { create(:iterations_cadence, group: group, active: true, duration_in_weeks: 1, title: 'one week iterations') }
   let_it_be(:iteration_cadence2) { create(:iterations_cadence, group: group, active: true, duration_in_weeks: 2, title: 'two week iterations') }
 
@@ -15,10 +15,6 @@
   let_it_be(:upcoming_group_iteration) { create(:iteration, iterations_cadence: iteration_cadence2, start_date: 1.day.from_now, due_date: 2.days.from_now) }
   let_it_be(:closed_group_iteration) { create(:iteration, iterations_cadence: iteration_cadence1, start_date: 3.weeks.ago, due_date: 1.week.ago) }
 
-  before do
-    group.add_maintainer(user)
-  end
-
   describe 'query for iterations by timeframe' do
     context 'without start date' do
       it 'returns error' do
diff --git a/ee/spec/requests/api/graphql/mutations/projects/chat_spec.rb b/ee/spec/requests/api/graphql/mutations/projects/chat_spec.rb
index c08f891bb27e8a30e6dc0071c8f667fd52bb59a5..d0b8fa3394b70e24a3a2118961d6005359d3952b 100644
--- a/ee/spec/requests/api/graphql/mutations/projects/chat_spec.rb
+++ b/ee/spec/requests/api/graphql/mutations/projects/chat_spec.rb
@@ -7,7 +7,7 @@
 
   let_it_be_with_reload(:group) { create(:group_with_plan, :public, plan: :ultimate_plan) }
   let_it_be(:project) { create(:project, :public, group: group) }
-  let_it_be(:current_user) { create(:user, developer_of: project) }
+  let_it_be(:current_user) { create(:user, developer_of: [project, group]) }
   let_it_be(:resource) { create(:issue, project: project) }
   let(:params) { { chat: { resource_id: resource&.to_gid, content: "summarize" } } }
 
@@ -19,10 +19,6 @@
     end
   end
 
-  before do
-    group.add_developer(current_user)
-  end
-
   include_context 'with ai features enabled for group'
 
   context 'when resource is nil' do
diff --git a/ee/spec/requests/api/graphql/mutations/projects/set_compliance_framework_spec.rb b/ee/spec/requests/api/graphql/mutations/projects/set_compliance_framework_spec.rb
index 043decef002e261e284c6a23b86bd09812b5788d..ade94bac7d6f993fb0d83a3f9cefff6def97efa2 100644
--- a/ee/spec/requests/api/graphql/mutations/projects/set_compliance_framework_spec.rb
+++ b/ee/spec/requests/api/graphql/mutations/projects/set_compliance_framework_spec.rb
@@ -8,11 +8,7 @@
   let_it_be(:namespace) { create(:group) }
   let_it_be(:project) { create(:project, namespace: namespace) }
   let_it_be(:framework) { create(:compliance_framework, namespace: namespace) }
-  let_it_be(:current_user) { create(:user) }
-
-  before do
-    namespace.add_owner(current_user)
-  end
+  let_it_be(:current_user) { create(:user, owner_of: namespace) }
 
   let(:variables) { { project_id: GitlabSchema.id_from_object(project).to_s, compliance_framework_id: GitlabSchema.id_from_object(framework).to_s } }
 
diff --git a/ee/spec/requests/api/graphql/mutations/releases/create_spec.rb b/ee/spec/requests/api/graphql/mutations/releases/create_spec.rb
index 304ea2ce7e2295096a1a8bffbd1d8ac4e0333662..a35a63c13327e90b35867d25c856692b3893c8c5 100644
--- a/ee/spec/requests/api/graphql/mutations/releases/create_spec.rb
+++ b/ee/spec/requests/api/graphql/mutations/releases/create_spec.rb
@@ -11,7 +11,7 @@
   let_it_be(:milestone_12_3) { create(:milestone, project: project, title: '12.3') }
   let_it_be(:milestone_12_4) { create(:milestone, project: project, title: '12.4') }
   let_it_be(:group_milestone) { create(:milestone, group: group, title: '13.1') }
-  let_it_be(:developer) { create(:user) }
+  let_it_be(:developer) { create(:user, developer_of: project) }
 
   let(:mutation_name) { :release_create }
 
@@ -44,10 +44,6 @@
   let(:create_release) { post_graphql_mutation(mutation, current_user: developer) }
   let(:mutation_response) { graphql_mutation_response(mutation_name)&.with_indifferent_access }
 
-  before do
-    project.add_developer(developer)
-  end
-
   context 'when the provided milestones include a group milestone' do
     context 'when the group milestone association feature is licensed' do
       before do
diff --git a/ee/spec/requests/api/graphql/mutations/releases/update_spec.rb b/ee/spec/requests/api/graphql/mutations/releases/update_spec.rb
index 1bf22739bc2ad5c4ba13a7ce8100c2ccae325f7a..ffd1ae851259324ee2e9e731fdb54e6b7f6a181d 100644
--- a/ee/spec/requests/api/graphql/mutations/releases/update_spec.rb
+++ b/ee/spec/requests/api/graphql/mutations/releases/update_spec.rb
@@ -11,7 +11,7 @@
   let_it_be(:milestone_12_3) { create(:milestone, project: project, title: '12.3') }
   let_it_be(:milestone_12_4) { create(:milestone, project: project, title: '12.4') }
   let_it_be(:group_milestone) { create(:milestone, group: group, title: '13.1') }
-  let_it_be(:developer) { create(:user) }
+  let_it_be(:developer) { create(:user, developer_of: project) }
   let_it_be(:tag_name) { 'v1.1.0' }
   let_it_be(:release) do
     create(:release, project: project, tag: tag_name)
@@ -45,10 +45,6 @@
   let(:update_release) { post_graphql_mutation(mutation, current_user: developer) }
   let(:mutation_response) { graphql_mutation_response(mutation_name)&.with_indifferent_access }
 
-  before do
-    project.add_developer(developer)
-  end
-
   context 'when the provided milestones include a group milestone' do
     context 'when the group milestone association feature is licensed' do
       before do
diff --git a/ee/spec/requests/api/graphql/mutations/users/abuse/namespace_bans/destroy_spec.rb b/ee/spec/requests/api/graphql/mutations/users/abuse/namespace_bans/destroy_spec.rb
index 05671b95969ccc6342c84f403ad58d8710df63eb..182e50b0474bd33186bd532777d18ed8264680ff 100644
--- a/ee/spec/requests/api/graphql/mutations/users/abuse/namespace_bans/destroy_spec.rb
+++ b/ee/spec/requests/api/graphql/mutations/users/abuse/namespace_bans/destroy_spec.rb
@@ -6,7 +6,7 @@
   include GraphqlHelpers
 
   let_it_be(:user) { create(:user) }
-  let_it_be(:namespace) { create(:group) }
+  let_it_be(:namespace) { create(:group, owners: user) }
   let_it_be(:namespace_ban) { create(:namespace_ban, namespace: namespace) }
 
   let(:mutation) do
@@ -34,10 +34,6 @@ def mutation_response
     graphql_mutation_response(:namespace_ban_destroy)
   end
 
-  before do
-    namespace.add_owner(user)
-  end
-
   it 'removes the ban' do
     post_graphql_mutation(mutation, current_user: user)
 
diff --git a/ee/spec/requests/api/graphql/project/compliance_framework_filters_spec.rb b/ee/spec/requests/api/graphql/project/compliance_framework_filters_spec.rb
index b4e71ec4c420989760e7dcd144e452ec0b951b93..8c641bc2187758fa9bc0d9217870aaa4f3930e9c 100644
--- a/ee/spec/requests/api/graphql/project/compliance_framework_filters_spec.rb
+++ b/ee/spec/requests/api/graphql/project/compliance_framework_filters_spec.rb
@@ -13,7 +13,7 @@
   end
 
   let_it_be(:user) { create(:user) }
-  let_it_be(:namespace) { create(:group) }
+  let_it_be(:namespace) { create(:group, owners: user) }
 
   let_it_be(:project_with_framework_1) { create(:project, group: namespace) }
   let_it_be(:project_with_framework_2) { create(:project, group: namespace) }
@@ -32,10 +32,6 @@
       compliance_management_framework: compliance_framework_2)
   end
 
-  before do
-    namespace.add_owner(user)
-  end
-
   subject(:execute_query) { post_graphql(query, current_user: user) }
 
   def projects_full_paths
diff --git a/ee/spec/requests/api/group_hooks_spec.rb b/ee/spec/requests/api/group_hooks_spec.rb
index 42edb8f2f3990f56d8aa148be5bffa3ce32085b4..dd05a866f9a8e900fc4b996e0ace3c2bde215c90 100644
--- a/ee/spec/requests/api/group_hooks_spec.rb
+++ b/ee/spec/requests/api/group_hooks_spec.rb
@@ -5,7 +5,7 @@
 RSpec.describe API::GroupHooks, :aggregate_failures, feature_category: :webhooks do
   let_it_be(:group_admin) { create(:user) }
   let_it_be(:non_admin_user) { create(:user) }
-  let_it_be(:group) { create(:group) }
+  let_it_be(:group) { create(:group, owners: group_admin) }
   let_it_be_with_refind(:hook) do
     create(:group_hook,
       :all_events_enabled,
@@ -14,10 +14,6 @@
       enable_ssl_verification: true)
   end
 
-  before do
-    group.add_owner(group_admin)
-  end
-
   it_behaves_like 'web-hook API endpoints', '/groups/:id' do
     let(:user) { group_admin }
     let(:unauthorized_user) { non_admin_user }
diff --git a/ee/spec/requests/api/helm_packages_spec.rb b/ee/spec/requests/api/helm_packages_spec.rb
index 63e2990bd8003cb09179f560d4239f870d9a8ca8..1098fa9a15d7d7e5a76fef1f7b4d645f3afc14d5 100644
--- a/ee/spec/requests/api/helm_packages_spec.rb
+++ b/ee/spec/requests/api/helm_packages_spec.rb
@@ -6,17 +6,13 @@
   include HttpBasicAuthHelpers
 
   let_it_be(:user) { create(:user) }
-  let_it_be(:group) { create(:group) }
+  let_it_be(:group) { create(:group, maintainers: user) }
   let_it_be(:project) { create(:project, group: group) }
   let_it_be(:package) { create(:helm_package, project: project) }
   let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
 
   let(:headers) { basic_auth_header(user.username, personal_access_token.token) }
 
-  before do
-    group.add_maintainer(user)
-  end
-
   describe 'GET /api/v4/projects/:id/packages/helm/:channel/charts/:file_name.tgz' do
     let(:url) { "/projects/#{project.id}/packages/helm/stable/charts/#{package.name}-#{package.version}.tgz" }
 
diff --git a/ee/spec/requests/api/issue_links_spec.rb b/ee/spec/requests/api/issue_links_spec.rb
index a9b2c6f37e0a941827b63557728a50456e3121c1..27bd731938a66531032de6228fabc6ef93255f82 100644
--- a/ee/spec/requests/api/issue_links_spec.rb
+++ b/ee/spec/requests/api/issue_links_spec.rb
@@ -4,14 +4,10 @@
 
 RSpec.describe API::IssueLinks, feature_category: :team_planning do
   let_it_be(:user) { create(:user) }
-  let_it_be(:project) { create(:project) }
+  let_it_be(:project) { create(:project, reporters: user) }
   let_it_be(:issue) { create(:issue, project: project) }
   let_it_be(:target_issue) { create(:issue, project: project) }
 
-  before do
-    project.add_reporter(user)
-  end
-
   describe 'POST /links' do
     context 'when creating a blocked relationship' do
       context 'when feature is enabled' do
diff --git a/ee/spec/requests/api/maven_packages_spec.rb b/ee/spec/requests/api/maven_packages_spec.rb
index 6b1d1f3718cc918cd43a35cc64aea6a1437075d6..c3c5306eb922b7992483512d4032d5eb4b0a9e45 100644
--- a/ee/spec/requests/api/maven_packages_spec.rb
+++ b/ee/spec/requests/api/maven_packages_spec.rb
@@ -7,7 +7,7 @@
 
   let_it_be(:user) { create(:user) }
   let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
-  let_it_be(:group) { create(:group) }
+  let_it_be(:group) { create(:group, maintainers: user) }
   let_it_be(:project) { create(:project, group: group) }
   let_it_be(:package) { create(:maven_package, project: project, name: project.full_path) }
   let_it_be(:maven_metadatum) { package.maven_metadatum }
@@ -15,10 +15,6 @@
 
   let(:headers) { { 'Private-Token' => personal_access_token.token } }
 
-  before do
-    group.add_maintainer(user)
-  end
-
   describe 'GET /api/v4/groups/:id/-/packages/maven/*path/:file_name' do
     let(:url) { "/groups/#{group.id}/-/packages/maven/#{maven_metadatum.path}/#{package_file.file_name}" }
 
diff --git a/ee/spec/requests/api/merge_requests_spec.rb b/ee/spec/requests/api/merge_requests_spec.rb
index 5a32b7d26d7422a5e271b6872c9cd46242ffde56..53ed49d9ed0cf89c36d2792e9e888657268c9894 100644
--- a/ee/spec/requests/api/merge_requests_spec.rb
+++ b/ee/spec/requests/api/merge_requests_spec.rb
@@ -7,7 +7,7 @@
 
   let_it_be(:user)       { create(:user) }
   let_it_be(:user2)      { create(:user) }
-  let_it_be(:project)    { create(:project, :public, :repository, creator: user, namespace: user.namespace, only_allow_merge_if_pipeline_succeeds: false) }
+  let_it_be(:project)    { create(:project, :public, :repository, creator: user, namespace: user.namespace, only_allow_merge_if_pipeline_succeeds: false, reporters: user) }
   let_it_be(:milestone)  { create(:milestone, title: '1.0.0', project: project) }
   let_it_be(:milestone1) { create(:milestone, title: '0.9', project: project) }
   let_it_be(:label)      { create(:label, title: 'label', color: '#FFAABB', project: project) }
@@ -16,10 +16,6 @@
   let(:base_time)        { Time.now }
   let!(:merge_request)   { create(:merge_request, :simple, milestone: milestone1, author: user, assignees: [user, user2], source_project: project, target_project: project, title: "Test", created_at: base_time) }
 
-  before do
-    project.add_reporter(user)
-  end
-
   describe 'PUT /projects/:id/merge_requests' do
     def update_merge_request(params)
       put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: params
diff --git a/ee/spec/requests/api/npm_project_packages_spec.rb b/ee/spec/requests/api/npm_project_packages_spec.rb
index 059aa7deef3141c3a2cd308ea5fca71d03e03021..dcefad78fca18989870a882ae1e7bc80c24dd016 100644
--- a/ee/spec/requests/api/npm_project_packages_spec.rb
+++ b/ee/spec/requests/api/npm_project_packages_spec.rb
@@ -6,17 +6,13 @@
   include HttpBasicAuthHelpers
 
   let_it_be(:user) { create(:user) }
-  let_it_be(:group) { create(:group) }
+  let_it_be(:group) { create(:group, maintainers: user) }
   let_it_be(:project) { create(:project, :public, group: group) }
   let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
   let_it_be(:package) { create(:npm_package, project: project) }
 
   let(:headers) { basic_auth_header(user.username, personal_access_token.token) }
 
-  before do
-    group.add_maintainer(user)
-  end
-
   describe 'GET /api/v4/projects/:id/packages/npm/*package_name/-/*file_name' do
     let(:package_file) { package.package_files.first }
     let(:url) { "/projects/#{project.id}/packages/npm/#{package.name}/-/#{package_file.file_name}" }
diff --git a/ee/spec/requests/api/nuget_group_packages_spec.rb b/ee/spec/requests/api/nuget_group_packages_spec.rb
index 7c143ce80f905e0116f96783ea72d68958616da8..bf6753ed8427030c5e9caac89fa3641969e2df0f 100644
--- a/ee/spec/requests/api/nuget_group_packages_spec.rb
+++ b/ee/spec/requests/api/nuget_group_packages_spec.rb
@@ -6,7 +6,7 @@
   include HttpBasicAuthHelpers
 
   let_it_be(:user) { create(:user) }
-  let_it_be(:group) { create(:group) }
+  let_it_be(:group) { create(:group, maintainers: user) }
   let_it_be(:project) { create(:project, group: group) }
   let_it_be(:package_name) { 'Dummy.Package' }
   let_it_be(:package) { create(:nuget_package, :with_symbol_package, project: project, name: package_name) }
@@ -15,10 +15,6 @@
 
   let(:headers) { basic_auth_header(user.username, personal_access_token.token) }
 
-  before do
-    group.add_maintainer(user)
-  end
-
   describe 'GET /api/v4/groups/:id/-/packages/nuget/metadata/*package_name/*package_version' do
     let(:url) { "/groups/#{group.id}/-/packages/nuget/metadata/#{package_name}/#{version}.json" }
 
diff --git a/ee/spec/requests/api/nuget_project_packages_spec.rb b/ee/spec/requests/api/nuget_project_packages_spec.rb
index e916afbdf84006bdec1c36054306ecc84b177fe5..98240dc0e871e4a2bf2b81ef50578accdc1e045f 100644
--- a/ee/spec/requests/api/nuget_project_packages_spec.rb
+++ b/ee/spec/requests/api/nuget_project_packages_spec.rb
@@ -6,7 +6,7 @@
   include HttpBasicAuthHelpers
 
   let_it_be(:user) { create(:user) }
-  let_it_be(:group) { create(:group) }
+  let_it_be(:group) { create(:group, maintainers: user) }
   let_it_be(:project) { create(:project, group: group) }
   let_it_be(:package_name) { 'Dummy.Package' }
   let_it_be(:package) { create(:nuget_package, :with_symbol_package, project: project, name: package_name) }
@@ -15,10 +15,6 @@
 
   let(:headers) { basic_auth_header(user.username, personal_access_token.token) }
 
-  before do
-    group.add_maintainer(user)
-  end
-
   describe 'GET /api/v4/projects/:id/packages/nuget/download/*package_name/*package_version/*package_filename' do
     let(:url) do
       "/projects/#{project.id}/packages/nuget/download/#{package.name}/#{version}/#{package.name}.#{version}.nupkg"
diff --git a/ee/spec/requests/api/pypi_packages_spec.rb b/ee/spec/requests/api/pypi_packages_spec.rb
index 5b4f8f58eac49357c8c71d1844e4693d0f1da995..75b37cdee1a8bb82d3d86932560caeaca6b83f40 100644
--- a/ee/spec/requests/api/pypi_packages_spec.rb
+++ b/ee/spec/requests/api/pypi_packages_spec.rb
@@ -8,7 +8,7 @@
   using RSpec::Parameterized::TableSyntax
 
   let_it_be(:user) { create(:user) }
-  let_it_be(:group) { create(:group) }
+  let_it_be(:group) { create(:group, maintainers: user) }
   let_it_be(:project) { create(:project, group: group) }
   let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
   let_it_be(:package_name) { 'Dummy-Package' }
@@ -21,10 +21,6 @@
 
   subject { get api(url), headers: headers }
 
-  before do
-    group.add_maintainer(user)
-  end
-
   describe 'GET /api/v4/groups/:id/-/packages/pypi/files/:sha256/*file_identifier' do
     let(:url) { "/groups/#{group.id}/-/packages/pypi/files/#{package.package_files.first.file_sha256}/#{package_name}-1.0.0.tar.gz" } # rubocop:disable convention:Layout/LineLength
 
diff --git a/ee/spec/requests/api/remote_mirrors_spec.rb b/ee/spec/requests/api/remote_mirrors_spec.rb
index 39549ab96cbeb1dc788f9b7bf95963b88a6033a2..0f3da6ff36b144d437ce253e338f55f6e9b16aa0 100644
--- a/ee/spec/requests/api/remote_mirrors_spec.rb
+++ b/ee/spec/requests/api/remote_mirrors_spec.rb
@@ -4,13 +4,9 @@
 
 RSpec.describe API::RemoteMirrors, feature_category: :source_code_management do
   let_it_be(:user) { create(:user) }
-  let_it_be(:project) { create(:project, :repository, :remote_mirror) }
+  let_it_be(:project) { create(:project, :repository, :remote_mirror, maintainers: user) }
   let_it_be(:project_setting) { create(:project_setting, project: project) }
 
-  before do
-    project.add_maintainer(user)
-  end
-
   describe 'POST /projects/:id/remote_mirrors' do
     let(:route) { "/projects/#{project.id}/remote_mirrors" }
 
diff --git a/ee/spec/requests/api/resource_weight_events_spec.rb b/ee/spec/requests/api/resource_weight_events_spec.rb
index 6bd44157675870048c6ac1a735463bf2ca0c1cba..89390549d9eb7bd403d686ffbd11936129f17d56 100644
--- a/ee/spec/requests/api/resource_weight_events_spec.rb
+++ b/ee/spec/requests/api/resource_weight_events_spec.rb
@@ -4,13 +4,9 @@
 
 RSpec.describe ::API::ResourceWeightEvents, feature_category: :team_planning do
   let_it_be(:user) { create(:user) }
-  let_it_be(:project, reload: true) { create(:project, :public, namespace: user.namespace) }
+  let_it_be(:project, reload: true) { create(:project, :public, namespace: user.namespace, developers: user) }
   let_it_be(:issue) { create(:issue, project: project, author: user) }
 
-  before do
-    project.add_developer(user)
-  end
-
   describe "GET /projects/:id/issues/:noteable_id/resource_weight_events" do
     let!(:event) { create_event }
 
diff --git a/ee/spec/requests/api/rubygem_packages_spec.rb b/ee/spec/requests/api/rubygem_packages_spec.rb
index d2c9cf26eb1aa7774ba0868c452b0acaf1e20213..5870384009dd4bb306042bd3938776389a9fa288 100644
--- a/ee/spec/requests/api/rubygem_packages_spec.rb
+++ b/ee/spec/requests/api/rubygem_packages_spec.rb
@@ -6,7 +6,7 @@
   include HttpBasicAuthHelpers
 
   let_it_be(:user) { create(:user) }
-  let_it_be(:group) { create(:group) }
+  let_it_be(:group) { create(:group, maintainers: user) }
   let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
   let_it_be(:project) { create(:project, group: group) }
   let_it_be(:package_name) { 'package' }
@@ -16,10 +16,6 @@
 
   let(:headers) { build_auth_headers(personal_access_token.token) }
 
-  before do
-    group.add_maintainer(user)
-  end
-
   describe 'GET /api/v4/projects/:project_id/packages/rubygems/gems/:file_name' do
     let(:url) { api("/projects/#{project.id}/packages/rubygems/gems/#{file_name}") }
 
diff --git a/ee/spec/requests/repositories/git_http_controller_spec.rb b/ee/spec/requests/repositories/git_http_controller_spec.rb
index dee4bfe92c6c60372d6b09336ebac0815f4a577f..f41a97bd1f5166fb555f7620206d256e69ac09f5 100644
--- a/ee/spec/requests/repositories/git_http_controller_spec.rb
+++ b/ee/spec/requests/repositories/git_http_controller_spec.rb
@@ -7,15 +7,11 @@
   include ::EE::GeoHelpers
 
   let_it_be(:user) { create(:user) }
-  let_it_be(:project) { create(:project, :repository, :private) }
+  let_it_be(:project) { create(:project, :repository, :private, developers: user) }
 
   let(:env) { { user: user.username, password: user.password } }
   let(:path) { "#{project.full_path}.git" }
 
-  before do
-    project.add_developer(user)
-  end
-
   describe 'POST #git_upload_pack' do
     context 'geo pulls a personal snippet' do
       let_it_be(:snippet) { create(:personal_snippet, :repository, author: user) }
diff --git a/spec/requests/api/ci/pipelines_spec.rb b/spec/requests/api/ci/pipelines_spec.rb
index ee39a9eb2e6bef18a57efab4d5eadc64b45aff7d..14d96f8c0c6de803f5a41e28211cb7cfa679a560 100644
--- a/spec/requests/api/ci/pipelines_spec.rb
+++ b/spec/requests/api/ci/pipelines_spec.rb
@@ -9,7 +9,7 @@
 
   # We need to reload as the shared example 'pipelines visibility table' is changing project
   let_it_be(:project, reload: true) do
-    create(:project, :repository, creator: user)
+    create(:project, :repository, creator: user, maintainers: user)
   end
 
   let_it_be(:pipeline) do
@@ -23,10 +23,6 @@
     )
   end
 
-  before do
-    project.add_maintainer(user)
-  end
-
   describe 'GET /projects/:id/pipelines ' do
     it_behaves_like 'pipelines visibility table'
 
diff --git a/spec/requests/api/draft_notes_spec.rb b/spec/requests/api/draft_notes_spec.rb
index fc465fa7c425892c24b4e18a15b877a76108a698..3d44dbf454f40daf70834a1cdcf826d31d3797ac 100644
--- a/spec/requests/api/draft_notes_spec.rb
+++ b/spec/requests/api/draft_notes_spec.rb
@@ -5,7 +5,7 @@
 RSpec.describe API::DraftNotes, feature_category: :code_review_workflow do
   let_it_be(:user) { create(:user) }
   let_it_be(:user_2) { create(:user) }
-  let_it_be(:project) { create(:project, :public, :repository) }
+  let_it_be(:project) { create(:project, :public, :repository, developers: user) }
   let_it_be(:merge_request) { create(:merge_request, source_project: project, target_project: project, author: user) }
 
   let_it_be(:private_project) { create(:project, :private) }
@@ -19,10 +19,6 @@
 
   let_it_be(:base_url) { "/projects/#{project.id}/merge_requests/#{merge_request.iid}/draft_notes" }
 
-  before do
-    project.add_developer(user)
-  end
-
   describe "Get a list of merge request draft notes" do
     it "returns 200 OK status" do
       get api(base_url, user)
diff --git a/spec/requests/api/environments_spec.rb b/spec/requests/api/environments_spec.rb
index 23ebe8d4e7c593ee6a10de7e29596916126453c4..954d7b86101cbe8b92ab1aa8703cf22ebc02d850 100644
--- a/spec/requests/api/environments_spec.rb
+++ b/spec/requests/api/environments_spec.rb
@@ -6,14 +6,9 @@
   let_it_be(:user) { create(:user) }
   let_it_be(:developer) { create(:user) }
   let_it_be(:non_member) { create(:user) }
-  let_it_be(:project) { create(:project, :private, :repository, namespace: user.namespace) }
+  let_it_be(:project) { create(:project, :private, :repository, namespace: user.namespace, maintainers: user, developers: developer) }
   let_it_be_with_reload(:environment) { create(:environment, project: project) }
 
-  before do
-    project.add_maintainer(user)
-    project.add_developer(developer)
-  end
-
   describe 'GET /projects/:id/environments', :aggregate_failures do
     context 'as member of the project' do
       it 'returns project environments' do
diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb
index aa30b58338eff051388b063bb9ad9343e34586fb..32a348fc2c9709747fdd72e92c7854422bb83ce1 100644
--- a/spec/requests/api/files_spec.rb
+++ b/spec/requests/api/files_spec.rb
@@ -29,7 +29,7 @@ def header(key, value)
   let_it_be(:inherited_reporter) { create(:user, reporter_of: group) }
   let_it_be(:inherited_developer) { create(:user, developer_of: group) }
 
-  let_it_be_with_reload(:project) { create(:project, :repository, namespace: user.namespace) }
+  let_it_be_with_reload(:project) { create(:project, :repository, namespace: user.namespace, developers: user) }
   let_it_be_with_reload(:public_project) { create(:project, :public, :repository) }
   let_it_be_with_reload(:private_project) { create(:project, :private, :repository, group: group) }
   let_it_be_with_reload(:public_project_private_repo) { create(:project, :public, :repository, :repository_private, group: group) }
@@ -65,10 +65,6 @@ def header(key, value)
     let(:author_name) { 'John Doe' }
   end
 
-  before do
-    project.add_developer(user)
-  end
-
   def route(file_path = nil)
     "/projects/#{project.id}/repository/files/#{file_path}"
   end
diff --git a/spec/requests/api/graphql/ci/manual_variables_spec.rb b/spec/requests/api/graphql/ci/manual_variables_spec.rb
index 41788881e624fbeb0b5e9028a2ab05e1bc187253..3f859d3e8cd8ae291cb0106ba147f45466cee298 100644
--- a/spec/requests/api/graphql/ci/manual_variables_spec.rb
+++ b/spec/requests/api/graphql/ci/manual_variables_spec.rb
@@ -7,7 +7,7 @@
 
   let_it_be(:project) { create(:project) }
   let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
-  let_it_be(:user) { create(:user) }
+  let_it_be(:user) { create(:user, maintainer_of: project) }
 
   let(:query) do
     %(
@@ -31,10 +31,6 @@
     )
   end
 
-  before do
-    project.add_maintainer(user)
-  end
-
   it 'returns the manual variables for actionable jobs' do
     job = create(:ci_build, :actionable, pipeline: pipeline)
     create(:ci_job_variable, key: 'MANUAL_TEST_VAR', job: job)
diff --git a/spec/requests/api/graphql/ci/runners_spec.rb b/spec/requests/api/graphql/ci/runners_spec.rb
index e4003f747bb7cb277805d99da7a8e3f9f834491f..bee84b3b5c0693945b93503043b5e360f4c5e74b 100644
--- a/spec/requests/api/graphql/ci/runners_spec.rb
+++ b/spec/requests/api/graphql/ci/runners_spec.rb
@@ -341,11 +341,7 @@ def pagination_results_data(runners)
   include GraphqlHelpers
 
   let_it_be(:group) { create(:group) }
-  let_it_be(:group_owner) { create_default(:user) }
-
-  before do
-    group.add_owner(group_owner)
-  end
+  let_it_be(:group_owner) { create_default(:user, owner_of: group) }
 
   describe 'edges' do
     let_it_be(:runner) do
diff --git a/spec/requests/api/graphql/crm/contacts_spec.rb b/spec/requests/api/graphql/crm/contacts_spec.rb
index b6785491388f1199029e3471684be6a24e0e58ce..8e17e39c567edea519ccc73ce5fbc6306edb5e4f 100644
--- a/spec/requests/api/graphql/crm/contacts_spec.rb
+++ b/spec/requests/api/graphql/crm/contacts_spec.rb
@@ -6,7 +6,7 @@
   include GraphqlHelpers
 
   let_it_be(:current_user) { create(:user) }
-  let_it_be(:group) { create(:group) }
+  let_it_be(:group) { create(:group, reporters: current_user) }
 
   let_it_be(:contact_a) do
     create(
@@ -44,10 +44,6 @@
     )
   end
 
-  before do
-    group.add_reporter(current_user)
-  end
-
   it_behaves_like 'sorted paginated query' do
     let(:sort_argument) { {} }
     let(:first_param) { 2 }
diff --git a/spec/requests/api/graphql/custom_emoji_query_spec.rb b/spec/requests/api/graphql/custom_emoji_query_spec.rb
index e09a71d1f903b35c59a4b8134a8037be4b54f37e..13fa97bb62c90c7895546abfba51e996edf7d764 100644
--- a/spec/requests/api/graphql/custom_emoji_query_spec.rb
+++ b/spec/requests/api/graphql/custom_emoji_query_spec.rb
@@ -6,13 +6,9 @@
   include GraphqlHelpers
 
   let_it_be(:current_user) { create(:user) }
-  let_it_be(:group) { create(:group, :private) }
+  let_it_be(:group) { create(:group, :private, developers: current_user) }
   let_it_be(:custom_emoji) { create(:custom_emoji, group: group, file: 'http://example.com/test.png') }
 
-  before do
-    group.add_developer(current_user)
-  end
-
   describe "Query CustomEmoji on Group" do
     def custom_emoji_query(group)
       fields = all_graphql_fields_for('Group')
diff --git a/spec/requests/api/graphql/group/merge_requests_spec.rb b/spec/requests/api/graphql/group/merge_requests_spec.rb
index 207ff360b2ffd34b8f22243652f46a4186bf4c8d..5eac66fdadd491ca001ad1a96c350918bd5df37b 100644
--- a/spec/requests/api/graphql/group/merge_requests_spec.rb
+++ b/spec/requests/api/graphql/group/merge_requests_spec.rb
@@ -14,7 +14,7 @@
   let_it_be(:project_b) { create(:project, :repository, group: group) }
   let_it_be(:project_c) { create(:project, :repository, group: sub_group) }
   let_it_be(:project_x) { create(:project, :repository) }
-  let_it_be(:user)      { create(:user, developer_of: project_x) }
+  let_it_be(:user)      { create(:user, developer_of: [project_x, group]) }
 
   let_it_be(:archived_project) { create(:project, :archived, :repository, group: group) }
   let_it_be(:archived_mr) { create(:merge_request, source_project: archived_project) }
@@ -34,10 +34,6 @@
 
   let(:mrs_data) { graphql_data_at(:group, :merge_requests, :nodes) }
 
-  before do
-    group.add_developer(user)
-  end
-
   def expected_mrs(mrs)
     mrs.map { |mr| a_graphql_entity_for(mr) }
   end
diff --git a/spec/requests/api/graphql/mutations/alert_management/alerts/create_alert_issue_spec.rb b/spec/requests/api/graphql/mutations/alert_management/alerts/create_alert_issue_spec.rb
index f2b516783e5feca2dd44b3458f6d66896cf8bde6..bf11cdd66800eac120b697d18bdf6da13f382643 100644
--- a/spec/requests/api/graphql/mutations/alert_management/alerts/create_alert_issue_spec.rb
+++ b/spec/requests/api/graphql/mutations/alert_management/alerts/create_alert_issue_spec.rb
@@ -6,7 +6,7 @@
   include GraphqlHelpers
 
   let_it_be(:user) { create(:user) }
-  let_it_be(:project) { create(:project) }
+  let_it_be(:project) { create(:project, developers: user) }
   let_it_be(:alert) { create(:alert_management_alert, project: project) }
 
   let(:mutation) do
@@ -36,10 +36,6 @@
 
   let(:mutation_response) { graphql_mutation_response(:create_alert_issue) }
 
-  before do
-    project.add_developer(user)
-  end
-
   context 'when there is no issue associated with the alert' do
     it 'creates an alert issue' do
       post_graphql_mutation(mutation, current_user: user)
diff --git a/spec/requests/api/graphql/mutations/alert_management/alerts/todo/create_spec.rb b/spec/requests/api/graphql/mutations/alert_management/alerts/todo/create_spec.rb
index 570324a31264756a3943768958d16fe0599a715f..615f3f7fdd419ac5150ee5583ffd1199f84e0454 100644
--- a/spec/requests/api/graphql/mutations/alert_management/alerts/todo/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/alert_management/alerts/todo/create_spec.rb
@@ -6,7 +6,7 @@
   include GraphqlHelpers
 
   let_it_be(:user) { create(:user) }
-  let_it_be(:project) { create(:project) }
+  let_it_be(:project) { create(:project, developers: user) }
 
   let(:alert) { create(:alert_management_alert, project: project) }
 
@@ -30,10 +30,6 @@
 
   let(:mutation_response) { graphql_mutation_response(:alert_todo_create) }
 
-  before do
-    project.add_developer(user)
-  end
-
   it 'creates a todo for the current user' do
     post_graphql_mutation(mutation, current_user: user)
 
diff --git a/spec/requests/api/graphql/mutations/alert_management/alerts/update_alert_status_spec.rb b/spec/requests/api/graphql/mutations/alert_management/alerts/update_alert_status_spec.rb
index 6537747850c1869f108a14d2f755ae0c1729a476..85e6470f3825557765372bae1a0f91d8546aea54 100644
--- a/spec/requests/api/graphql/mutations/alert_management/alerts/update_alert_status_spec.rb
+++ b/spec/requests/api/graphql/mutations/alert_management/alerts/update_alert_status_spec.rb
@@ -6,7 +6,7 @@
   include GraphqlHelpers
 
   let_it_be(:user) { create(:user) }
-  let_it_be(:project) { create(:project) }
+  let_it_be(:project) { create(:project, developers: user) }
 
   let(:alert) { create(:alert_management_alert, project: project) }
   let(:input) { { status: 'ACKNOWLEDGED' } }
@@ -30,10 +30,6 @@
 
   let(:mutation_response) { graphql_mutation_response(:update_alert_status) }
 
-  before do
-    project.add_developer(user)
-  end
-
   it 'updates the status of the alert' do
     post_graphql_mutation(mutation, current_user: user)
 
diff --git a/spec/requests/api/graphql/mutations/alert_management/http_integration/create_spec.rb b/spec/requests/api/graphql/mutations/alert_management/http_integration/create_spec.rb
index b0e9f59b9965905d13306f189594326b771aaa51..6c09567d32cd1a647b7b3f467b7b6867709e8325 100644
--- a/spec/requests/api/graphql/mutations/alert_management/http_integration/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/alert_management/http_integration/create_spec.rb
@@ -6,7 +6,7 @@
   include GraphqlHelpers
 
   let_it_be(:current_user) { create(:user) }
-  let_it_be(:project) { create(:project) }
+  let_it_be(:project) { create(:project, maintainers: current_user) }
 
   let(:variables) do
     {
@@ -36,10 +36,6 @@
 
   let(:mutation_response) { graphql_mutation_response(:http_integration_create) }
 
-  before do
-    project.add_maintainer(current_user)
-  end
-
   it_behaves_like 'creating a new HTTP integration'
 
   [:project_path, :active, :name].each do |argument|
diff --git a/spec/requests/api/graphql/mutations/alert_management/http_integration/destroy_spec.rb b/spec/requests/api/graphql/mutations/alert_management/http_integration/destroy_spec.rb
index 110c65d24a0c5f66eb11a2dd6ea37b5430fc8cb7..0162f9c7b22d8ea653d538f366d727111b068ca4 100644
--- a/spec/requests/api/graphql/mutations/alert_management/http_integration/destroy_spec.rb
+++ b/spec/requests/api/graphql/mutations/alert_management/http_integration/destroy_spec.rb
@@ -6,7 +6,7 @@
   include GraphqlHelpers
 
   let_it_be(:user) { create(:user) }
-  let_it_be(:project) { create(:project) }
+  let_it_be(:project) { create(:project, maintainers: user) }
   let_it_be(:integration) { create(:alert_management_http_integration, project: project) }
 
   let(:mutation) do
@@ -32,10 +32,6 @@
 
   let(:mutation_response) { graphql_mutation_response(:http_integration_destroy) }
 
-  before do
-    project.add_maintainer(user)
-  end
-
   it 'removes the integration' do
     post_graphql_mutation(mutation, current_user: user)
 
diff --git a/spec/requests/api/graphql/mutations/alert_management/http_integration/reset_token_spec.rb b/spec/requests/api/graphql/mutations/alert_management/http_integration/reset_token_spec.rb
index 049d7e8dace4875fb0834accc62c29239a5498c5..df08c7bc4780d00f475cea3d0fefe0d63b40abce 100644
--- a/spec/requests/api/graphql/mutations/alert_management/http_integration/reset_token_spec.rb
+++ b/spec/requests/api/graphql/mutations/alert_management/http_integration/reset_token_spec.rb
@@ -6,7 +6,7 @@
   include GraphqlHelpers
 
   let_it_be(:user) { create(:user) }
-  let_it_be(:project) { create(:project) }
+  let_it_be(:project) { create(:project, maintainers: user) }
   let_it_be(:integration) { create(:alert_management_http_integration, project: project) }
 
   let(:mutation) do
@@ -27,10 +27,6 @@
 
   let(:mutation_response) { graphql_mutation_response(:http_integration_reset_token) }
 
-  before do
-    project.add_maintainer(user)
-  end
-
   it 'updates the integration' do
     previous_token = integration.token
 
diff --git a/spec/requests/api/graphql/mutations/alert_management/http_integration/update_spec.rb b/spec/requests/api/graphql/mutations/alert_management/http_integration/update_spec.rb
index 70adff1fdc4df26a50c9bcfa7fea345532859d73..8c2d34ed1e5f459bb46013edc027aa8d3cd14a52 100644
--- a/spec/requests/api/graphql/mutations/alert_management/http_integration/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/alert_management/http_integration/update_spec.rb
@@ -6,7 +6,7 @@
   include GraphqlHelpers
 
   let_it_be(:current_user) { create(:user) }
-  let_it_be(:project) { create(:project) }
+  let_it_be(:project) { create(:project, maintainers: current_user) }
   let_it_be(:integration) { create(:alert_management_http_integration, project: project) }
 
   let(:mutation) do
@@ -31,9 +31,5 @@
 
   let(:mutation_response) { graphql_mutation_response(:http_integration_update) }
 
-  before do
-    project.add_maintainer(current_user)
-  end
-
   it_behaves_like 'updating an existing HTTP integration'
 end
diff --git a/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/create_spec.rb b/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/create_spec.rb
index ec94760e3f0d88e8a57d28673566c20a2436e253..0ab87941e6b71e9459f48d93eb0434a624047066 100644
--- a/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/create_spec.rb
@@ -6,7 +6,7 @@
   include GraphqlHelpers
 
   let_it_be(:current_user) { create(:user) }
-  let_it_be(:project) { create(:project) }
+  let_it_be(:project) { create(:project, maintainers: current_user) }
 
   let(:api_url) { 'https://prometheus-url.com' }
 
@@ -38,10 +38,6 @@
 
   let(:mutation_response) { graphql_mutation_response(:prometheus_integration_create) }
 
-  before do
-    project.add_maintainer(current_user)
-  end
-
   it 'creates a new integration' do
     post_graphql_mutation(mutation, current_user: current_user)
 
diff --git a/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/reset_token_spec.rb b/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/reset_token_spec.rb
index 15127843b95bdfa0cd69a7375c670c6e9596e8b4..7b00c9e3802a6ca6f64959b748357335c933b372 100644
--- a/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/reset_token_spec.rb
+++ b/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/reset_token_spec.rb
@@ -6,7 +6,7 @@
   include GraphqlHelpers
 
   let_it_be(:user) { create(:user) }
-  let_it_be(:project) { create(:project) }
+  let_it_be(:project) { create(:project, maintainers: user) }
   let_it_be(:integration) { create(:prometheus_integration, project: project) }
 
   let(:mutation) do
@@ -27,10 +27,6 @@
 
   let(:mutation_response) { graphql_mutation_response(:prometheus_integration_reset_token) }
 
-  before do
-    project.add_maintainer(user)
-  end
-
   it 'creates a token' do
     post_graphql_mutation(mutation, current_user: user)
     integration_response = mutation_response['integration']
diff --git a/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/update_spec.rb b/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/update_spec.rb
index 63e95f4513b44a4a62e6d6ffb4eb7e35ec691062..3219127fb5a01c44d51c7ab0e0f2f1039930329a 100644
--- a/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/update_spec.rb
@@ -6,7 +6,7 @@
   include GraphqlHelpers
 
   let_it_be(:user) { create(:user) }
-  let_it_be(:project) { create(:project) }
+  let_it_be(:project) { create(:project, maintainers: user) }
   let_it_be(:integration) { create(:prometheus_integration, project: project) }
 
   let(:mutation) do
@@ -30,10 +30,6 @@
 
   let(:mutation_response) { graphql_mutation_response(:prometheus_integration_update) }
 
-  before do
-    project.add_maintainer(user)
-  end
-
   it 'updates the integration' do
     post_graphql_mutation(mutation, current_user: user)
 
diff --git a/spec/requests/api/graphql/mutations/ci/runner/create_spec.rb b/spec/requests/api/graphql/mutations/ci/runner/create_spec.rb
index 567ef12df2b61e5318642cc37aa807424637aaf3..53f401e71db03e6bd9ef2e3b58e19617bc0c6f1b 100644
--- a/spec/requests/api/graphql/mutations/ci/runner/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/ci/runner/create_spec.rb
@@ -9,7 +9,7 @@
   let_it_be(:group_owner) { create(:user) }
   let_it_be(:admin) { create(:admin) }
 
-  let_it_be(:group) { create(:group) }
+  let_it_be(:group) { create(:group, owners: group_owner) }
   let_it_be(:other_group) { create(:group) }
 
   let(:mutation_params) do
@@ -53,10 +53,6 @@
 
   let(:mutation_response) { graphql_mutation_response(:runner_create) }
 
-  before do
-    group.add_owner(group_owner)
-  end
-
   shared_context 'when model is invalid returns error' do
     let(:mutation_params) do
       {
diff --git a/spec/requests/api/graphql/mutations/incident_management/timeline_event/create_spec.rb b/spec/requests/api/graphql/mutations/incident_management/timeline_event/create_spec.rb
index 49cee4f680179d3b5125eef6440408e594fa1027..e1a5d14fed748a76e2b3b8c5c81a9bab00b1918e 100644
--- a/spec/requests/api/graphql/mutations/incident_management/timeline_event/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/incident_management/timeline_event/create_spec.rb
@@ -6,7 +6,7 @@
   include GraphqlHelpers
 
   let_it_be(:user) { create(:user) }
-  let_it_be(:project) { create(:project) }
+  let_it_be(:project) { create(:project, developers: user) }
   let_it_be(:incident) { create(:incident, project: project) }
   let_it_be(:event_occurred_at) { Time.current }
   let_it_be(:note) { 'demo note' }
@@ -41,10 +41,6 @@
 
   let(:mutation_response) { graphql_mutation_response(:timeline_event_create) }
 
-  before do
-    project.add_developer(user)
-  end
-
   it 'creates incident timeline event', :aggregate_failures do
     post_graphql_mutation(mutation, current_user: user)
 
diff --git a/spec/requests/api/graphql/mutations/incident_management/timeline_event/destroy_spec.rb b/spec/requests/api/graphql/mutations/incident_management/timeline_event/destroy_spec.rb
index 6e1a7b367369de57cda7260bdfc5ad4fe68aa7c5..53bf5101ee8e50c8de51db2a3e954c2d979d5cff 100644
--- a/spec/requests/api/graphql/mutations/incident_management/timeline_event/destroy_spec.rb
+++ b/spec/requests/api/graphql/mutations/incident_management/timeline_event/destroy_spec.rb
@@ -6,7 +6,7 @@
   include GraphqlHelpers
 
   let_it_be(:user) { create(:user) }
-  let_it_be(:project) { create(:project) }
+  let_it_be(:project) { create(:project, developers: user) }
   let_it_be(:incident) { create(:incident, project: project) }
   let_it_be(:timeline_event) { create(:incident_management_timeline_event, incident: incident, project: project) }
 
@@ -35,10 +35,6 @@
 
   let(:mutation_response) { graphql_mutation_response(:timeline_event_destroy) }
 
-  before do
-    project.add_developer(user)
-  end
-
   it 'removes incident timeline event', :aggregate_failures do
     post_graphql_mutation(mutation, current_user: user)
 
diff --git a/spec/requests/api/graphql/mutations/incident_management/timeline_event/promote_from_note_spec.rb b/spec/requests/api/graphql/mutations/incident_management/timeline_event/promote_from_note_spec.rb
index ca9557b31832f1d92d45a6132940d629488c266c..b7d72917448514e1c7fc3dfc3fe962a8cc8e4a1e 100644
--- a/spec/requests/api/graphql/mutations/incident_management/timeline_event/promote_from_note_spec.rb
+++ b/spec/requests/api/graphql/mutations/incident_management/timeline_event/promote_from_note_spec.rb
@@ -7,7 +7,7 @@
   include NotesHelper
 
   let_it_be(:user) { create(:user) }
-  let_it_be(:project) { create(:project) }
+  let_it_be(:project) { create(:project, developers: user) }
   let_it_be(:incident) { create(:incident, project: project) }
   let_it_be(:comment) { create(:note, project: project, noteable: incident, note: 'a' * 281) }
 
@@ -32,10 +32,6 @@
 
   let(:mutation_response) { graphql_mutation_response(:timeline_event_promote_from_note) }
 
-  before do
-    project.add_developer(user)
-  end
-
   it 'creates incident timeline event from the note', :aggregate_failures do
     post_graphql_mutation(mutation, current_user: user)
 
diff --git a/spec/requests/api/graphql/mutations/incident_management/timeline_event/update_spec.rb b/spec/requests/api/graphql/mutations/incident_management/timeline_event/update_spec.rb
index 163c689e399d59049f38ce65a634a47c08f18c83..25f6473aa6ac4292ed81c069c4ddeac1bc001d78 100644
--- a/spec/requests/api/graphql/mutations/incident_management/timeline_event/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/incident_management/timeline_event/update_spec.rb
@@ -6,7 +6,7 @@
   include GraphqlHelpers
 
   let_it_be(:user) { create(:user) }
-  let_it_be(:project) { create(:project) }
+  let_it_be(:project) { create(:project, developers: user) }
   let_it_be(:incident) { create(:incident, project: project) }
   let_it_be(:tag1) { create(:incident_management_timeline_event_tag, project: project, name: 'Tag 1') }
   let_it_be(:tag2) { create(:incident_management_timeline_event_tag, project: project, name: 'Tag 2') }
@@ -58,10 +58,6 @@
 
   let(:mutation_response) { graphql_mutation_response(:timeline_event_update) }
 
-  before do
-    project.add_developer(user)
-  end
-
   it 'updates the timeline event', :aggregate_failures do
     post_graphql_mutation(mutation, current_user: user)
 
diff --git a/spec/requests/api/graphql/mutations/releases/delete_spec.rb b/spec/requests/api/graphql/mutations/releases/delete_spec.rb
index bb398787cc661a2b9eb2bca44e603aed0e676792..aebf9004217874e0306db244617b2cfb71a8b842 100644
--- a/spec/requests/api/graphql/mutations/releases/delete_spec.rb
+++ b/spec/requests/api/graphql/mutations/releases/delete_spec.rb
@@ -11,7 +11,7 @@
   let_it_be(:reporter) { create(:user) }
   let_it_be(:developer) { create(:user) }
   let_it_be(:maintainer) { create(:user) }
-  let_it_be(:project) { create(:project, :public, :repository) }
+  let_it_be(:project) { create(:project, :public, :repository, guests: guest, reporters: reporter, developers: developer, maintainers: maintainer) }
   let_it_be(:tag_name) { 'v1.1.0' }
   let_it_be(:release) { create(:release, project: project, tag: tag_name) }
 
@@ -37,13 +37,6 @@
   let(:delete_release) { post_graphql_mutation(mutation, current_user: current_user) }
   let(:mutation_response) { graphql_mutation_response(mutation_name)&.with_indifferent_access }
 
-  before do
-    project.add_guest(guest)
-    project.add_reporter(reporter)
-    project.add_developer(developer)
-    project.add_maintainer(maintainer)
-  end
-
   shared_examples 'unauthorized or not found error' do
     it 'returns a top-level error with message' do
       delete_release
diff --git a/spec/requests/api/graphql/project/alert_management/alert/assignees_spec.rb b/spec/requests/api/graphql/project/alert_management/alert/assignees_spec.rb
index 0ca4ec0e3639db332fed85d913e301833179b634..ae96e8a29bd57ba8c597be42f5f4579f3cce8d26 100644
--- a/spec/requests/api/graphql/project/alert_management/alert/assignees_spec.rb
+++ b/spec/requests/api/graphql/project/alert_management/alert/assignees_spec.rb
@@ -6,7 +6,7 @@
   include GraphqlHelpers
 
   let_it_be(:project) { create(:project) }
-  let_it_be(:current_user) { create(:user) }
+  let_it_be(:current_user) { create(:user, developer_of: project) }
   let_it_be(:first_alert) { create(:alert_management_alert, project: project, assignees: [current_user]) }
   let_it_be(:second_alert) { create(:alert_management_alert, project: project) }
 
@@ -38,10 +38,6 @@
   let(:first_assignees) { assignees[first_alert.iid.to_s] }
   let(:second_assignees) { assignees[second_alert.iid.to_s] }
 
-  before do
-    project.add_developer(current_user)
-  end
-
   it 'returns the correct assignees' do
     post_graphql(query, current_user: current_user)
 
diff --git a/spec/requests/api/graphql/project/alert_management/alert/issue_spec.rb b/spec/requests/api/graphql/project/alert_management/alert/issue_spec.rb
index 3c9ec4fb60b91a7ea7b2ff0ba33753806b8ceaae..46fb8ef1d3e75e4f1f481b851d64b90b08a6097c 100644
--- a/spec/requests/api/graphql/project/alert_management/alert/issue_spec.rb
+++ b/spec/requests/api/graphql/project/alert_management/alert/issue_spec.rb
@@ -6,7 +6,7 @@
   include GraphqlHelpers
 
   let_it_be(:project) { create(:project) }
-  let_it_be(:current_user) { create(:user) }
+  let_it_be(:current_user) { create(:user, developer_of: project) }
 
   let(:payload) { {} }
   let(:query) { 'avg(metric) > 1.0' }
@@ -34,10 +34,6 @@
   let(:alerts) { graphql_data.dig('project', 'alertManagementAlerts', 'nodes') }
   let(:first_alert) { alerts.first }
 
-  before do
-    project.add_developer(current_user)
-  end
-
   context 'with gitlab alert' do
     before do
       create(:alert_management_alert, :with_incident, project: project, payload: payload)
diff --git a/spec/requests/api/graphql/project/alert_management/alert/notes_spec.rb b/spec/requests/api/graphql/project/alert_management/alert/notes_spec.rb
index c1ac0367853d659f179f69bbe572d65b4817db33..101f90dbb78e350c74bd2a7bf3df3f5231d3f166 100644
--- a/spec/requests/api/graphql/project/alert_management/alert/notes_spec.rb
+++ b/spec/requests/api/graphql/project/alert_management/alert/notes_spec.rb
@@ -6,7 +6,7 @@
   include GraphqlHelpers
 
   let_it_be(:project) { create(:project) }
-  let_it_be(:current_user) { create(:user) }
+  let_it_be(:current_user) { create(:user, developer_of: project) }
   let_it_be(:first_alert) { create(:alert_management_alert, project: project, assignees: [current_user]) }
   let_it_be(:second_alert) { create(:alert_management_alert, project: project) }
   let_it_be(:first_system_note) { create(:note_on_alert, :with_system_note_metadata, noteable: first_alert, project: project) }
@@ -42,10 +42,6 @@
   let(:first_notes_result) { notes_result[first_alert.iid.to_s] }
   let(:second_notes_result) { notes_result[second_alert.iid.to_s] }
 
-  before do
-    project.add_developer(current_user)
-  end
-
   it 'includes expected data' do
     post_graphql(query, current_user: current_user)
 
diff --git a/spec/requests/api/graphql/project/alert_management/alert/todos_spec.rb b/spec/requests/api/graphql/project/alert_management/alert/todos_spec.rb
index ad4361dfa50995498ba1ceb129d5bad76c75c841..f3ceba4051ff20f159b80af5918aadbf6d479fd2 100644
--- a/spec/requests/api/graphql/project/alert_management/alert/todos_spec.rb
+++ b/spec/requests/api/graphql/project/alert_management/alert/todos_spec.rb
@@ -6,7 +6,7 @@
   include GraphqlHelpers
 
   let_it_be(:project) { create(:project) }
-  let_it_be(:current_user) { create(:user) }
+  let_it_be(:current_user) { create(:user, developer_of: project) }
   let_it_be(:alert) { create(:alert_management_alert, project: project) }
   let_it_be(:other_alert) { create(:alert_management_alert, project: project) }
   let_it_be(:todo) { create(:todo, :pending, target: alert, user: current_user, project: project) }
@@ -38,10 +38,6 @@
   let(:gql_alert_todo) { gql_todos[alert.iid.to_s].first }
   let(:gql_other_alert_todo) { gql_todos[other_alert.iid.to_s].first }
 
-  before do
-    project.add_developer(current_user)
-  end
-
   it 'includes the correct metrics dashboard url' do
     post_graphql(graphql_query, current_user: current_user)
 
diff --git a/spec/requests/api/graphql/project/issue_spec.rb b/spec/requests/api/graphql/project/issue_spec.rb
index 8d21a9f0394b6e53f146701625db7fa1e3adb3cd..99a077e652063221773cb4957e25d764819f204f 100644
--- a/spec/requests/api/graphql/project/issue_spec.rb
+++ b/spec/requests/api/graphql/project/issue_spec.rb
@@ -8,7 +8,7 @@
   let_it_be(:project) { create(:project) }
   let_it_be(:issue) { create(:issue, project: project) }
   let_it_be(:issue_b) { create(:issue, project: project) }
-  let_it_be(:developer) { create(:user) }
+  let_it_be(:developer) { create(:user, developer_of: project) }
   let(:current_user) { developer }
 
   let_it_be(:project_params) { { 'fullPath' => project.full_path } }
@@ -80,10 +80,6 @@
     end
   end
 
-  before do
-    project.add_developer(developer)
-  end
-
   let(:post_query) { post_graphql(query, current_user: current_user) }
 
   describe '.designCollection' do
diff --git a/spec/requests/api/graphql/todo_query_spec.rb b/spec/requests/api/graphql/todo_query_spec.rb
index b8ce065dbbb5061737f0b9f5b2d3f30f4c8aa0e5..83b7af7dfd43df198bd5931205417d34698040b9 100644
--- a/spec/requests/api/graphql/todo_query_spec.rb
+++ b/spec/requests/api/graphql/todo_query_spec.rb
@@ -9,16 +9,12 @@
   let_it_be(:project) { create(:project) }
   let_it_be(:issue) { create(:issue, project: project) }
 
-  let_it_be(:todo_owner) { create(:user) }
+  let_it_be(:todo_owner) { create(:user, developer_of: project) }
 
   let_it_be(:todo) { create(:todo, user: todo_owner, target: issue) }
 
   let(:todo_subject) { todo }
 
-  before do
-    project.add_developer(todo_owner)
-  end
-
   let(:fields) do
     <<~GRAPHQL
       id
diff --git a/spec/requests/api/group_boards_spec.rb b/spec/requests/api/group_boards_spec.rb
index acc30b2c13736bfa436cc37c2a38b7af4573af7e..feed66979f17939704f6e9a3c8748dbb9f3261d0 100644
--- a/spec/requests/api/group_boards_spec.rb
+++ b/spec/requests/api/group_boards_spec.rb
@@ -7,11 +7,7 @@
   let_it_be(:non_member) { create(:user) }
   let_it_be(:guest) { create(:user) }
   let_it_be(:admin) { create(:user, :admin) }
-  let_it_be(:board_parent) { create(:group, :public) }
-
-  before do
-    board_parent.add_owner(user)
-  end
+  let_it_be(:board_parent) { create(:group, :public, owners: user) }
 
   let_it_be(:project) { create(:project, :public, namespace: board_parent) }
 
diff --git a/spec/requests/api/issue_links_spec.rb b/spec/requests/api/issue_links_spec.rb
index f3b905459725f509e27bec21cf5f4e1602862fa0..6bedc84719e6f0c11ee4564ef6dda722817efc7c 100644
--- a/spec/requests/api/issue_links_spec.rb
+++ b/spec/requests/api/issue_links_spec.rb
@@ -4,13 +4,9 @@
 
 RSpec.describe API::IssueLinks, feature_category: :team_planning do
   let_it_be(:user) { create(:user) }
-  let_it_be(:project) { create(:project) }
+  let_it_be(:project) { create(:project, guests: user) }
   let_it_be(:issue) { create(:issue, project: project) }
 
-  before do
-    project.add_guest(user)
-  end
-
   describe 'GET /links' do
     def perform_request(user = nil, params = {})
       get api("/projects/#{project.id}/issues/#{issue.iid}/links", user), params: params
diff --git a/spec/requests/api/maven_packages_spec.rb b/spec/requests/api/maven_packages_spec.rb
index 5e432cfca74411745d51591b8a3bb5f536e0c701..b67fd9d6d634c358b06783f232b86c43f0d8fb94 100644
--- a/spec/requests/api/maven_packages_spec.rb
+++ b/spec/requests/api/maven_packages_spec.rb
@@ -11,7 +11,7 @@
   let_it_be_with_refind(:package_settings) { create(:namespace_package_setting, :group) }
   let_it_be_with_refind(:group) { package_settings.namespace }
   let_it_be(:user) { create(:user) }
-  let_it_be(:project, reload: true) { create(:project, :public, namespace: group) }
+  let_it_be(:project, reload: true) { create(:project, :public, namespace: group, developers: user) }
   let_it_be(:package, reload: true) { create(:maven_package, project: project, name: project.full_path) }
   let_it_be(:maven_metadatum, reload: true) { package.maven_metadatum }
   let_it_be(:package_file) { package.package_files.with_file_name_like('%.xml').first }
@@ -39,10 +39,6 @@
   let(:version) { '1.0-SNAPSHOT' }
   let(:param_path) { "#{package_name}/#{version}" }
 
-  before do
-    project.add_developer(user)
-  end
-
   shared_examples 'handling groups and subgroups for' do |shared_example_name, shared_example_args = {}, visibilities: { public: :redirect }|
     context 'within a group' do
       visibilities.each do |visibility, not_found_response|
diff --git a/spec/requests/api/pages/pages_spec.rb b/spec/requests/api/pages/pages_spec.rb
index 74dd1ed4f2b19cdd4a19a7426203a7443ca6c4cf..e701238701ddabcc8fbd1577d7293abc3a26fd6e 100644
--- a/spec/requests/api/pages/pages_spec.rb
+++ b/spec/requests/api/pages/pages_spec.rb
@@ -5,11 +5,7 @@
 RSpec.describe API::Pages, feature_category: :pages do
   let_it_be_with_reload(:project) { create(:project, path: 'my.project', pages_https_only: false) }
   let_it_be(:admin) { create(:admin) }
-  let_it_be(:user) { create(:user) }
-
-  before do
-    project.add_maintainer(user)
-  end
+  let_it_be(:user) { create(:user, maintainer_of: project) }
 
   describe 'DELETE /projects/:id/pages' do
     let(:path) { "/projects/#{project.id}/pages" }
diff --git a/spec/requests/api/project_clusters_spec.rb b/spec/requests/api/project_clusters_spec.rb
index a288adbc78a112e1882ebdb544edec4fbe5245dc..214c4c8db0bc06881b47f804194c2aa58bfbcc9d 100644
--- a/spec/requests/api/project_clusters_spec.rb
+++ b/spec/requests/api/project_clusters_spec.rb
@@ -8,13 +8,7 @@
   let_it_be(:maintainer_user) { create(:user) }
   let_it_be(:developer_user) { create(:user) }
   let_it_be(:reporter_user) { create(:user) }
-  let_it_be(:project) { create(:project) }
-
-  before do
-    project.add_maintainer(maintainer_user)
-    project.add_developer(developer_user)
-    project.add_reporter(reporter_user)
-  end
+  let_it_be(:project) { create(:project, maintainers: maintainer_user, developers: developer_user, reporters: reporter_user) }
 
   describe 'GET /projects/:id/clusters' do
     let_it_be(:extra_cluster) { create(:cluster, :provided_by_gcp, :project) }
diff --git a/spec/requests/api/project_statistics_spec.rb b/spec/requests/api/project_statistics_spec.rb
index 39ead8cc573a59832a3b683a446aa6c536329a0f..0d97f46e3ad33b5bc6d0b210928fd238a1581afb 100644
--- a/spec/requests/api/project_statistics_spec.rb
+++ b/spec/requests/api/project_statistics_spec.rb
@@ -4,11 +4,7 @@
 
 RSpec.describe API::ProjectStatistics, feature_category: :source_code_management do
   let_it_be(:reporter) { create(:user) }
-  let_it_be(:public_project) { create(:project, :public) }
-
-  before do
-    public_project.add_reporter(reporter)
-  end
+  let_it_be(:public_project) { create(:project, :public, reporters: reporter) }
 
   describe 'GET /projects/:id/statistics' do
     let_it_be(:fetch_statistics1) { create(:project_daily_statistic, project: public_project, fetch_count: 30, date: 29.days.ago) }
diff --git a/spec/requests/api/resource_label_events_spec.rb b/spec/requests/api/resource_label_events_spec.rb
index 1adffea17b7419cf6976b61303b74276db3311e0..fa232e7e6390f80b0d25cd87e13a3f3b683e96b1 100644
--- a/spec/requests/api/resource_label_events_spec.rb
+++ b/spec/requests/api/resource_label_events_spec.rb
@@ -4,13 +4,9 @@
 
 RSpec.describe API::ResourceLabelEvents, feature_category: :team_planning do
   let_it_be(:user) { create(:user) }
-  let_it_be(:project, reload: true) { create(:project, :public, namespace: user.namespace) }
+  let_it_be(:project, reload: true) { create(:project, :public, namespace: user.namespace, developers: user) }
   let_it_be(:label) { create(:label, project: project) }
 
-  before do
-    project.add_developer(user)
-  end
-
   context 'when eventable is an Issue' do
     it_behaves_like 'resource_label_events API', 'projects', 'issues', 'iid' do
       let(:parent) { project }
diff --git a/spec/requests/projects/aws/configuration_controller_spec.rb b/spec/requests/projects/aws/configuration_controller_spec.rb
index af9460eb76c3b8af088d5828abf52f265baed0a6..2c1f0f4db688e2a62211c16e8d00305bc19d2d19 100644
--- a/spec/requests/projects/aws/configuration_controller_spec.rb
+++ b/spec/requests/projects/aws/configuration_controller_spec.rb
@@ -6,19 +6,13 @@
   let_it_be(:project) { create(:project, :public) }
   let_it_be(:url) { project_aws_configuration_path(project) }
 
-  let_it_be(:user_guest) { create(:user) }
-  let_it_be(:user_developer) { create(:user) }
-  let_it_be(:user_maintainer) { create(:user) }
+  let_it_be(:user_guest) { create(:user, guest_of: project) }
+  let_it_be(:user_developer) { create(:user, developer_of: project) }
+  let_it_be(:user_maintainer) { create(:user, maintainer_of: project) }
 
   let_it_be(:unauthorized_members) { [user_guest, user_developer] }
   let_it_be(:authorized_members) { [user_maintainer] }
 
-  before do
-    project.add_guest(user_guest)
-    project.add_developer(user_developer)
-    project.add_maintainer(user_maintainer)
-  end
-
   context 'when accessed by unauthorized members' do
     it 'returns not found on GET request' do
       unauthorized_members.each do |unauthorized_member|
diff --git a/spec/requests/projects/google_cloud/configuration_controller_spec.rb b/spec/requests/projects/google_cloud/configuration_controller_spec.rb
index b807ff7930e60af402250961935ab1bd419b8da7..ab0cd6109f5a058cec28b07bddb27dfb356c677c 100644
--- a/spec/requests/projects/google_cloud/configuration_controller_spec.rb
+++ b/spec/requests/projects/google_cloud/configuration_controller_spec.rb
@@ -6,19 +6,13 @@
   let_it_be(:project) { create(:project, :public) }
   let_it_be(:url) { project_google_cloud_configuration_path(project) }
 
-  let_it_be(:user_guest) { create(:user) }
-  let_it_be(:user_developer) { create(:user) }
-  let_it_be(:user_maintainer) { create(:user) }
+  let_it_be(:user_guest) { create(:user, guest_of: project) }
+  let_it_be(:user_developer) { create(:user, developer_of: project) }
+  let_it_be(:user_maintainer) { create(:user, maintainer_of: project) }
 
   let_it_be(:unauthorized_members) { [user_guest, user_developer] }
   let_it_be(:authorized_members) { [user_maintainer] }
 
-  before do
-    project.add_guest(user_guest)
-    project.add_developer(user_developer)
-    project.add_maintainer(user_maintainer)
-  end
-
   context 'when accessed by unauthorized members' do
     it 'returns not found on GET request' do
       unauthorized_members.each do |unauthorized_member|
diff --git a/spec/requests/projects/google_cloud/deployments_controller_spec.rb b/spec/requests/projects/google_cloud/deployments_controller_spec.rb
index 1a6482477ef66b559906ecbf08876cbdc5523924..220cca9c884ca2d3de891b12be9fbcbd71b80ecd 100644
--- a/spec/requests/projects/google_cloud/deployments_controller_spec.rb
+++ b/spec/requests/projects/google_cloud/deployments_controller_spec.rb
@@ -6,21 +6,15 @@
   let_it_be(:project) { create(:project, :public, :repository) }
   let_it_be(:repository) { project.repository }
 
-  let_it_be(:user_guest) { create(:user) }
-  let_it_be(:user_developer) { create(:user) }
-  let_it_be(:user_maintainer) { create(:user) }
+  let_it_be(:user_guest) { create(:user, guest_of: project) }
+  let_it_be(:user_developer) { create(:user, developer_of: project) }
+  let_it_be(:user_maintainer) { create(:user, maintainer_of: project) }
 
   let_it_be(:unauthorized_members) { [user_guest, user_developer] }
   let_it_be(:authorized_members) { [user_maintainer] }
 
   let_it_be(:urls_list) { %W[#{project_google_cloud_deployments_cloud_run_path(project)} #{project_google_cloud_deployments_cloud_storage_path(project)}] }
 
-  before do
-    project.add_guest(user_guest)
-    project.add_developer(user_developer)
-    project.add_maintainer(user_maintainer)
-  end
-
   describe "Routes must be restricted behind Google OAuth2", :snowplow do
     context 'when a public request is made' do
       it 'returns not found on GET request' do
diff --git a/spec/requests/projects/releases_controller_spec.rb b/spec/requests/projects/releases_controller_spec.rb
index 42fd55b5a436930f506327319570b43c8ee0bd77..872f2849c5e5938c25f1081df2895b7e74ed9fca 100644
--- a/spec/requests/projects/releases_controller_spec.rb
+++ b/spec/requests/projects/releases_controller_spec.rb
@@ -4,11 +4,7 @@
 
 RSpec.describe 'Projects::ReleasesController', feature_category: :release_orchestration do
   let_it_be(:project) { create(:project, :repository) }
-  let_it_be(:user) { create(:user) }
-
-  before do
-    project.add_developer(user)
-  end
+  let_it_be(:user) { create(:user, developer_of: project) }
 
   # Added as a request spec because of https://gitlab.com/gitlab-org/gitlab/-/issues/232386
   describe 'GET #downloads' do