module JamRuby class Track < ActiveRecord::Base self.table_name = "tracks" self.primary_key = 'id' default_scope order('created_at ASC') attr_accessor :musician SOUND = %w(mono stereo) belongs_to :connection, :class_name => "JamRuby::Connection", :inverse_of => :tracks, :foreign_key => 'connection_id' belongs_to :instrument, :class_name => "JamRuby::Instrument", :inverse_of => :tracks validates :sound, :inclusion => {:in => SOUND} validates :connection, presence: true def user self.connection.user end def musician @musician end def musician=(user) @musician = user end def self.index(current_user, music_session_id) query = Track .joins( %Q{ INNER JOIN connections ON connections.music_session_id = '#{music_session_id}' AND connections.id = connection_id AND connections.user_id = '#{current_user.id}' INNER JOIN music_sessions ON music_sessions.id = '#{music_session_id}' AND music_sessions.user_id = '#{current_user.id}' } ) return query end # this is a bit different from a normal track synchronization in that the client just sends up all tracks, # ... some may already exist def self.sync(clientId, tracks) result = [] Track.transaction do connection = Connection.find_by_client_id!(clientId) # each time tracks are synced we have to update the entry in music_sessions_user_history msh = MusicSessionUserHistory.find_by_client_id!(clientId) instruments = [] if tracks.length == 0 connection.tracks.delete_all else connection_tracks = connection.tracks # we will prune from this as we find matching tracks to_delete = Set.new(connection_tracks) to_add = Array.new(tracks) connection_tracks.each do |connection_track| tracks.each do |track| if track[:id] == connection_track.id || track[:client_track_id] == connection_track.client_track_id; to_delete.delete(connection_track) to_add.delete(track) # don't update connection_id or client_id; it's unknown what would happen if these changed mid-session connection_track.instrument_id = track[:instrument_id] connection_track.sound = track[:sound] connection_track.client_track_id = track[:client_track_id] instruments << track[:instrument_id] if connection_track.save result.push(connection_track) next else result = connection_track raise ActiveRecord::Rollback end end end end msh.instruments = instruments.join("|") if !msh.save raise ActiveRecord::Rollback end to_add.each do |track| connection_track = Track.new connection_track.connection = connection connection_track.instrument_id = track[:instrument_id] connection_track.sound = track[:sound] connection_track.client_track_id = track[:client_track_id] if connection_track.save result.push(connection_track) else result = connection_track raise ActiveRecord::Rollback end end to_delete.each do |delete_me| delete_me.delete end end end result end def self.save(id, connection_id, instrument_id, sound, client_track_id) if id.nil? track = Track.new track.connection_id = connection_id else track = Track.find(id) end unless instrument_id.nil? track.instrument_id = instrument_id end unless sound.nil? track.sound = sound end unless client_track_id.nil? track.client_track_id = client_track_id end track.updated_at = Time.now.getutc track.save return track end end end