2012-11-08 01:13:35 +00:00
module JamRuby
2014-01-11 14:59:09 +00:00
2014-01-11 12:26:40 +00:00
# not a active_record model; just a search result container
2012-11-08 01:13:35 +00:00
class Search
2015-05-01 18:22:34 +00:00
attr_accessor :results , :search_type , :query
2014-01-11 14:59:09 +00:00
attr_accessor :user_counters , :page_num , :page_count
2013-01-14 04:50:38 +00:00
LIMIT = 10
2013-10-28 14:22:06 +00:00
2014-01-11 12:26:40 +00:00
SEARCH_TEXT_TYPES = [ :musicians , :bands , :fans ]
SEARCH_TEXT_TYPE_ID = :search_text_type
2012-11-08 01:13:35 +00:00
2014-02-16 07:28:39 +00:00
PARAM_SESSION_INVITE = :srch_sessinv
2013-11-23 12:16:40 +00:00
PARAM_MUSICIAN = :srch_m
2013-11-30 00:34:00 +00:00
PARAM_BAND = :srch_b
2014-01-22 02:56:35 +00:00
PARAM_FEED = :srch_f
2014-11-04 20:55:12 +00:00
PARAM_JAMTRACK = :srch_j
2013-11-06 13:50:34 +00:00
2014-02-18 07:09:31 +00:00
F_PER_PAGE = B_PER_PAGE = M_PER_PAGE = 20
2013-11-23 12:16:40 +00:00
M_MILES_DEFAULT = 500
2013-11-30 00:34:00 +00:00
B_MILES_DEFAULT = 0
2013-11-06 13:50:34 +00:00
M_ORDER_FOLLOWS = [ 'Most Followed' , :followed ]
M_ORDER_PLAYS = [ 'Most Plays' , :plays ]
M_ORDER_PLAYING = [ 'Playing Now' , :playing ]
2014-07-29 04:04:56 +00:00
M_ORDER_LATENCY = [ 'Latency To Me' , :latency ]
2014-09-22 19:20:58 +00:00
M_ORDER_DISTANCE = [ 'Distance To Me' , :distance ]
M_ORDERINGS = [ M_ORDER_LATENCY , M_ORDER_DISTANCE , M_ORDER_FOLLOWS , M_ORDER_PLAYS ]
2014-07-29 04:04:56 +00:00
ORDERINGS = B_ORDERINGS = [ M_ORDER_FOLLOWS , M_ORDER_PLAYS , M_ORDER_PLAYING ]
M_ORDERING_KEYS = M_ORDERINGS . collect { | oo | oo [ 1 ] }
B_ORDERING_KEYS = B_ORDERINGS . collect { | oo | oo [ 1 ] }
2013-11-30 00:34:00 +00:00
2014-09-22 19:20:58 +00:00
DISTANCE_OPTS = B_DISTANCE_OPTS = M_DISTANCE_OPTS = [ [ 25 . to_s , 25 ] , [ 50 . to_s , 50 ] , [ 100 . to_s , 100 ] , [ 250 . to_s , 250 ] , [ 500 . to_s , 500 ] , [ 1000 . to_s , 1000 ] ]
2013-11-06 13:50:34 +00:00
2014-05-30 16:34:06 +00:00
# the values for score ranges are raw roundtrip scores. david often talks of one way scores (<= 20 is good), but
# the client reports scores as roundtrip and the server uses those values throughout
GOOD_SCORE = '.-40'
MODERATE_SCORE = '40-80'
POOR_SCORE = '80-120'
UNACCEPTABLE_SCORE = '120-.'
SCORED_SCORE = '.-.' # does not appear in menu choices
TEST_SCORE = '.-60' # does not appear in menu choices
ANY_SCORE = ''
M_SCORE_OPTS = [ [ 'Any' , ANY_SCORE ] , [ 'Good' , GOOD_SCORE ] , [ 'Moderate' , MODERATE_SCORE ] , [ 'Poor' , POOR_SCORE ] , [ 'Unacceptable' , UNACCEPTABLE_SCORE ] ]
M_SCORE_DEFAULT = ANY_SCORE
2014-09-22 19:20:58 +00:00
M_DISTANCE_DEFAULT = 500
2014-05-30 16:34:06 +00:00
2014-03-11 07:40:58 +00:00
F_SORT_RECENT = [ 'Most Recent' , :date ]
F_SORT_OLDEST = [ 'Most Liked' , :likes ]
F_SORT_LENGTH = [ 'Most Played' , :plays ]
2014-01-22 02:56:35 +00:00
F_SORT_OPTS = [ F_SORT_RECENT , F_SORT_LENGTH , F_SORT_OLDEST ]
2014-03-11 07:40:58 +00:00
SHOW_BOTH = [ 'Sessions & Recordings' , :all ]
2014-05-06 13:34:38 +00:00
SHOW_SESSIONS = [ 'Sessions' , :music_session ]
2014-03-11 07:40:58 +00:00
SHOW_RECORDINGS = [ 'Recordings' , :recording ]
2014-01-22 02:56:35 +00:00
SHOW_OPTS = [ SHOW_BOTH , SHOW_SESSIONS , SHOW_RECORDINGS ]
2014-03-11 07:40:58 +00:00
DATE_OPTS = [ [ 'Today' , 'today' ] , [ 'This Week' , 'week' ] , [ 'This Month' , 'month' ] , [ 'All Time' , 'all' ] ]
2014-01-22 02:56:35 +00:00
2015-05-01 18:22:34 +00:00
def initialize ( search_results = nil )
@results = [ ]
self
end
def is_blank?
! ! @query && @query . empty?
2013-11-06 13:50:34 +00:00
end
2015-05-01 18:22:34 +00:00
def text_search ( params , user = nil )
@query = params [ :query ]
tsquery = Search . create_tsquery ( params [ :query ] )
return [ ] if tsquery . blank?
2013-11-06 13:50:34 +00:00
2015-05-01 18:22:34 +00:00
rel = case params [ SEARCH_TEXT_TYPE_ID ] . to_s
when 'bands'
@search_type = :bands
2016-07-17 15:16:27 +00:00
Band . where ( nil )
2015-05-01 18:22:34 +00:00
when 'fans'
@search_type = :fans
User . fans
else
@search_type = :musicians
User . musicians
end
@results = rel . where ( " (name_tsv @@ to_tsquery('jamenglish', ?)) " , tsquery ) . limit ( 10 )
2020-10-14 02:05:08 +00:00
@results = Search . scope_schools_together ( @results , user )
2015-05-01 18:22:34 +00:00
end
2014-05-20 14:46:45 +00:00
2015-05-01 18:22:34 +00:00
class << self
def band_search ( txt , user = nil )
self . text_search ( { SEARCH_TEXT_TYPE_ID = > :bands , :query = > txt } , user )
2014-05-29 02:19:50 +00:00
end
2015-05-01 18:22:34 +00:00
def fan_search ( txt , user = nil )
self . text_search ( { SEARCH_TEXT_TYPE_ID = > :fans , :query = > txt } , user )
end
2014-05-29 02:19:50 +00:00
2015-05-01 18:22:34 +00:00
def musician_search ( txt , user = nil )
self . text_search ( { SEARCH_TEXT_TYPE_ID = > :musicians , :query = > txt } , user )
end
2014-09-22 19:20:58 +00:00
2015-05-01 18:22:34 +00:00
def session_invite_search ( query , user )
srch = Search . new
srch . search_type = :session_invite
like_str = " % #{ query . downcase } % "
rel = User
. musicians
. where ( [ " users.id IN (SELECT friend_id FROM friendships WHERE user_id = ' #{ user . id } ') " ] )
. where ( [ " first_name ILIKE ? OR last_name ILIKE ? " , like_str , like_str ] )
. limit ( 10 )
. order ( [ :last_name , :first_name ] )
srch . results = rel . all
srch
2014-09-22 19:20:58 +00:00
end
2020-10-14 02:05:08 +00:00
def scope_schools_together_feeds ( rel , user )
if user . nil?
return rel . where ( " feeds.school_id is null " )
end
# platform instructors can search anybody (non-school and school). So no nothing special for them.
if ! user . is_platform_instructor
# for everyone else...
# make sure you can only see same-school. Or in the case of 'null school', you'll get other non-schoolers (i.e. normies)
# also, make sure anyone will find platform_instructors
if user . school_id . nil?
rel = rel . where ( " feeds.school_id is null " )
else
rel = rel . where ( " feeds.school_id = #{ user . school_id } OR feeds.is_platform_instructor " )
end
end
rel
end
def scope_schools_together_sessions ( rel , user , table_name = 'active_music_sessions' )
if user . nil?
return rel . where ( " #{ table_name } .school_id is null " )
end
# platform instructors can search anybody (non-school and school). So no nothing special for them.
if ! user . is_platform_instructor
# for everyone else...
# make sure you can only see same-school. Or in the case of 'null school', you'll get other non-schoolers (i.e. normies)
# also, make sure anyone will find platform_instructors
if user . school_id . nil?
rel = rel . where ( " #{ table_name } .school_id is null " )
else
rel = rel . where ( " #{ table_name } .school_id = #{ user . school_id } OR #{ table_name } .is_platform_instructor " )
end
end
rel
end
def scope_schools_together ( rel , user )
if user . nil?
return rel . where ( " school_id is null " )
end
# platform instructors can search anybody (non-school and school). So no nothing special for them.
if ! user . is_platform_instructor
# for everyone else...
# make sure you can only see same-school. Or in the case of 'null school', you'll get other non-schoolers (i.e. normies)
# also, make sure anyone will find platform_instructors
if user . school_id . nil?
rel = rel . where ( " school_id is null " )
else
rel = rel . where ( " school_id = #{ user . school_id } OR is_platform_instructor " )
end
end
rel
end
2015-05-01 18:22:34 +00:00
def text_search ( params , user = nil )
srch = Search . new
unless ( params . blank? || params [ :query ] . blank? || 2 > params [ :query ] . length )
srch . text_search ( params , user )
end
srch
2014-09-22 19:20:58 +00:00
end
2014-05-27 16:52:18 +00:00
2015-05-01 18:22:34 +00:00
def create_tsquery ( query )
return nil if query . blank?
search_terms = query . split
return nil if search_terms . length == 0
args = nil
search_terms . each do | search_term |
2015-08-22 10:44:59 +00:00
# remove ( ) ! : from query terms. parser blows up
search_term . gsub! ( / [ \ ( \ )!:] / , '' )
2015-05-01 18:22:34 +00:00
if args == nil
2015-08-22 10:32:28 +00:00
args = '"' + search_term + '"'
2014-05-30 16:34:06 +00:00
else
2015-08-22 10:32:28 +00:00
args = args + " & " + '"' + search_term + '"'
2015-05-01 18:22:34 +00:00
end
end
args = args + " :* "
args
end
2015-08-18 19:26:41 +00:00
2015-05-01 18:22:34 +00:00
def order_param ( params , keys = M_ORDERING_KEYS )
ordering = params [ :orderby ]
ordering . blank? ? keys [ 0 ] : keys . detect { | oo | oo . to_s == ordering }
end
# produce a list of musicians (users where musician is true)
# params:
# instrument - instrument to search for or blank
# score_limit - a range specification for score, see M_SCORE_OPTS above.
# handled by relation_pagination:
# page - page number to fetch (origin 1)
# per_page - number of entries per page
# handled by order_param:
# orderby - what sort of search, also defines order (followed, plays, playing)
# previously handled by where_latlng:
# distance - defunct!
# city - defunct!
# remote_ip - defunct!
def musician_filter ( params = { } , user = nil )
rel = User . musicians # not musicians_geocoded on purpose; we allow 'unknowns' to surface in the search page
rel = rel . select ( 'users.*' )
rel = rel . group ( 'users.id' )
unless ( instrument = params [ :instrument ] ) . blank?
VRFS-3242 : Schema and model changes required for band profile functionality.
* Additional attributes for band_type, band_status, concert_count,
add_new_members, play_commitment, touring_option, paid_gigs,
hourly_rate, gig_minimum
* For joined table musician_instruments, remove the hard requirement
that they be joined to a user, rather a “player” that is polymorphic.
* For joined table performance_stamples, remove the hard requirement
that they be joined to a user, rather a “player” that is polymorphic.
* For joined table online_presences, remove the hard requirement that
they be joined to a user, rather a “player” that is polymorphic.
* Change models as appropriate with new attributes and modify
belongs_to / has_many directives as necessary.
* Fix existing usages of user_id to work with polymorphic player_id.
* Fix tests that use user_id
* Add new tests that exercise online_presence, performance_samples, and
instruments that target a band, rather than a user.
2015-05-14 02:06:14 +00:00
rel = rel . joins ( " inner JOIN musicians_instruments AS minst ON minst.player_id = users.id " )
2015-05-01 18:22:34 +00:00
. where ( [ 'minst.instrument_id = ?' , instrument ] )
2014-05-30 16:34:06 +00:00
end
2020-10-14 02:05:08 +00:00
rel = scope_schools_together ( rel , user )
2015-05-01 18:22:34 +00:00
# to find appropriate musicians we need to join users with scores to get to those with no scores or bad scores
# weeded out
2014-05-30 16:34:06 +00:00
2015-05-01 18:22:34 +00:00
# filter on scores using selections from params
# see M_SCORE_OPTS
score_limit = ANY_SCORE
l = params [ :score_limit ]
unless l . nil?
score_limit = l
end
2014-07-29 04:04:56 +00:00
2015-05-01 18:22:34 +00:00
locidispid = user . nil? ? 0 : ( user . last_jam_locidispid || 0 )
# user can override their location with these 3 values
country = params [ :country ]
region = params [ :region ]
city = params [ :city ]
my_locid = nil # this is used for distance searches only
2020-09-01 18:56:13 +00:00
#if country && region && city
# geoiplocation = GeoIpLocations.where(countrycode: country, region: region, city: city).first
# my_locid = geoiplocation.locid
#end
2015-05-01 18:22:34 +00:00
unless my_locid
my_locid = locidispid / 1000000 # if the user didn't specify a location to search on, user their account locidispid
end
if ! locidispid . nil? && ! user . nil?
# score_join of left allows for null scores, whereas score_join of inner requires a score however good or bad
# this is ANY_SCORE:
score_join = 'left outer' # or 'inner'
score_min = nil
score_max = nil
# these score_min, score_max come from here (doubled): https://jamkazam.atlassian.net/browse/VRFS-1962
case score_limit
when GOOD_SCORE
score_join = 'inner'
score_min = nil
score_max = 40
when MODERATE_SCORE
score_join = 'inner'
score_min = 40
score_max = 70
when POOR_SCORE
score_join = 'inner'
score_min = 80
score_max = 100
when UNACCEPTABLE_SCORE
score_join = 'inner'
score_min = 100
score_max = nil
when SCORED_SCORE
score_join = 'inner'
score_min = nil
score_max = nil
when TEST_SCORE
score_join = 'inner'
score_min = nil
score_max = 60
when ANY_SCORE
# the default of ANY setup above applies
else
# the default of ANY setup above applies
end
rel = rel . joins ( " LEFT JOIN current_scores ON current_scores.a_userid = users.id AND current_scores.b_userid = ' #{ user . id } ' " )
rel = rel . joins ( 'LEFT JOIN regions ON regions.countrycode = users.country AND regions.region = users.state' )
rel = rel . where ( [ 'current_scores.full_score > ?' , score_min ] ) unless score_min . nil?
rel = rel . where ( [ 'current_scores.full_score <= ?' , score_max ] ) unless score_max . nil?
rel = rel . select ( 'current_scores.full_score, current_scores.score, regions.regionname' )
rel = rel . group ( 'current_scores.full_score, current_scores.score, regions.regionname' )
end
ordering = self . order_param ( params )
case ordering
when :latency
# nothing to do. the sort added below 'current_scores.score ASC NULLS LAST' handles this
when :distance
# convert miles to meters for PostGIS functions
miles = params [ :distance ] . blank? ? 500 : params [ :distance ] . to_i
meters = miles * 1609 . 34
rel = rel . joins ( " INNER JOIN geoiplocations AS my_geo ON #{ my_locid } = my_geo.locid " )
rel = rel . joins ( " INNER JOIN geoiplocations AS other_geo ON users.last_jam_locidispid/1000000 = other_geo.locid " )
rel = rel . where ( " users.last_jam_locidispid/1000000 IN (SELECT locid FROM geoiplocations WHERE geog && st_buffer((SELECT geog FROM geoiplocations WHERE locid = #{ my_locid } ), #{ meters } )) " )
rel = rel . group ( " my_geo.geog, other_geo.geog " )
rel = rel . order ( 'st_distance(my_geo.geog, other_geo.geog)' )
when :plays # FIXME: double counting?
# sel_str = "COUNT(records)+COUNT(sessions) AS play_count, #{sel_str}"
rel = rel . select ( 'COUNT(records.id)+COUNT(sessions.id) AS search_play_count' )
rel = rel . joins ( " LEFT JOIN music_sessions AS sessions ON sessions.user_id = users.id " )
rel = rel . joins ( " LEFT JOIN recordings AS records ON records.owner_id = users.id " )
rel = rel . order ( " search_play_count DESC " )
when :followed
rel = rel . joins ( 'left outer join follows on follows.followable_id = users.id' )
rel = rel . select ( 'count(follows.user_id) as search_follow_count' )
rel = rel . order ( 'search_follow_count DESC' )
when :playing
rel = rel . joins ( " inner JOIN connections ON connections.user_id = users.id " )
rel = rel . where ( [ 'connections.aasm_state != ?' , 'expired' ] )
end
2014-05-27 16:52:18 +00:00
2015-05-01 18:22:34 +00:00
if ! locidispid . nil? && ! user . nil?
rel = rel . order ( 'current_scores.full_score ASC NULLS LAST' )
end
rel = rel . order ( 'users.created_at DESC' )
rel , page = self . relation_pagination ( rel , params )
rel = rel . includes ( [ :instruments , :followings , :friends ] )
# XXX: DOES THIS MEAN ALL MATCHING USERS ARE RETURNED?
objs = rel . all
srch = Search . new
srch . search_type = :musicians_filter
srch . page_num , srch . page_count = page , objs . total_pages
srch . musician_results_for_user ( objs , user )
2014-05-29 02:19:50 +00:00
end
2015-05-01 18:22:34 +00:00
def relation_pagination ( rel , params )
perpage = [ ( params [ :per_page ] || M_PER_PAGE ) . to_i , 100 ] . min
page = [ params [ :page ] . to_i , 1 ] . max
[ rel . paginate ( :page = > page , :per_page = > perpage ) , page ]
2014-05-27 16:52:18 +00:00
end
2013-11-28 04:32:13 +00:00
2015-05-01 18:22:34 +00:00
def new_musicians ( usr , since_date )
# this attempts to find interesting musicians to tell another musician about where interesting
# is "has a good score and was created recently"
# we're sort of depending upon usr being a musicians_geocoded as well...
# this appears to only be called from EmailBatchNewMusician#deliver_batch_sets! which is
# an offline process and thus uses the last jam location as "home base"
locidispid = usr . last_jam_locidispid
score_limit = 70
limit = 50
rel = User . musicians_geocoded
. where ( [ 'users.created_at >= ? AND users.id != ?' , since_date , usr . id ] )
. joins ( 'inner join current_scores on users.id = current_scores.a_userid' )
. where ( [ 'current_scores.b_userid = ?' , usr . id ] )
. where ( [ 'current_scores.full_score <= ?' , score_limit ] )
. order ( 'current_scores.full_score' ) # best scores first
. order ( 'users.created_at DESC' ) # then most recent
. limit ( limit )
objs = rel . all . to_a
if block_given?
yield ( objs ) if 0 < objs . count
else
return objs
end
2013-11-06 13:50:34 +00:00
end
2015-05-01 18:22:34 +00:00
def band_filter ( params = { } , current_user = nil )
rel = Band . scoped
2014-05-29 02:19:50 +00:00
2015-05-01 18:22:34 +00:00
unless ( genre = params [ :genre ] ) . blank?
rel = Band . joins ( " RIGHT JOIN genre_players AS bgenres ON bgenres.player_id = bands.id AND bgenres.player_type = 'JamRuby::Band' " )
. where ( [ 'bgenres.genre_id = ? AND bands.id IS NOT NULL' , genre ] )
end
2013-11-06 13:50:34 +00:00
2015-05-01 18:22:34 +00:00
rel = GeoIpLocations . where_latlng ( rel , params , current_user )
2014-05-29 02:19:50 +00:00
2015-05-01 18:22:34 +00:00
sel_str = 'bands.*'
case ordering = self . order_param ( params , B_ORDERING_KEYS )
when :plays # FIXME: double counting?
sel_str = " COUNT(records)+COUNT(msh) AS play_count, #{ sel_str } "
rel = rel . joins ( " LEFT JOIN music_sessions AS msh ON msh.band_id = bands.id " )
. joins ( " LEFT JOIN recordings AS records ON records.band_id = bands.id " )
. group ( " bands.id " )
. order ( " play_count DESC, bands.created_at DESC " )
when :followed
sel_str = " COUNT(follows) AS search_follow_count, #{ sel_str } "
rel = rel . joins ( " LEFT JOIN follows ON follows.followable_id = bands.id " )
. group ( " bands.id " )
. order ( " COUNT(follows) DESC, bands.created_at DESC " )
when :playing
rel = rel . joins ( " LEFT JOIN music_sessions AS msh ON msh.band_id = bands.id " )
. where ( 'msh.music_session_id IS NOT NULL AND msh.session_removed_at IS NULL' )
. order ( " bands.created_at DESC " )
end
rel = rel . select ( sel_str )
rel , page = self . relation_pagination ( rel , params )
rel = rel . includes ( [ { :users = > :instruments } , :genres ] )
objs = rel . all
srch = Search . new
srch . search_type = :band_filter
srch . page_num , srch . page_count = page , objs . total_pages
if 1 == page && current_user . bands . present?
current_user . bands . order ( 'created_at DESC' ) . each { | bb | objs . unshift ( bb ) }
end if current_user && current_user . is_a? ( User )
srch . band_results_for_user ( objs , current_user )
end
2013-11-06 13:50:34 +00:00
2013-12-09 17:41:35 +00:00
end
2015-05-01 18:22:34 +00:00
2013-11-05 14:49:31 +00:00
RESULT_FOLLOW = :follows
RESULT_FRIEND = :friends
2013-11-06 13:50:34 +00:00
COUNT_FRIEND = :count_friend
COUNT_FOLLOW = :count_follow
COUNT_RECORD = :count_record
COUNT_SESSION = :count_session
COUNTERS = [ COUNT_FRIEND , COUNT_FOLLOW , COUNT_RECORD , COUNT_SESSION ]
2014-01-11 15:27:56 +00:00
def musician_results_for_user ( _results , user )
@results = _results
2013-11-05 14:49:31 +00:00
if user
2014-01-11 15:27:56 +00:00
@user_counters = @results . inject ( { } ) { | hh , val | hh [ val . id ] = [ ] ; hh }
mids = " ' #{ @results . map ( & :id ) . join ( " ',' " ) } ' "
2013-11-28 04:32:13 +00:00
# this gets counts for each search result on friends/follows/records/sessions
2014-01-11 15:27:56 +00:00
@results . each do | uu |
2013-11-06 13:50:34 +00:00
counters = { }
counters [ COUNT_FRIEND ] = Friendship . where ( :user_id = > uu . id ) . count
2014-02-16 07:28:35 +00:00
counters [ COUNT_FOLLOW ] = Follow . where ( :followable_id = > uu . id ) . count
2013-11-14 17:56:20 +00:00
counters [ COUNT_RECORD ] = ClaimedRecording . where ( :user_id = > uu . id ) . count
2013-11-06 13:50:34 +00:00
counters [ COUNT_SESSION ] = MusicSession . where ( :user_id = > uu . id ) . count
@user_counters [ uu . id ] << counters
end
2013-11-05 14:49:31 +00:00
2013-11-28 04:32:13 +00:00
# this section determines follow/like/friend status for each search result
# so that action links can be activated or not
2013-11-05 15:07:02 +00:00
rel = User . select ( " users.id AS uid " )
2014-02-16 07:28:35 +00:00
rel = rel . joins ( " LEFT JOIN follows ON follows.user_id = ' #{ user . id } ' " )
rel = rel . where ( [ " users.id IN ( #{ mids } ) AND follows.followable_id = users.id " ] )
2013-11-06 13:50:34 +00:00
rel . all . each { | val | @user_counters [ val . uid ] << RESULT_FOLLOW }
2013-11-05 14:49:31 +00:00
2013-11-05 15:07:02 +00:00
rel = User . select ( " users.id AS uid " )
2013-11-05 14:49:31 +00:00
rel = rel . joins ( " LEFT JOIN friendships AS friends ON friends.friend_id = ' #{ user . id } ' " )
rel = rel . where ( [ " users.id IN ( #{ mids } ) AND friends.user_id = users.id " ] )
2013-11-06 13:50:34 +00:00
rel . all . each { | val | @user_counters [ val . uid ] << RESULT_FRIEND }
2013-11-06 10:16:47 +00:00
2013-11-05 14:49:31 +00:00
else
2013-11-06 13:50:34 +00:00
@user_counters = { }
2013-11-05 14:49:31 +00:00
end
self
end
2013-11-25 21:56:54 +00:00
private
2013-11-06 13:50:34 +00:00
def _count ( musician , key )
if mm = @user_counters [ musician . id ]
return mm . detect { | ii | ii . is_a? ( Hash ) } [ key ]
2013-11-15 19:52:53 +00:00
end if @user_counters
2013-11-06 13:50:34 +00:00
0
end
2013-11-25 21:56:54 +00:00
public
2014-02-16 07:28:39 +00:00
def session_invite_search?
:session_invite == @search_type
end
2014-01-11 15:12:26 +00:00
def musicians_text_search?
2014-01-11 14:59:09 +00:00
:musicians == @search_type
end
2014-01-11 15:12:26 +00:00
def fans_text_search?
2014-01-11 14:59:09 +00:00
:fans == @search_type
end
2014-01-11 15:12:26 +00:00
def bands_text_search?
2014-01-11 14:59:09 +00:00
:bands == @search_type
end
2014-01-11 15:12:26 +00:00
def musicians_filter_search?
:musicians_filter == @search_type
end
def bands_filter_search?
:band_filter == @search_type
2014-01-11 14:59:09 +00:00
end
2013-11-06 13:50:34 +00:00
def follow_count ( musician )
_count ( musician , COUNT_FOLLOW )
end
def friend_count ( musician )
_count ( musician , COUNT_FRIEND )
end
def record_count ( musician )
_count ( musician , COUNT_RECORD )
end
def session_count ( musician )
_count ( musician , COUNT_SESSION )
end
2013-11-05 14:49:31 +00:00
def is_friend? ( musician )
2013-11-06 13:50:34 +00:00
if mm = @user_counters [ musician . id ]
2013-11-05 14:49:31 +00:00
return mm . include? ( RESULT_FRIEND )
2013-11-15 19:52:53 +00:00
end if @user_counters
2013-11-05 14:49:31 +00:00
false
end
def is_follower? ( musician )
2013-11-06 13:50:34 +00:00
if mm = @user_counters [ musician . id ]
2013-11-05 14:49:31 +00:00
return mm . include? ( RESULT_FOLLOW )
2013-11-15 19:52:53 +00:00
end if @user_counters
2013-11-05 14:49:31 +00:00
false
end
2014-05-23 02:42:07 +00:00
2013-12-09 13:15:59 +00:00
2014-01-11 15:27:56 +00:00
def band_results_for_user ( _results , user )
@results = _results
2013-12-09 13:15:59 +00:00
if user
2014-01-11 15:27:56 +00:00
@user_counters = @results . inject ( { } ) { | hh , val | hh [ val . id ] = [ ] ; hh }
mids = " ' #{ @results . map ( & :id ) . join ( " ',' " ) } ' "
2013-12-09 13:15:59 +00:00
# this gets counts for each search result
2014-01-11 15:27:56 +00:00
@results . each do | bb |
2013-12-09 13:15:59 +00:00
counters = { }
2014-02-16 07:28:35 +00:00
counters [ COUNT_FOLLOW ] = Follow . where ( :followable_id = > bb . id ) . count
2013-12-09 17:41:35 +00:00
counters [ COUNT_RECORD ] = Recording . where ( :band_id = > bb . id ) . count
counters [ COUNT_SESSION ] = MusicSession . where ( :band_id = > bb . id ) . count
2013-12-09 13:15:59 +00:00
@user_counters [ bb . id ] << counters
end
# this section determines follow/like/friend status for each search result
# so that action links can be activated or not
rel = Band . select ( " bands.id AS bid " )
2014-02-16 07:28:35 +00:00
rel = rel . joins ( " LEFT JOIN follows ON follows.user_id = ' #{ user . id } ' " )
rel = rel . where ( [ " bands.id IN ( #{ mids } ) AND follows.followable_id = bands.id " ] )
2013-12-09 13:15:59 +00:00
rel . all . each { | val | @user_counters [ val . bid ] << RESULT_FOLLOW }
else
@user_counters = { }
end
self
end
2012-11-08 01:13:35 +00:00
end
2013-04-25 06:50:52 +00:00
end