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

270 lines
9.3 KiB
Ruby
Raw Normal View History

2012-10-01 21:27:32 +00:00
module JamRuby
class Band < ActiveRecord::Base
2013-12-16 03:53:16 +00:00
attr_accessible :name, :website, :biography, :city, :state,
2013-12-16 18:47:59 +00:00
:country, :original_fpfile_photo, :cropped_fpfile_photo,
:cropped_s3_path_photo, :crop_selection_photo, :photo_url
2012-11-03 19:32:27 +00:00
2013-12-15 21:27:11 +00:00
attr_accessor :updating_photo
2012-10-28 02:35:28 +00:00
self.primary_key = 'id'
2012-10-01 21:27:32 +00:00
2013-12-16 03:53:16 +00:00
before_save :stringify_photo_info , :if => :updating_photo
validate :validate_photo_info
2013-07-26 08:07:24 +00:00
validates :biography, no_profanity: true
before_save :check_lat_lng
# musicians
2012-11-16 02:08:37 +00:00
has_many :band_musicians, :class_name => "JamRuby::BandMusician"
has_many :users, :through => :band_musicians, :class_name => "JamRuby::User"
# genres
has_and_belongs_to_many :genres, :class_name => "JamRuby::Genre", :join_table => "bands_genres"
2012-10-01 21:27:32 +00:00
2012-11-16 02:08:37 +00:00
# recordings
2013-01-22 19:15:52 +00:00
has_many :recordings, :class_name => "JamRuby::Recording", :foreign_key => "band_id"
# likers
has_many :likers, :class_name => "JamRuby::BandLiker", :foreign_key => "band_id", :inverse_of => :band
has_many :inverse_likers, :through => :likers, :class_name => "JamRuby::User", :foreign_key => "liker_id"
2012-11-16 02:08:37 +00:00
2012-11-04 22:54:53 +00:00
# followers
2013-04-28 19:06:17 +00:00
has_many :band_followers, :class_name => "JamRuby::BandFollower", :foreign_key => "band_id"
2013-04-29 02:21:16 +00:00
has_many :followers, :through => :band_followers, :class_name => "JamRuby::User"
2013-04-28 19:06:17 +00:00
has_many :inverse_band_followers, :through => :followers, :class_name => "JamRuby::BandFollower", :foreign_key => "follower_id"
has_many :inverse_followers, :through => :inverse_band_followers, :source => :band, :class_name => "JamRuby::Band"
# invitations
has_many :invitations, :inverse_of => :band, :class_name => "JamRuby::BandInvitation", :foreign_key => "band_id"
2012-11-04 22:54:53 +00:00
# music_sessions
has_many :music_sessions, :class_name => "JamRuby::MusicSession", :foreign_key => "band_id"
has_many :music_session_history, :class_name => "JamRuby::MusicSessionHistory", :foreign_key => "band_id", :inverse_of => :band
include Geokit::ActsAsMappable::Glue unless defined?(acts_as_mappable)
acts_as_mappable
def liker_count
return self.likers.size
2012-10-29 10:45:47 +00:00
end
def follower_count
return self.followers.size
2012-10-29 10:45:47 +00:00
end
def recording_count
return self.recordings.size
end
2012-11-24 18:22:44 +00:00
def session_count
return self.music_sessions.size
2012-11-06 04:47:50 +00:00
end
def location
2013-04-28 19:06:17 +00:00
loc = self.city.blank? ? '' : self.city
loc = loc.blank? ? self.state : "#{loc}, #{self.state}" unless self.state.blank?
#loc = loc.blank? ? self.country : "#{loc}, #{self.country}" unless self.country.blank?
loc
end
2013-12-16 03:53:16 +00:00
def validate_photo_info
if updating_photo
# we want to mak sure that original_fpfile and cropped_fpfile seems like real fpfile info objects (i.e, json objects from filepicker.io)
errors.add(:original_fpfile_photo, ValidationMessages::INVALID_FPFILE) if self.original_fpfile_photo.nil? || self.original_fpfile_photo["key"].nil? || self.original_fpfile_photo["url"].nil?
errors.add(:cropped_fpfile_photo, ValidationMessages::INVALID_FPFILE) if self.cropped_fpfile_photo.nil? || self.cropped_fpfile_photo["key"].nil? || self.cropped_fpfile_photo["url"].nil?
end
end
def add_member(user_id, admin)
BandMusician.create(:band_id => self.id, :user_id => user_id, :admin => admin)
end
2012-12-17 07:02:20 +00:00
2013-11-02 13:59:04 +00:00
def self.musician_index(band_id)
@musicians = User.joins(:band_musicians).where(:bands_musicians => {:band_id => "#{band_id}"})
end
def self.pending_musicians(band_id)
@musicians = User.joins(:received_band_invitations)
.where(:band_invitations => {:band_id => "#{band_id}"})
.where(:band_invitations => {:accepted => nil})
end
2012-12-17 07:02:20 +00:00
def self.recording_index(current_user, band_id)
hide_private = false
band = Band.find(band_id)
# hide private Recordings from anyone who's not in the Band
unless band.users.exists? current_user
hide_private = true
end
if hide_private
recordings = Recording.joins(:band_recordings)
2013-12-16 18:47:59 +00:00
.where(:bands_recordings => {:band_id => "#{band_id}"}, :public => true)
2012-12-17 07:02:20 +00:00
else
recordings = Recording.joins(:band_recordings)
2013-12-16 18:47:59 +00:00
.where(:bands_recordings => {:band_id => "#{band_id}"})
2012-12-17 07:02:20 +00:00
end
return recordings
end
# helper method for creating / updating a Band
def self.save(id, name, website, biography, city, state, country, genres, user_id, photo_url, logo_url)
user = User.find(user_id)
# new band
2013-12-17 02:32:17 +00:00
if id.blank?
# ensure person creating this Band is a Musician
unless user.musician?
raise JamRuby::PermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR
end
validate_genres(genres, false)
2012-11-03 19:32:27 +00:00
band = Band.new()
2013-12-16 18:47:59 +00:00
# band update
2012-11-03 19:32:27 +00:00
else
validate_genres(genres, true)
band = Band.find(id)
# ensure user updating Band details is a Band member
unless band.users.exists? user
raise PermissionError, ValidationMessages::USER_NOT_BAND_MEMBER_VALIDATION_ERROR
end
2012-11-03 19:32:27 +00:00
end
# name
2013-11-21 06:24:40 +00:00
band.name = name unless name.nil?
2012-11-03 19:32:27 +00:00
2012-11-04 22:54:53 +00:00
# website
2013-11-21 06:24:40 +00:00
band.website = website unless website.nil?
2012-11-03 19:32:27 +00:00
2012-11-04 22:54:53 +00:00
# biography
2013-11-21 06:24:40 +00:00
band.biography = biography unless biography.nil?
2012-11-03 19:32:27 +00:00
2012-11-06 02:55:08 +00:00
# city
2013-11-21 06:24:40 +00:00
band.city = city unless city.nil?
2012-11-06 02:55:08 +00:00
# state
2013-11-21 06:24:40 +00:00
band.state = state unless state.nil?
2012-11-06 02:55:08 +00:00
# country
2013-11-21 06:24:40 +00:00
band.country = country unless country.nil?
2012-11-06 02:55:08 +00:00
2013-12-17 02:32:17 +00:00
# photo url
band.photo_url = photo_url unless photo_url.nil?
# logo url
band.logo_url = logo_url unless logo_url.nil?
# band.updated_at = Time.now.getutc
band.save!
band.reload
2012-11-03 19:32:27 +00:00
# genres
unless genres.nil?
ActiveRecord::Base.transaction do
# delete all genres for this band first
2013-12-17 02:32:17 +00:00
band.genres.delete_all if id.present?
2012-11-04 22:54:53 +00:00
# loop through each genre in the array and save to the db
2013-12-17 02:32:17 +00:00
genres.each { |genre_id| band.genres << Genre.find(genre_id) }
2012-11-03 19:32:27 +00:00
end
end
# add the creator as the admin
2013-12-17 02:32:17 +00:00
BandMusician.create(:band_id => band.id, :user_id => user_id, :admin => true) if id.blank?
return band
end
2013-12-15 21:30:04 +00:00
def update_photo(original_fpfile, cropped_fpfile, crop_selection, aws_bucket)
2013-12-15 21:27:11 +00:00
self.updating_photo = true
cropped_s3_path = cropped_fpfile["key"]
return self.update_attributes(
2013-12-16 18:47:59 +00:00
:original_fpfile_photo => original_fpfile,
:cropped_fpfile_photo => cropped_fpfile,
:cropped_s3_path_photo => cropped_s3_path,
:crop_selection_photo => crop_selection,
:photo_url => S3Util.url(aws_bucket, cropped_s3_path, :secure => false)
)
2013-12-15 21:27:11 +00:00
end
2013-12-15 21:30:04 +00:00
def delete_photo(aws_bucket)
2013-12-15 21:27:11 +00:00
2013-12-15 21:30:04 +00:00
Band.transaction do
2013-12-15 21:27:11 +00:00
2013-12-17 04:23:59 +00:00
unless self.cropped_s3_path_photo.nil?
S3Util.delete(aws_bucket, File.dirname(self.cropped_s3_path_photo) + '/cropped.jpg')
S3Util.delete(aws_bucket, self.cropped_s3_path_photo)
2013-12-15 21:27:11 +00:00
end
return self.update_attributes(
2013-12-16 18:47:59 +00:00
:original_fpfile_photo => nil,
:cropped_fpfile_photo => nil,
:cropped_s3_path_photo => nil,
:crop_selection_photo => nil,
:photo_url => nil
)
2013-12-15 21:27:11 +00:00
end
2013-12-16 18:47:59 +00:00
end
2013-12-15 21:27:11 +00:00
def check_lat_lng
if (city_changed? || state_changed? || country_changed?)
update_lat_lng
end
2013-12-17 02:32:17 +00:00
true
end
def update_lat_lng
if self.city
query = { :city => self.city }
query[:region] = self.state unless self.state.blank?
query[:country] = self.country unless self.country.blank?
if geo = MaxMindGeo.where(query).limit(1).first
if geo.lat && geo.lng && (self.lat != geo.lat || self.lng != geo.lng)
self.lat, self.lng = geo.lat, geo.lng
return true
end
end
end
self.lat, self.lng = nil, nil
false
2013-12-15 21:27:11 +00:00
end
private
2013-12-16 18:47:59 +00:00
def self.validate_genres(genres, is_nil_ok)
if is_nil_ok && genres.nil?
return
end
2013-12-16 18:47:59 +00:00
if genres.nil?
raise JamRuby::JamArgumentError, ValidationMessages::GENRE_MINIMUM_NOT_MET
else
if genres.size < Limits::MIN_GENRES_PER_BAND
raise JamRuby::JamArgumentError, ValidationMessages::GENRE_MINIMUM_NOT_MET
2013-12-16 18:47:59 +00:00
end
2013-12-16 18:47:59 +00:00
if genres.size > Limits::MAX_GENRES_PER_BAND
raise JamRuby::JamArgumentError, ValidationMessages::GENRE_LIMIT_EXCEEDED
end
end
2013-12-16 18:47:59 +00:00
end
2013-12-16 03:53:16 +00:00
2013-12-16 18:47:59 +00:00
def stringify_photo_info
# fpfile comes in as a hash, which is a easy-to-use and validate form. However, we store it as a VARCHAR,
# so we need t oconvert it to JSON before storing it (otherwise it gets serialized as a ruby object)
# later, when serving this data out to the REST API, we currently just leave it as a string and make a JSON capable
# client parse it, because it's very rare when it's needed at all
self.original_fpfile_photo = original_fpfile_photo.to_json if !original_fpfile_photo.nil?
self.cropped_fpfile_photo = cropped_fpfile_photo.to_json if !cropped_fpfile_photo.nil?
self.crop_selection_photo = crop_selection_photo.to_json if !crop_selection_photo.nil?
end
2012-10-01 21:27:32 +00:00
end
2012-11-08 04:08:16 +00:00
end