Add occupies filter back to item search

Mostly adapting what was already there!
This commit is contained in:
Matchu 2023-07-26 12:28:25 -07:00
parent da508ab33a
commit db9e3dfb53
3 changed files with 31 additions and 5 deletions

View file

@ -30,8 +30,6 @@ class Item < ActiveRecord::Base
order(it[:name])
}
scope :join_swf_assets, -> { joins(:swf_assets).group(arel_table[:id]) }
scope :newest, -> {
order(arel_table[:created_at].desc) if arel_table[:created_at]
}
@ -77,6 +75,22 @@ class Item < ActiveRecord::Base
where('description NOT LIKE ?',
'%' + Item.sanitize_sql_like(PAINTBRUSH_SET_DESCRIPTION) + '%')
}
scope :occupies, ->(zone_label, locale = I18n.locale) {
zone_ids = Zone.matching_label(zone_label, locale).map(&:id)
i = Item.arel_table
sa = SwfAsset.arel_table
Item.joins(:swf_assets).where(sa[:zone_id].in(zone_ids)).distinct
}
scope :not_occupies, ->(zone_label, locale = I18n.locale) {
# TODO: The perf on this is miserable on its own, the query plan chooses
# a bad index for the join on parents_swf_assets here (but not in the
# `occupies` scope?) and I don't know why! But it makes a better plan when
# combined with `name_includes` so this is probably fine in practice?
zone_ids = Zone.matching_label(zone_label, locale).map(&:id)
i = Item.arel_table
sa = SwfAsset.arel_table
Item.joins(:swf_assets).where(sa[:zone_id].not_in(zone_ids)).distinct
}
def closeted?
@owned || @wanted

View file

@ -38,6 +38,10 @@ class Item
filters << (is_positive ?
Filter.name_includes(value, locale) :
Filter.name_excludes(value, locale))
when 'occupies'
filters << (is_positive ?
Filter.occupies(value, locale) :
Filter.not_occupies(value, locale))
when 'is'
case value
when 'nc'
@ -101,6 +105,14 @@ class Item
self.new Item.name_excludes(value, locale), text
end
def self.occupies(value, locale)
self.new Item.occupies(value, locale), "occupies:#{value}"
end
def self.not_occupies(value, locale)
self.new Item.not_occupies(value, locale), "-occupies:#{value}"
end
def self.is_nc
self.new Item.is_nc, 'is:nc'
end

View file

@ -9,11 +9,11 @@ class Zone < ActiveRecord::Base
with_translations(I18n.locale).order(Zone::Translation.arel_table[:label])
}
scope :includes_translations, -> { includes(:translations) }
scope :with_plain_label, ->(label) {
scope :matching_label, ->(label, locale = I18n.locale) {
t = Zone::Translation.arel_table
includes(:translations)
joins(:translations)
.where(t[:locale].eq(locale))
.where(t[:plain_label].eq(Zone.plainify_label(label)))
.where(t[:locale].eq(I18n.locale))
}
scope :for_items, -> { where(arel_table[:type_id].gt(1)) }