The N+1 query issue was introduced when the :project_id option was added to the Account serializer, because it does a query per Account being displayed. Avoid this issue by not using serializers for project user page. Serializers only make sense as a separate object if you want to share the same type of serialization in multiple places, and you actually need to serialize. Multiple API routes that need the same type of serialization. For other places, it is both simpler and faster to underlying objects directly instead of using a serializer. To get the subject tags for the users, extract a SubjectTag.subject_id_map_for_project_and_accounts method, and use that for the project user page as well as the form submission handler for updating policies for users. As they are no longer used, remove the Account#subject_tags association and the ProjectInvitation serializer.
57 lines
1.6 KiB
Ruby
57 lines
1.6 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require_relative "../model"
|
|
|
|
class SubjectTag < Sequel::Model
|
|
include ResourceMethods
|
|
include AccessControlModelTag
|
|
|
|
module Cleanup
|
|
def before_destroy
|
|
AccessControlEntry.where(subject_id: id).destroy
|
|
DB[:applied_subject_tag].where(subject_id: id).delete
|
|
super
|
|
end
|
|
end
|
|
|
|
def self.subject_id_map_for_project_and_accounts(project_id, account_ids)
|
|
DB[:applied_subject_tag]
|
|
.join(:subject_tag, id: :tag_id)
|
|
.where(project_id:, subject_id: account_ids)
|
|
.order(:subject_id, :name)
|
|
.select_hash_groups(:subject_id, :name)
|
|
end
|
|
|
|
def self.options_for_project(project)
|
|
{
|
|
"Tag" => project.subject_tags.reject { _1.name == "Admin" },
|
|
"Account" => project.accounts
|
|
}
|
|
end
|
|
|
|
def self.valid_member?(project_id, subject)
|
|
case subject
|
|
when SubjectTag
|
|
subject.project_id == project_id
|
|
when Account
|
|
!AccessTag.where(project_id:, hyper_tag_id: subject.id).empty?
|
|
when ApiKey
|
|
subject.owner_table == "accounts" &&
|
|
!AccessTag.where(project_id:, hyper_tag_id: subject.owner_id).empty?
|
|
end
|
|
end
|
|
end
|
|
|
|
# Table: subject_tag
|
|
# Columns:
|
|
# id | uuid | PRIMARY KEY
|
|
# project_id | uuid | NOT NULL
|
|
# name | text | NOT NULL
|
|
# Indexes:
|
|
# subject_tag_pkey | PRIMARY KEY btree (id)
|
|
# subject_tag_project_id_name_index | UNIQUE btree (project_id, name)
|
|
# Foreign key constraints:
|
|
# subject_tag_project_id_fkey | (project_id) REFERENCES project(id)
|
|
# Referenced By:
|
|
# applied_subject_tag | applied_subject_tag_tag_id_fkey | (tag_id) REFERENCES subject_tag(id)
|