Files
ubicloud/model/subject_tag.rb
Jeremy Evans 4ed5dbb8ba Avoid N+1 query issue when displaying project user page
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.
2025-01-09 09:55:55 -08:00

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)