module JamRuby class Feed < ActiveRecord::Base belongs_to :recording, class_name: "JamRuby::Recording", inverse_of: :feed, foreign_key: 'recording_id' belongs_to :music_session, class_name: "JamRuby::MusicSession", inverse_of: :feed, foreign_key: 'music_session_id' FIXNUM_MAX = (2**(0.size * 8 -2) -1) SORT_TYPES = ['date', 'plays', 'likes'] TIME_RANGES = { "today" => 1 , "week" => 7, "month" => 30, "all" => 0} TYPE_FILTERS = ['music_session', 'recording', 'all'] def self.index(user, params = {}) limit = params[:limit] limit ||= 20 limit = limit.to_i # validate sort sort = params[:sort] sort ||= 'date' raise "not valid sort #{sort}" unless SORT_TYPES.include?(sort) time_range = params[:time_range] time_range ||= 'all' raise "not valid time_range #{time_range}" unless TIME_RANGES.has_key?(time_range) type_filter = params[:type] type_filter ||= 'all' raise "not valid type #{type_filter}" unless TYPE_FILTERS.include?(type_filter) target_user = params[:user] target_band = params[:band] #query = Feed.includes([:recording]).includes([:music_session]).limit(limit) query = Feed.joins("LEFT OUTER JOIN recordings ON recordings.id = feeds.recording_id") .joins("LEFT OUTER JOIN music_sessions ON music_sessions.id = feeds.music_session_id") .limit(limit) .where('feeds.recording_id is NULL OR (recordings.all_discarded = false AND recordings.deleted = false)') # remove any 'all_discarded recordings from the search results' or 'deleted' # handle sort if sort == 'date' query = query.order('feeds.id DESC') elsif sort == 'plays' query = query.order("COALESCE(recordings.play_count, music_sessions.play_count) DESC") elsif sort == 'likes' query = query.order("COALESCE(recordings.like_count, music_sessions.like_count) DESC") else raise "sort not implemented: #{sort}" end # handle time range days = TIME_RANGES[time_range] if days > 0 query = query.where("feeds.created_at > NOW() - '#{days} day'::INTERVAL") end # handle type filters if type_filter == 'music_session' query = query.where('feeds.music_session_id is not NULL') elsif type_filter == 'recording' query = query.where('feeds.recording_id is not NULL') end if target_user query = query.joins("LEFT OUTER JOIN claimed_recordings ON recordings.id = claimed_recordings.recording_id AND claimed_recordings.discarded = FALSE AND (claimed_recordings.user_id = '#{target_user}' OR (recordings.band_id IN (SELECT band_id FROM bands_musicians where user_id='#{target_user}')))") query = query.joins("LEFT OUTER JOIN music_sessions_user_history ON music_sessions.id = music_sessions_user_history.music_session_id AND music_sessions_user_history.user_id = '#{target_user}'") query = query.group("feeds.id") if sort == 'plays' query = query.group("COALESCE(recordings.play_count, music_sessions.play_count)") elsif sort == 'likes' query = query.group("COALESCE(recordings.like_count, music_sessions.like_count)") end query = query.where('feeds.recording_id is NULL OR claimed_recordings.id IS NOT NULL') query = query.where('feeds.music_session_id is NULL OR music_sessions_user_history.id IS NOT NULL') elsif target_band query = query.joins("LEFT OUTER JOIN claimed_recordings ON feeds.recording_id = claimed_recordings.recording_id AND claimed_recordings.discarded = FALSE AND recordings.band_id = '#{target_band}'") query = query.where("feeds.music_session_id IS NULL OR music_sessions.band_id = '#{target_band}'") query = query.group("feeds.id") if sort == 'plays' query = query.group("COALESCE(recordings.play_count, music_sessions.play_count)") elsif sort == 'likes' query = query.group("COALESCE(recordings.like_count, music_sessions.like_count)") end query = query.where('feeds.recording_id is NULL OR claimed_recordings.id IS NOT NULL') #query = query.where('music_sessions.id is NULL OR music_sessions_user_history.id IS NOT NULL') else query = query.joins('LEFT OUTER JOIN claimed_recordings ON feeds.recording_id = claimed_recordings.recording_id AND claimed_recordings.discarded = FALSE') query = query.joins("LEFT OUTER JOIN music_sessions_user_history ON music_sessions.id = music_sessions_user_history.music_session_id") query = query.group("feeds.id") if sort == 'plays' query = query.group("COALESCE(recordings.play_count, music_sessions.play_count)") elsif sort == 'likes' query = query.group("COALESCE(recordings.like_count, music_sessions.like_count)") end query = query.where('feeds.recording_id is NULL OR claimed_recordings.is_public = TRUE') query = query.where('feeds.music_session_id is NULL OR music_sessions_user_history.id IS NOT NULL') end current_page = params[:next_page].nil? ? 1 : params[:next_page].to_i next_page = current_page + 1 # will_paginate gem query = query.paginate(:page => current_page, :per_page => limit) if params[:hash] if query.length == 0 # no more results { query: query, next_page: nil} elsif query.length < limit # no more results { query: query, next_page: nil} else { query: query, next_page: next_page } end else if query.length == 0 # no more results [query, nil] elsif query.length < limit # no more results [query, nil] else [query, next_page] end end end end end