mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-25 14:36:41 +08:00
Merge pull request #4183 from okriuchykhin/ok_SCI_6917
Convert team_repository to polymorphic relation [SCI-6917]
This commit is contained in:
commit
e23475fbbe
10 changed files with 117 additions and 86 deletions
|
@ -20,8 +20,8 @@ class Repository < RepositoryBase
|
|||
class_name: 'User',
|
||||
inverse_of: :restored_repositories,
|
||||
optional: true
|
||||
has_many :team_repositories, inverse_of: :repository, dependent: :destroy
|
||||
has_many :teams_shared_with, through: :team_repositories, source: :team
|
||||
has_many :team_shared_objects, as: :shared_object, dependent: :destroy
|
||||
has_many :teams_shared_with, through: :team_shared_objects, source: :team
|
||||
has_many :repository_snapshots,
|
||||
class_name: 'RepositorySnapshot',
|
||||
foreign_key: :parent_id,
|
||||
|
|
|
@ -48,7 +48,12 @@ class Team < ApplicationRecord
|
|||
has_many :reports, inverse_of: :team, dependent: :destroy
|
||||
has_many :activities, inverse_of: :team, dependent: :destroy
|
||||
has_many :assets, inverse_of: :team, dependent: :destroy
|
||||
has_many :team_repositories, inverse_of: :team, dependent: :destroy
|
||||
has_many :team_shared_objects, inverse_of: :team, dependent: :destroy
|
||||
has_many :team_shared_repositories,
|
||||
-> { where(shared_object_type: 'RepositoryBase') },
|
||||
class_name: 'TeamSharedObject',
|
||||
inverse_of: :team
|
||||
has_many :shared_repositories, through: :team_shared_objects, source: :shared_object, source_type: 'RepositoryBase'
|
||||
has_many :repository_sharing_user_assignments,
|
||||
(lambda do |team|
|
||||
joins(
|
||||
|
@ -59,7 +64,7 @@ class Team < ApplicationRecord
|
|||
.where.not('user_assignments.team_id = repositories.team_id')
|
||||
end),
|
||||
class_name: 'UserAssignment'
|
||||
has_many :shared_repositories,
|
||||
has_many :shared_by_user_repositories,
|
||||
through: :repository_sharing_user_assignments,
|
||||
source: :assignable,
|
||||
source_type: 'RepositoryBase'
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class TeamRepository < ApplicationRecord
|
||||
enum permission_level: Extends::SHARED_INVENTORIES_PERMISSION_LEVELS.except(:not_shared)
|
||||
|
||||
belongs_to :team
|
||||
belongs_to :repository
|
||||
|
||||
before_destroy :unassign_unshared_items
|
||||
|
||||
validates :permission_level, presence: true
|
||||
validates :repository, uniqueness: { scope: :team_id }
|
||||
validate :team_cannot_be_the_same
|
||||
|
||||
private
|
||||
|
||||
def team_cannot_be_the_same
|
||||
errors.add(:team_id, :same_team) if repository&.team_id == team_id
|
||||
end
|
||||
|
||||
def unassign_unshared_items
|
||||
return if repository.shared_read? || repository.shared_write?
|
||||
|
||||
MyModuleRepositoryRow.joins(my_module: { experiment: { project: :team } })
|
||||
.joins(repository_row: :repository)
|
||||
.where(my_module: { experiment: { projects: { team: team } } })
|
||||
.where(repository_rows: { repository: repository })
|
||||
.destroy_all
|
||||
end
|
||||
end
|
35
app/models/team_shared_object.rb
Normal file
35
app/models/team_shared_object.rb
Normal file
|
@ -0,0 +1,35 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class TeamSharedObject < ApplicationRecord
|
||||
enum permission_level: Extends::SHARED_OBJECTS_PERMISSION_LEVELS
|
||||
|
||||
belongs_to :team
|
||||
belongs_to :shared_object, polymorphic: true
|
||||
belongs_to :shared_repository,
|
||||
(lambda do |team_shared_object|
|
||||
team_shared_object.shared_object_type == 'RepositoryBAse' ? self : none
|
||||
end),
|
||||
optional: true, foreign_key: :shared_object_id, inverse_of: :team_shared_object
|
||||
|
||||
before_destroy :unassign_unshared_items, if: -> { shared_object.is_a?(Repository) }
|
||||
|
||||
validates :permission_level, presence: true
|
||||
validates :shared_object, uniqueness: { scope: :team_id }
|
||||
validate :team_cannot_be_the_same
|
||||
|
||||
private
|
||||
|
||||
def team_cannot_be_the_same
|
||||
errors.add(:team_id, :same_team) if shared_object.team.id == team_id
|
||||
end
|
||||
|
||||
def unassign_unshared_items
|
||||
return if repository.shared_read? || repository.shared_write?
|
||||
|
||||
MyModuleRepositoryRow.joins(my_module: { experiment: { project: :team } })
|
||||
.joins(repository_row: :repository)
|
||||
.where(my_module: { experiment: { projects: { team: team } } })
|
||||
.where(repository_rows: { repository: repository })
|
||||
.destroy_all
|
||||
end
|
||||
end
|
|
@ -18,12 +18,15 @@ class UserAssignment < ApplicationRecord
|
|||
private
|
||||
|
||||
def assign_shared_inventories
|
||||
assignable.repository_sharing_user_assignments
|
||||
.select('DISTINCT assignable_id, user_assignments.*')
|
||||
.find_each do |repository_sharing_user_assignment|
|
||||
new_user_assignment = repository_sharing_user_assignment.dup
|
||||
new_user_assignment.assign_attributes(user: user)
|
||||
new_user_assignment.save!
|
||||
viewer_role = UserRole.find_by(name: UserRole.public_send('viewer_role').name)
|
||||
normal_user_role = UserRole.find_by(name: UserRole.public_send('normal_user_role').name)
|
||||
|
||||
assignable.team_shared_repositories.find_each do |team_shared_repository|
|
||||
assignable.repository_sharing_user_assignments.create!(
|
||||
user: user,
|
||||
user_role: team_shared_repository.shared_write? ? normal_user_role : viewer_role,
|
||||
assignable: team_shared_repository.shared_object
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -409,6 +409,11 @@ class Extends
|
|||
shared_write: 2
|
||||
}.freeze
|
||||
|
||||
SHARED_OBJECTS_PERMISSION_LEVELS = {
|
||||
shared_read: 1,
|
||||
shared_write: 2
|
||||
}.freeze
|
||||
|
||||
SHARED_INVENTORIES_PL_MAPPINGS = {
|
||||
shared_read: 'view-only',
|
||||
shared_write: 'edit'
|
||||
|
|
|
@ -1,6 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class MigrateSharedRepositoriesToUserAssignments < ActiveRecord::Migration[6.1]
|
||||
class TeamRepository < ApplicationRecord
|
||||
self.table_name = 'team_repositories'
|
||||
enum permission_level: { not_shared: 0, shared_read: 1, shared_write: 2 }
|
||||
belongs_to :team
|
||||
belongs_to :repository
|
||||
end
|
||||
|
||||
def up
|
||||
viewer_role = UserRole.find_by(name: UserRole.public_send('viewer_role').name)
|
||||
normal_user_role = UserRole.find_by(name: UserRole.public_send('normal_user_role').name)
|
||||
|
@ -23,9 +30,34 @@ class MigrateSharedRepositoriesToUserAssignments < ActiveRecord::Migration[6.1]
|
|||
UserAssignment.import(user_assignments)
|
||||
end
|
||||
end
|
||||
|
||||
remove_index :repositories, :permission_level
|
||||
remove_index :team_repositories, :permission_level
|
||||
remove_index :team_repositories, :repository_id
|
||||
remove_index :team_repositories, %i(team_id repository_id), unique: true
|
||||
rename_table :team_repositories, :team_shared_objects
|
||||
rename_column :team_shared_objects, :repository_id, :shared_object_id
|
||||
add_column :team_shared_objects, :shared_object_type, :string
|
||||
execute("UPDATE team_shared_objects SET shared_object_type = 'RepositoryBase'")
|
||||
add_index :team_shared_objects,
|
||||
%i(shared_object_type shared_object_id team_id),
|
||||
name: 'index_team_shared_objects_on_shared_type_and_id_and_team_id',
|
||||
unique: true
|
||||
end
|
||||
|
||||
def down
|
||||
remove_index :team_shared_objects,
|
||||
%i(shared_object_type shared_object_id team_id),
|
||||
name: 'index_team_shared_objects_on_shared_type_and_id_and_team_id',
|
||||
unique: true
|
||||
remove_column :team_shared_objects, :shared_object_type
|
||||
rename_column :team_shared_objects, :shared_object_id, :repository_id
|
||||
rename_table :team_shared_objects, :team_repositories
|
||||
add_index :team_repositories, %i(team_id repository_id), unique: true
|
||||
add_index :team_repositories, :repository_id
|
||||
add_index :team_repositories, :permission_level
|
||||
add_index :repositories, :permission_level
|
||||
|
||||
UserAssignment.joins("INNER JOIN repositories ON user_assignments.assignable_id = repositories.id "\
|
||||
"AND user_assignments.assignable_type = 'RepositoryBase' "\
|
||||
"AND user_assignments.team_id != repositories.team_id")
|
||||
|
|
|
@ -2669,24 +2669,25 @@ ALTER SEQUENCE public.tags_id_seq OWNED BY public.tags.id;
|
|||
|
||||
|
||||
--
|
||||
-- Name: team_repositories; Type: TABLE; Schema: public; Owner: -
|
||||
-- Name: team_shared_objects; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.team_repositories (
|
||||
CREATE TABLE public.team_shared_objects (
|
||||
id bigint NOT NULL,
|
||||
team_id bigint,
|
||||
repository_id bigint,
|
||||
shared_object_id bigint,
|
||||
permission_level integer DEFAULT 0 NOT NULL,
|
||||
created_at timestamp without time zone NOT NULL,
|
||||
updated_at timestamp without time zone NOT NULL
|
||||
updated_at timestamp without time zone NOT NULL,
|
||||
shared_object_type character varying
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: team_repositories_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
-- Name: team_shared_objects_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.team_repositories_id_seq
|
||||
CREATE SEQUENCE public.team_shared_objects_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
|
@ -2695,10 +2696,10 @@ CREATE SEQUENCE public.team_repositories_id_seq
|
|||
|
||||
|
||||
--
|
||||
-- Name: team_repositories_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
-- Name: team_shared_objects_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.team_repositories_id_seq OWNED BY public.team_repositories.id;
|
||||
ALTER SEQUENCE public.team_shared_objects_id_seq OWNED BY public.team_shared_objects.id;
|
||||
|
||||
|
||||
--
|
||||
|
@ -3850,10 +3851,10 @@ ALTER TABLE ONLY public.tags ALTER COLUMN id SET DEFAULT nextval('public.tags_id
|
|||
|
||||
|
||||
--
|
||||
-- Name: team_repositories id; Type: DEFAULT; Schema: public; Owner: -
|
||||
-- Name: team_shared_objects id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.team_repositories ALTER COLUMN id SET DEFAULT nextval('public.team_repositories_id_seq'::regclass);
|
||||
ALTER TABLE ONLY public.team_shared_objects ALTER COLUMN id SET DEFAULT nextval('public.team_shared_objects_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
|
@ -4574,11 +4575,11 @@ ALTER TABLE ONLY public.tags
|
|||
|
||||
|
||||
--
|
||||
-- Name: team_repositories team_repositories_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
-- Name: team_shared_objects team_shared_objects_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.team_repositories
|
||||
ADD CONSTRAINT team_repositories_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE ONLY public.team_shared_objects
|
||||
ADD CONSTRAINT team_shared_objects_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
|
@ -5657,13 +5658,6 @@ CREATE INDEX index_repositories_on_discarded_at ON public.repositories USING btr
|
|||
CREATE INDEX index_repositories_on_my_module_id ON public.repositories USING btree (my_module_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_repositories_on_permission_level; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_repositories_on_permission_level ON public.repositories USING btree (permission_level);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_repositories_on_restored_by_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -6393,31 +6387,17 @@ CREATE INDEX index_tags_on_project_id ON public.tags USING btree (project_id);
|
|||
|
||||
|
||||
--
|
||||
-- Name: index_team_repositories_on_permission_level; Type: INDEX; Schema: public; Owner: -
|
||||
-- Name: index_team_shared_objects_on_shared_type_and_id_and_team_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_team_repositories_on_permission_level ON public.team_repositories USING btree (permission_level);
|
||||
CREATE UNIQUE INDEX index_team_shared_objects_on_shared_type_and_id_and_team_id ON public.team_shared_objects USING btree (shared_object_type, shared_object_id, team_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_team_repositories_on_repository_id; Type: INDEX; Schema: public; Owner: -
|
||||
-- Name: index_team_shared_objects_on_team_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_team_repositories_on_repository_id ON public.team_repositories USING btree (repository_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_team_repositories_on_team_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_team_repositories_on_team_id ON public.team_repositories USING btree (team_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_team_repositories_on_team_id_and_repository_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE UNIQUE INDEX index_team_repositories_on_team_id_and_repository_id ON public.team_repositories USING btree (team_id, repository_id);
|
||||
CREATE INDEX index_team_shared_objects_on_team_id ON public.team_shared_objects USING btree (team_id);
|
||||
|
||||
|
||||
--
|
||||
|
@ -6868,11 +6848,11 @@ ALTER TABLE ONLY public.tables
|
|||
|
||||
|
||||
--
|
||||
-- Name: team_repositories fk_rails_15daa6a6bf; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
-- Name: team_shared_objects fk_rails_15daa6a6bf; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.team_repositories
|
||||
ADD CONSTRAINT fk_rails_15daa6a6bf FOREIGN KEY (repository_id) REFERENCES public.repositories(id);
|
||||
ALTER TABLE ONLY public.team_shared_objects
|
||||
ADD CONSTRAINT fk_rails_15daa6a6bf FOREIGN KEY (shared_object_id) REFERENCES public.repositories(id);
|
||||
|
||||
|
||||
--
|
||||
|
@ -8124,10 +8104,10 @@ ALTER TABLE ONLY public.tags
|
|||
|
||||
|
||||
--
|
||||
-- Name: team_repositories fk_rails_f99472b670; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
-- Name: team_shared_objects fk_rails_f99472b670; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.team_repositories
|
||||
ALTER TABLE ONLY public.team_shared_objects
|
||||
ADD CONSTRAINT fk_rails_f99472b670 FOREIGN KEY (team_id) REFERENCES public.teams(id);
|
||||
|
||||
|
||||
|
@ -8388,6 +8368,7 @@ INSERT INTO "schema_migrations" (version) VALUES
|
|||
('20220325101011'),
|
||||
('20220328164215'),
|
||||
('20220516111152'),
|
||||
('20220621153016');
|
||||
('20220621153016'),
|
||||
('20220624091046');
|
||||
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ describe Repository, type: :model do
|
|||
it { should have_many :repository_rows }
|
||||
it { should have_many :repository_table_states }
|
||||
it { should have_many :report_elements }
|
||||
it { should have_many(:team_repositories).dependent(:destroy) }
|
||||
it { should have_many(:team_shared_objects).dependent(:destroy) }
|
||||
it { should have_many(:teams_shared_with) }
|
||||
end
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ describe Team, type: :model do
|
|||
it { should have_many :tiny_mce_assets }
|
||||
it { should have_many :repositories }
|
||||
it { should have_many :reports }
|
||||
it { should have_many(:team_repositories).dependent(:destroy) }
|
||||
it { should have_many(:team_shared_objects).dependent(:destroy) }
|
||||
it { should have_many :shared_repositories }
|
||||
end
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue