Oops, add unowned & unwanted support to search!

Uhhh idk how I messed this up, but right, wanting is not the opposite of owning, LOL!
This commit is contained in:
Matchu 2023-07-29 12:48:45 -07:00
parent 5a362d8048
commit bc5241d087
2 changed files with 53 additions and 7 deletions

View file

@ -66,9 +66,12 @@ class Item
case value case value
when 'owns' when 'owns'
filters << (is_positive ? filters << (is_positive ?
Filter.user_owns(user) : Filter.owned_by(user) :
Filter.user_wants(user)) Filter.not_owned_by(user))
when 'wants' when 'wants'
filters << (is_positive ?
Filter.wanted_by(user) :
Filter.not_wanted_by(user))
else else
message = I18n.translate('items.search.errors.not_found.ownership', message = I18n.translate('items.search.errors.not_found.ownership',
keyword: value) keyword: value)
@ -167,14 +170,22 @@ class Item
self.new Item.not_fits(body_id), "-fits:#{value}" self.new Item.not_fits(body_id), "-fits:#{value}"
end end
def self.user_owns(user) def self.owned_by(user)
self.new user.owned_items, 'user:owns' self.new user.owned_items, 'user:owns'
end end
def self.user_wants(user) def self.not_owned_by(user)
self.new user.unowned_items, 'user:owns'
end
def self.wanted_by(user)
self.new user.wanted_items, 'user:wants' self.new user.wanted_items, 'user:wants'
end end
def self.not_wanted_by(user)
self.new user.unwanted_items, 'user:wants'
end
def self.is_nc def self.is_nc
self.new Item.is_nc, 'is:nc' self.new Item.is_nc, 'is:nc'
end end

View file

@ -7,13 +7,17 @@ class User < ActiveRecord::Base
has_many :closet_hangers has_many :closet_hangers
has_many :closet_lists has_many :closet_lists
has_many :closeted_items, through: :closet_hangers, source: :item has_many :closeted_items, through: :closet_hangers, source: :item
has_many :contributions
has_many :neopets_connections
has_many :outfits
# TODO: When `owned_items` and `wanted_items` are merged, they override one
# another instead of correctly returning an empty set. Is this a Rails bug
# that gets fixed down the line once we finish upgrading, or...?
has_many :owned_items, -> { where(ClosetHanger.arel_table[:owned].eq(true)) }, has_many :owned_items, -> { where(ClosetHanger.arel_table[:owned].eq(true)) },
through: :closet_hangers, source: :item through: :closet_hangers, source: :item
has_many :wanted_items, -> { where(ClosetHanger.arel_table[:owned].eq(false)) }, has_many :wanted_items, -> { where(ClosetHanger.arel_table[:owned].eq(false)) },
through: :closet_hangers, source: :item through: :closet_hangers, source: :item
has_many :contributions
has_many :neopets_connections
has_many :outfits
belongs_to :contact_neopets_connection, class_name: 'NeopetsConnection' belongs_to :contact_neopets_connection, class_name: 'NeopetsConnection'
@ -25,6 +29,37 @@ class User < ActiveRecord::Base
name == 'matchu' # you know that's right. name == 'matchu' # you know that's right.
end end
def unowned_items
# Join all items against our owned closet hangers, group by item ID, then
# only return those with zero matching hangers.
#
# TODO: It'd be nice to replace this with a `left_outer_joins` call in
# Rails 5+, but these conditions really do need to be part of the join:
# if we do them as a `where`, they prevent unmatching items from being
# returned in the first place.
#
# TODO: This crashes the query when combined with `unwanted_items`.
ch = ClosetHanger.arel_table.alias("owned_hangers")
Item.
joins(
"LEFT JOIN closet_hangers owned_hangers ON owned_hangers.item_id = items.id " +
"AND #{ch[:user_id].eq(self.id).to_sql} AND owned_hangers.owned = true"
).
group("items.id").having("COUNT(owned_hangers.id) = 0")
end
def unwanted_items
# See `unowned_items` above! We just change the `true` to `false`.
# TODO: This crashes the query when combined with `unowned_items`.
ch = ClosetHanger.arel_table.alias("wanted_hangers")
Item.
joins(
"LEFT JOIN closet_hangers wanted_hangers ON wanted_hangers.item_id = items.id " +
"AND #{ch[:user_id].eq(self.id).to_sql} AND wanted_hangers.owned = false"
).
group("items.id").having("COUNT(wanted_hangers.id) = 0")
end
def contribute!(pet) def contribute!(pet)
new_contributions = [] new_contributions = []
pet.contributables.each do |contributable| pet.contributables.each do |contributable|