VRFS-2795 musician search first draft
This commit is contained in:
parent
3ca304b612
commit
83f3d56238
|
|
@ -61,6 +61,7 @@ group :test do
|
|||
gem 'resque_spec' #, :path => "/home/jam/src/resque_spec/"
|
||||
gem 'timecop'
|
||||
gem 'rspec-prof'
|
||||
gem 'time_difference'
|
||||
end
|
||||
|
||||
# Specify your gem's dependencies in jam_ruby.gemspec
|
||||
|
|
|
|||
|
|
@ -202,6 +202,8 @@ require "jam_ruby/models/text_message"
|
|||
require "jam_ruby/jam_tracks_manager"
|
||||
require "jam_ruby/models/performance_sample"
|
||||
require "jam_ruby/models/online_presence"
|
||||
require "jam_ruby/models/json_store"
|
||||
require "jam_ruby/models/musician_search"
|
||||
|
||||
include Jampb
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
module JamRuby
|
||||
class JsonStore < ActiveRecord::Base
|
||||
self.table_name = 'json_stores'
|
||||
|
||||
serialize :data_blob, JSON
|
||||
|
||||
before_create do
|
||||
self.data_blob ||= {}
|
||||
end
|
||||
|
||||
after_save do
|
||||
@json = nil
|
||||
end
|
||||
|
||||
attr_accessible :user_id
|
||||
|
||||
belongs_to :user, class_name: "JamRuby::User"
|
||||
|
||||
def json
|
||||
@json ||= self.data_blob
|
||||
end
|
||||
|
||||
def update_json_value(key, val)
|
||||
self.json[key] = val
|
||||
self.update_attribute(:data_blob, self.json)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,229 @@
|
|||
module JamRuby
|
||||
class MusicianSearch < JsonStore
|
||||
|
||||
ANY_VAL_STR = 'any'
|
||||
ANY_VAL_INT = 0
|
||||
|
||||
PER_PAGE = 10
|
||||
|
||||
KEY_GIG = 'gig_count'
|
||||
KEY_AGES = 'ages'
|
||||
|
||||
SORT_VALS = %W{ latency distance }
|
||||
SORT_ORDERS = {
|
||||
SORT_VALS[0] => 'Latency to Me',
|
||||
SORT_VALS[1] => 'Distance to Me'
|
||||
}
|
||||
|
||||
SKILL_VALS = [ANY_VAL_STR, 'pro', 'amateur']
|
||||
SKILL_LEVELS = {
|
||||
SKILL_VALS[0] => 'Any',
|
||||
SKILL_VALS[1] => 'Pro',
|
||||
SKILL_VALS[2] => 'Amateur'
|
||||
}
|
||||
|
||||
GIG_COUNTS = [ANY_VAL_INT, 1, 11, 51, 101]
|
||||
GIG_LABELS = {
|
||||
GIG_COUNTS[0] => 'Any',
|
||||
GIG_COUNTS[1] => 'More than 0',
|
||||
GIG_COUNTS[2] => 'More than 10',
|
||||
GIG_COUNTS[3] => 'More than 50',
|
||||
GIG_COUNTS[4] => 'More than 100'
|
||||
}
|
||||
|
||||
STUDIO_COUNTS = [ANY_VAL_INT, 1, 11, 51, 101]
|
||||
STUDIOS_LABELS = {
|
||||
STUDIO_COUNTS[0] => 'Any',
|
||||
STUDIO_COUNTS[1] => 'More than 0',
|
||||
STUDIO_COUNTS[2] => 'More than 10',
|
||||
STUDIO_COUNTS[3] => 'More than 50',
|
||||
STUDIO_COUNTS[4] => 'More than 100'
|
||||
}
|
||||
|
||||
AGE_COUNTS = [ANY_VAL_INT, 10, 20, 30, 40, 50]
|
||||
AGES = {
|
||||
AGE_COUNTS[0] => 'Any',
|
||||
AGE_COUNTS[1] => 'Teens',
|
||||
AGE_COUNTS[2] => "20's",
|
||||
AGE_COUNTS[3] => "30's",
|
||||
AGE_COUNTS[4] => "40's",
|
||||
AGE_COUNTS[5] => "50+"
|
||||
}
|
||||
|
||||
INTEREST_VALS = [ANY_VAL_STR,
|
||||
GenrePlayer::VIRTUAL_BAND,
|
||||
GenrePlayer::TRADITIONAL_BAND,
|
||||
GenrePlayer::PAID_SESSION,
|
||||
GenrePlayer::FREE_SESSION,
|
||||
GenrePlayer::COWRITING,
|
||||
]
|
||||
INTERESTS = {
|
||||
INTEREST_VALS[0] => 'Any',
|
||||
INTEREST_VALS[1] => 'Virtual Band',
|
||||
INTEREST_VALS[2] => 'Traditional Band',
|
||||
INTEREST_VALS[3] => 'Paid Sessions',
|
||||
INTEREST_VALS[4] => 'Free Sessions',
|
||||
INTEREST_VALS[5] => 'Co-Writing'
|
||||
}
|
||||
|
||||
JSON_SCHEMA = {
|
||||
:sort_order => '',
|
||||
:instruments => [],
|
||||
:interests => '',
|
||||
KEY_GIG => 0,
|
||||
:studio_session_count => '',
|
||||
:genres => [],
|
||||
:skills => '',
|
||||
KEY_AGES => []
|
||||
}
|
||||
|
||||
def self.create_search(user)
|
||||
ms = self.new
|
||||
ms.user = user
|
||||
ms.data_blob = JSON_SCHEMA
|
||||
ms.save!
|
||||
ms
|
||||
end
|
||||
|
||||
def _genres(rel)
|
||||
gids = json['genres']
|
||||
unless gids.blank?
|
||||
rel = rel.joins("RIGHT JOIN genre_players AS ugenres ON ugenres.player_id = users.id")
|
||||
.where(['ugenres.genre_id IN ("?") AND users.id IS NOT NULL', gids.join('","')])
|
||||
end
|
||||
rel
|
||||
end
|
||||
|
||||
def _instruments(rel)
|
||||
unless (instruments = json['instruments']).blank?
|
||||
rel = rel.joins("inner JOIN musicians_instruments AS minst ON minst.user_id = users.id")
|
||||
sql = ''
|
||||
instruments.each do |inst_level|
|
||||
sql += "(minst.instrument_id = '#{inst_level['id']}' AND minst.proficiency_level = #{inst_level['level']}) OR "
|
||||
end
|
||||
sql.chomp!(' OR ')
|
||||
rel = rel.where(sql)
|
||||
end
|
||||
rel
|
||||
end
|
||||
|
||||
def _ages(rel)
|
||||
unless (vals = json[KEY_AGES]).blank?
|
||||
return rel if vals.detect { |vv| ANY_VAL_INT == vv }
|
||||
arels = []
|
||||
vals.each do |val|
|
||||
today = Date.today
|
||||
case val
|
||||
when 10
|
||||
arels << User.where("birth_date >= ? AND birth_date < ?",
|
||||
today - 20.years, today - 10.years)
|
||||
when 20
|
||||
arels << User.where("birth_date >= ? AND birth_date < ?",
|
||||
today - 30.years, today - 20.years)
|
||||
when 30
|
||||
arels << User.where("birth_date >= ? AND birth_date < ?",
|
||||
today - 40.years, today - 50.years)
|
||||
when 40
|
||||
arels << User.where("birth_date >= ? AND birth_date < ?",
|
||||
today - 50.years, today - 40.years)
|
||||
when 50
|
||||
arels << User.where("birth_date <= ?", today - 50.years)
|
||||
end
|
||||
end
|
||||
rel = rel.where("birth_date IS NOT NULL")
|
||||
.where(arels.map(&:where_values).flatten.join(" OR "))
|
||||
end
|
||||
rel
|
||||
end
|
||||
|
||||
def _studios(rel)
|
||||
if 0 < (count = json['studio_session_count'].to_i)
|
||||
rel = rel.where('studio_session_count IS NOT NULL')
|
||||
case count
|
||||
when STUDIO_COUNTS[1]
|
||||
rel = rel.where('studio_session_count >= ? AND studio_session_count < ',
|
||||
count, STUDIO_COUNTS[2])
|
||||
when STUDIO_COUNTS[2]
|
||||
rel = rel.where('studio_session_count >= ? AND studio_session_count < ',
|
||||
count, STUDIO_COUNTS[3])
|
||||
when STUDIO_COUNTS[3]
|
||||
rel = rel.where('studio_session_count >= ? AND studio_session_count < ',
|
||||
count, STUDIO_COUNTS[4])
|
||||
when STUDIO_COUNTS[4]
|
||||
rel = rel.where('studio_session_count >= ?', count)
|
||||
end
|
||||
end
|
||||
rel
|
||||
end
|
||||
|
||||
def _gigs(rel)
|
||||
if 0 < (count = json[KEY_GIG].to_i)
|
||||
rel = rel.where('concert_count IS NOT NULL')
|
||||
case count
|
||||
when GIG_COUNTS[1]
|
||||
rel = rel.where('concert_count >= ? AND concert_count < ',
|
||||
count, GIG_COUNTS[2])
|
||||
when GIG_COUNTS[2]
|
||||
rel = rel.where('concert_count >= ? AND concert_count < ',
|
||||
count, GIG_COUNTS[3])
|
||||
when GIG_COUNTS[3]
|
||||
rel = rel.where('concert_count >= ? AND concert_count < ',
|
||||
count, GIG_COUNTS[4])
|
||||
when GIG_COUNTS[4]
|
||||
rel = rel.where('concert_count >= ?', count)
|
||||
end
|
||||
end
|
||||
rel
|
||||
end
|
||||
|
||||
def _skills(rel)
|
||||
if 0 < (count = json['skill_level'].to_i)
|
||||
rel = rel.where('skill_level IS NOT NULL')
|
||||
case count
|
||||
when SKILL_VALS[1]
|
||||
rel = rel.where('skill_level >= ? AND skill_level < ',
|
||||
count, SKILL_VALS[2])
|
||||
when SKILL_VALS[2]
|
||||
rel = rel.where('skill_level >= ? AND skill_level < ',
|
||||
count, SKILL_VALS[3])
|
||||
when SKILL_VALS[3]
|
||||
rel = rel.where('skill_level >= ? AND skill_level < ',
|
||||
count, SKILL_VALS[4])
|
||||
when SKILL_VALS[4]
|
||||
rel = rel.where('skill_level >= ?', count)
|
||||
end
|
||||
end
|
||||
rel
|
||||
end
|
||||
|
||||
def _interests(rel)
|
||||
val = json['interests']
|
||||
if val.present? && ANY_VAL_STR != val
|
||||
rel = rel.joins("RIGHT JOIN genre_players AS interest ON interest.player_id = users.id")
|
||||
.where(['interest..genre_type = ? AND users.id IS NOT NULL', val])
|
||||
end
|
||||
rel
|
||||
end
|
||||
|
||||
def pagination(rel, params)
|
||||
perpage = [(params[:per_page] || PER_PAGE).to_i, 100].min
|
||||
page = [params[:page].to_i, 1].max
|
||||
[rel.paginate(:page => page, :per_page => perpage), page]
|
||||
end
|
||||
|
||||
def do_search(params={})
|
||||
rel = User.musicians
|
||||
rel = self._genres(rel)
|
||||
rel = self._ages(rel)
|
||||
rel = self._studios(rel)
|
||||
rel = self._gigs(rel)
|
||||
rel = self._skills(rel)
|
||||
rel = self._instruments(rel)
|
||||
rel = self._interests(rel)
|
||||
rel, page = self.pagination(rel, params)
|
||||
rel
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -155,6 +155,8 @@ module JamRuby
|
|||
has_many :online_presences, :class_name => "JamRuby::OnlinePresence"
|
||||
has_many :performance_samples, :class_name => "JamRuby::PerformanceSample"
|
||||
|
||||
has_one :musician_search, :class_name => 'JamRuby::MusicianSearch'
|
||||
|
||||
before_save :create_remember_token, :if => :should_validate_password?
|
||||
before_save :stringify_avatar_info , :if => :updating_avatar
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,85 @@
|
|||
require 'spec_helper'
|
||||
require 'time_difference'
|
||||
require 'byebug'
|
||||
|
||||
describe 'Musician Search Model' do
|
||||
let!(:searcher) { FactoryGirl.create(:austin_user) }
|
||||
let!(:search) { MusicianSearch.create_search(searcher) }
|
||||
|
||||
before(:all) do
|
||||
User.delete_all
|
||||
@users = []
|
||||
today = Date.today
|
||||
MusicianSearch::AGE_COUNTS.each_with_index do |age, idx|
|
||||
age = 0==idx ? MusicianSearch::AGE_COUNTS[1] : age
|
||||
dd = today - age.years - 1.day
|
||||
@users << FactoryGirl.create(:austin_user, :birth_date => dd)
|
||||
@users << FactoryGirl.create(:dallas_user, :birth_date => dd)
|
||||
@users << FactoryGirl.create(:miami_user, :birth_date => dd)
|
||||
@users << FactoryGirl.create(:seattle_user, :birth_date => dd)
|
||||
end
|
||||
end
|
||||
|
||||
describe "creates search obj" do
|
||||
it "associates to user" do
|
||||
expect(search.user).to eq(searcher)
|
||||
searcher.reload
|
||||
expect(searcher.musician_search).to eq(search)
|
||||
end
|
||||
|
||||
it "sets json" do
|
||||
search.update_json_value(MusicianSearch::KEY_GIG, MusicianSearch::GIG_COUNTS[1])
|
||||
expect(search.json[MusicianSearch::KEY_GIG]).to eq(MusicianSearch::GIG_COUNTS[1])
|
||||
end
|
||||
end
|
||||
|
||||
describe "filtering criteria" do
|
||||
|
||||
it "filters musicians" do
|
||||
expect(search.do_search(per_page: User.musicians.count).count).to eq(User.musicians.count)
|
||||
end
|
||||
|
||||
it "filters ages" do
|
||||
age = MusicianSearch::AGE_COUNTS[1]
|
||||
search.update_json_value(MusicianSearch::KEY_AGES, [age])
|
||||
today = Date.today.to_time
|
||||
search.do_search.all.each do |uu|
|
||||
diff = TimeDifference.between(uu.birth_date.to_time, today).in_years
|
||||
expect(diff).to be >= age
|
||||
expect(diff).to be < MusicianSearch::AGE_COUNTS[2]
|
||||
end
|
||||
search.update_json_value(MusicianSearch::KEY_AGES, [0])
|
||||
search.do_search.to_sql =~ /(birth_date)/
|
||||
expect($1).to eq(nil)
|
||||
end
|
||||
|
||||
it "filters genres" do
|
||||
end
|
||||
it "filters studio sessions" do
|
||||
end
|
||||
it "filters gigs" do
|
||||
end
|
||||
it "filters skills" do
|
||||
end
|
||||
it "filters instruments" do
|
||||
end
|
||||
it "filters interests" do
|
||||
end
|
||||
it "filters combinations" do
|
||||
end
|
||||
end
|
||||
|
||||
describe "pagination" do
|
||||
it "first page results" do
|
||||
end
|
||||
it "second page results" do
|
||||
end
|
||||
end
|
||||
|
||||
describe "sort order" do
|
||||
before(:each) do
|
||||
create_phony_database
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
Loading…
Reference in New Issue