jam-cloud/ruby/lib/jam_ruby/models/track.rb

156 lines
4.3 KiB
Ruby

module JamRuby
class Track < ActiveRecord::Base
self.table_name = "tracks"
self.primary_key = 'id'
default_scope order('created_at ASC')
attr_accessor :musician, :instrument_ids
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]
result.push(connection_track)
if connection_track.save
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