Skip to content

Commit 9c440e4

Browse files
committed
fix slow query for product users
1 parent 869aef9 commit 9c440e4

File tree

2 files changed

+27
-3
lines changed

2 files changed

+27
-3
lines changed

app/controllers/api/v1/products/relationships/users_controller.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ class UsersController < Api::V1::BaseController
1212
authorize :product
1313

1414
def index
15-
users = apply_pagination(authorized_scope(apply_scopes(product.users)).preload(:role))
15+
users = apply_pagination(authorized_scope(apply_scopes(product_users)).preload(:role))
1616
authorize! users,
1717
with: Products::UserPolicy
1818

1919
render jsonapi: users
2020
end
2121

2222
def show
23-
user = FindByAliasService.call(product.users, id: params[:id], aliases: :email)
23+
user = FindByAliasService.call(product_users, id: params[:id], aliases: :email)
2424
authorize! user,
2525
with: Products::UserPolicy
2626

@@ -31,6 +31,10 @@ def show
3131

3232
attr_reader :product
3333

34+
# FIXME(ezekg) Uses a more optimized query for large accounts. This should
35+
# be considered a bug in union_of.
36+
def product_users = current_account.users.for_product(product)
37+
3438
def set_product
3539
scoped_products = authorized_scope(current_account.products)
3640

app/models/user.rb

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,27 @@ def owned = where(owner: proxy_association.owner)
309309
end
310310
}
311311

312-
scope :for_product, -> id { joins(:licenses).where(licenses: { product_id: id }).distinct }
312+
scope :for_product, -> id {
313+
license_users = LicenseUser.arel_table
314+
licenses = License.arel_table
315+
users = User.arel_table
316+
317+
# More optimized union query for this particular association
318+
left_outer_joins(:license_users)
319+
.joins(
320+
Arel::Nodes::InnerJoin.new(
321+
licenses,
322+
Arel::Nodes::On.new(
323+
licenses[:user_id].eq(users[:id]).or(
324+
licenses[:id].eq(license_users[:license_id]),
325+
)
326+
),
327+
),
328+
)
329+
.where(
330+
licenses: { product_id: id },
331+
)
332+
}
313333
scope :for_license, -> id { joins(:licenses).where(licenses: { id: id }).distinct }
314334
scope :for_group_owner, -> id { joins(group: :owners).where(group: { group_owners: { user_id: id } }).distinct }
315335
scope :for_user, -> id {

0 commit comments

Comments
 (0)