diff --git a/ruby/lib/jam_ruby/models/band_search.rb b/ruby/lib/jam_ruby/models/band_search.rb new file mode 100644 index 000000000..927049d5b --- /dev/null +++ b/ruby/lib/jam_ruby/models/band_search.rb @@ -0,0 +1,172 @@ +module JamRuby + class MusicianSearch < BaseSearch + + attr_accessor :user_counters + + KEY_BAND_SEARCH_TYPE = 'band_search_type' + KEY_BAND_TYPE = 'band_type' + KEY_PLAY_COMMIT = 'play_commit' + KEY_TOUR_OPTION = 'tour_option' + + BAND_SEARCH_TYPE_VALS = %W{ to_join to_hire } + BAND_SEARCH_TYPES = { + BAND_SEARCH_TYPE_VALS[0] => 'search bands', + BAND_SEARCH_TYPE_VALS[1] => 'search bands to hire', + } + + SORT_VALS = %W{ distance latency } + SORT_ORDERS = { + SORT_VALS[0] => 'Distance to Me' + SORT_VALS[1] => 'Latency to Me', + } + + BAND_TYPE_VALS = [ANY_VAL_STR, + GenrePlayer::VIRTUAL_BAND, + GenrePlayer::TRADITIONAL_BAND, + ] + BAND_TYPES = { + INTEREST_VALS[0] => 'Any', + INTEREST_VALS[1] => 'Virtual Band', + INTEREST_VALS[2] => 'Traditional Band', + } + + PLAY_COMMIT_VALS = [ANY_VAL_STR, + '0', + '1', + '2', + ] + PLAY_COMMITS = { + PLAY_COMMIT_VALS[0] => 'Any', + PLAY_COMMIT_VALS[1] => 'Infrequent', + PLAY_COMMIT_VALS[2] => 'Once a week', + PLAY_COMMIT_VALS[3] => 'More than once a week', + } + + TOUR_OPTION_VALS = [ANY_VAL_STR, + 'yes', + 'no', + ] + TOUR_OPTIONS = { + TOUR_OPTION_VALS[0] => 'Any', + TOUR_OPTION_VALS[1] => 'Yes', + TOUR_OPTION_VALS[1] => 'No', + } + + JSON_SCHEMA = BaseSearch::JSON_SCHEMA.merge({ + KEY_BAND_SEARCH_TYPE => BAND_SEARCH_TYPES[0], + KEY_BAND_TYPE => BAND_TYPE_VALS[0], + KEY_PLAY_COMMIT => PLAY_COMMIT_VALS[0], + KEY_TOUR_OPTION => TOUR_OPTION_VALS[0], + }) + + SEARCH_FILTER_META = BaseSearch::SEARCH_FILTER_META.merge({ + sort_order: { keys: self::SORT_VALS, map: self::SORT_ORDERS }, + band_type: { keys: BAND_TYPE_VALS, map: BAND_TYPES }, + play_commit: { keys: PLAY_COMMIT_VALS, map: PLAY_COMMITS }, + tour_option: { keys: TOUR_OPTION_VALS, map: TOUR_OPTIONS } + }) + + def self.search_target_class + User + end + + def do_search(params={}) + rel = User.musicians.where('users.id <> ?', self.user.id) + rel = self._sort_order(rel) + rel + end + + def search_includes(rel) + rel.includes([:instruments, :followings, :friends]) + end + + def process_results_page(_results) + @results = _results + if user + @user_counters = @results.inject({}) { |hh,val| hh[val.id] = []; hh } + mids = "'#{@results.map(&:id).join("','")}'" + + # this gets counts for each search result + @results.each do |bb| + counters = { } + counters[COUNT_FOLLOW] = Follow.where(:followable_id => bb.id).count + counters[COUNT_RECORD] = Recording.where(:band_id => bb.id).count + counters[COUNT_SESSION] = MusicSession.where(:band_id => bb.id).count + @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") + 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"]) + rel.all.each { |val| @user_counters[val.bid] << RESULT_FOLLOW } + + else + @user_counters = {} + end + self + end + + private + + def _count(musician, key) + if mm = @user_counters[musician.id] + return mm.detect { |ii| ii.is_a?(Hash) }[key] + end if @user_counters + 0 + end + + public + + 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 + + def is_friend?(musician) + if mm = @user_counters[musician.id] + return mm.include?(RESULT_FRIEND) + end if @user_counters + false + end + + def is_follower?(musician) + if mm = @user_counters[musician.id] + return mm.include?(RESULT_FOLLOW) + end if @user_counters + false + end + + def search_type + self.class.to_s + end + + def is_blank? + self.data_blob == JSON_SCHEMA + end + + def description + if self.is_blank? + return 'Click search button to look for musicians with similar interests, skill levels, etc.' + end + jj = self.json + str = 'Current Search: ' + str += "Sort = #{SORT_ORDERS[json_value(BandSearch::KEY_SORT_ORDER)]}" + str + end + + end +end diff --git a/ruby/lib/jam_ruby/models/base_search.rb b/ruby/lib/jam_ruby/models/base_search.rb index d6244b355..950dab57b 100644 --- a/ruby/lib/jam_ruby/models/base_search.rb +++ b/ruby/lib/jam_ruby/models/base_search.rb @@ -44,24 +44,25 @@ module JamRuby } JSON_SCHEMA = { - KEY_SORT_ORDER => SORT_VALS[0], + KEY_SORT_ORDER => self::SORT_VALS[0], KEY_INSTRUMENTS => [], KEY_GENRES => [], - KEY_SKILL => SKILL_VALS[0].to_s, - KEY_GIGS => GIG_COUNTS[0].to_s, + KEY_SKILL => self::SKILL_VALS[0].to_s, + KEY_GIGS => self::GIG_COUNTS[0].to_s, } - JSON_SCHEMA_KEYS = JSON_SCHEMA.keys - MULTI_VALUE_KEYS = JSON_SCHEMA.collect { |kk,vv| vv.is_a?(Array) ? kk : nil }.compact - SINGLE_VALUE_KEYS = JSON_SCHEMA.keys - MULTI_VALUE_KEYS + + JSON_SCHEMA_KEYS = self::JSON_SCHEMA.keys + MULTI_VALUE_KEYS = self::JSON_SCHEMA.collect { |kk,vv| vv.is_a?(Array) ? kk : nil }.compact + SINGLE_VALUE_KEYS = self::JSON_SCHEMA.keys - self::MULTI_VALUE_KEYS SEARCH_FILTER_META = { - per_page: PER_PAGE, + per_page: self::PER_PAGE, filter_keys: { - keys: JSON_SCHEMA_KEYS, - multi: MULTI_VALUE_KEYS, - single: SINGLE_VALUE_KEYS, + keys: self::JSON_SCHEMA_KEYS, + multi: self::MULTI_VALUE_KEYS, + single: self::SINGLE_VALUE_KEYS, }, - sort_order: { keys: SORT_VALS, map: SORT_ORDERS }, + sort_order: { keys: self::SORT_VALS, map: self::SORT_ORDERS }, } RESULT_FOLLOW = :follows