1
0
Fork 0
forked from OpenNeo/impress

Improve not_occupied solution

Not being a subquery is better! I realized later that a LEFT JOIN would probably do it even betterer? with like `HAVING count(x) = 0`? but the `left_outer_joins` method doesn't seem to be in Rails 4, and I don't want to do stringy joins, so this is fine for now!
This commit is contained in:
Matchu 2023-07-28 14:10:13 -07:00
parent ab015db461
commit 4ac1304c74

View file

@ -87,11 +87,15 @@ class Item < ActiveRecord::Base
zone_ids = Zone.matching_label(zone_label, locale).map(&:id)
i = Item.arel_table
sa = SwfAsset.arel_table
psa = ParentSwfAssetRelationship.arel_table
subquery = SwfAsset.select('COUNT(*)').joins(:parent_swf_asset_relationships).
where(psa[:parent_type].eq('Item')).where(psa[:parent_id].eq(i[:id])).
where(sa[:zone_id].in(zone_ids))
where("(#{subquery.to_sql}) = 0")
# Querying for "has NO swf_assets matching these zone IDs" is trickier than
# the positive case! To do it, we GROUP_CONCAT the zone_ids together for
# each item, then use FIND_IN_SET to search the result for each zone ID,
# and assert that it must not find a match. (This is uhh, not exactly fast,
# so it helps to have other tighter conditions applied first!)
# TODO: I feel like this could also be solved with a LEFT JOIN, idk if that
# performs any better? In Rails 5+ `left_outer_joins` is built in so!
condition = zone_ids.map { 'FIND_IN_SET(?, GROUP_CONCAT(zone_id)) = 0' }.join(' AND ')
joins(:swf_assets).group(i[:id]).having(condition, *zone_ids).distinct
}
scope :restricts, ->(zone_label, locale = I18n.locale) {
zone_ids = Zone.matching_label(zone_label, locale).map(&:id)