Skip to content

Commit

Permalink
fix slow query for product users
Browse files Browse the repository at this point in the history
  • Loading branch information
ezekg committed Mar 18, 2024
1 parent 869aef9 commit 9c440e4
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ class UsersController < Api::V1::BaseController
authorize :product

def index
users = apply_pagination(authorized_scope(apply_scopes(product.users)).preload(:role))
users = apply_pagination(authorized_scope(apply_scopes(product_users)).preload(:role))
authorize! users,
with: Products::UserPolicy

render jsonapi: users
end

def show
user = FindByAliasService.call(product.users, id: params[:id], aliases: :email)
user = FindByAliasService.call(product_users, id: params[:id], aliases: :email)
authorize! user,
with: Products::UserPolicy

Expand All @@ -31,6 +31,10 @@ def show

attr_reader :product

# FIXME(ezekg) Uses a more optimized query for large accounts. This should
# be considered a bug in union_of.
def product_users = current_account.users.for_product(product)

def set_product
scoped_products = authorized_scope(current_account.products)

Expand Down
22 changes: 21 additions & 1 deletion app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,27 @@ def owned = where(owner: proxy_association.owner)
end
}

scope :for_product, -> id { joins(:licenses).where(licenses: { product_id: id }).distinct }
scope :for_product, -> id {
license_users = LicenseUser.arel_table
licenses = License.arel_table
users = User.arel_table

# More optimized union query for this particular association
left_outer_joins(:license_users)
.joins(
Arel::Nodes::InnerJoin.new(
licenses,
Arel::Nodes::On.new(
licenses[:user_id].eq(users[:id]).or(
licenses[:id].eq(license_users[:license_id]),
)
),
),
)
.where(
licenses: { product_id: id },
)
}
scope :for_license, -> id { joins(:licenses).where(licenses: { id: id }).distinct }
scope :for_group_owner, -> id { joins(group: :owners).where(group: { group_owners: { user_id: id } }).distinct }
scope :for_user, -> id {
Expand Down

0 comments on commit 9c440e4

Please sign in to comment.