diff options
Diffstat (limited to 'app/models/tournament.rb')
-rw-r--r-- | app/models/tournament.rb | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/app/models/tournament.rb b/app/models/tournament.rb index dcdb8d5..854b8c9 100644 --- a/app/models/tournament.rb +++ b/app/models/tournament.rb @@ -1,3 +1,184 @@ class Tournament < ActiveRecord::Base belongs_to :game + + has_many :tournament_stages + # Don't validate presence of stages; sadly, it seems to break things + #validates_presence_of :tournament_stages + alias_attribute :stages, :tournament_stages + + has_many :brackets + + has_many :tournament_settings + + has_and_belongs_to_many :players, class_name: "User", association_foreign_key: "player_id", join_table: "players_tournaments" + + has_and_belongs_to_many :hosts, class_name: "User", association_foreign_key: "host_id", join_table: "hosts_tournaments" + validates_presence_of :hosts + + validates_presence_of :game + + before_save { self.status ||= 0 } + + validates(:name, + presence: true, + length: {minimum: 5}, + uniqueness: {case_sensitive: true}) + + validates(:min_players_per_team, + presence: true, + numericality: { + only_integer: true, + less_than_or_equal_to: :max_players_per_team, + }) + validates(:max_players_per_team, + presence: true, + numericality: { + only_integer: true, + greater_than_or_equal_to: :min_players_per_team, + }) + + validates(:min_teams_per_match, + presence: true, + numericality: { + only_integer: true, + less_than_or_equal_to: :max_teams_per_match, + }) + validates(:max_teams_per_match, + presence: true, + numericality: { + only_integer: true, + greater_than_or_equal_to: :min_teams_per_match, + }) + + validate :validate_scoring_method + def validate_scoring_method + (not self.scoring_method.try(:empty?)) and (scoring_methods.include? scoring_method) + end + + def owned_by?(user) + self.hosts.include?(user) + end + + # Settings ################################################################# + + def settings + @settings ||= Settings.new(self) + end + + def settings=(setting) + setting.each do |key, value| + value = false if value == "0" + settings[key] = value + end + end + + class Settings + def initialize(tournament) + @tournament = tournament + end + + def [](setting_name) + tournament_setting = @tournament.tournament_settings.find{|s|s.name==setting_name} + if tournament_setting.nil? + return nil + else + return tournament_setting.value + end + end + + def []=(setting_name, val) + tournament_setting = @tournament.tournament_settings.find{|s|s.name==setting_name} + if tournament_setting.nil? + game_setting = @tournament.game.settings.find_by_name(setting_name) + @tournament.tournament_settings.build(name: setting_name, value: val, + vartype: game_setting.vartype, + type_opt: game_setting.type_opt, + description: game_setting.description, + display_order: game_setting.display_order) + else + tournament_setting.value = val + end + end + + def keys + @tournament.tournament_settings.all.collect { |x| x.name } + end + + def empty?() keys.empty? end + def count() keys.count end + def length() count end + def size() count end + + def method_missing(name, *args) + if name.to_s.ends_with?('=') + self[name.to_s.sub(/=$/, '').to_s] = args.first + else + return self[name.to_s] + end + end + end + + # Joining/Leaving ########################################################## + + def joinable_by?(user) + return (status==0 and user.can?(:join_tournament) and !players.include?(user)) + end + + def join(user) + unless joinable_by?(user) + return false + end + players.push(user) + end + + def leave(user) + if players.include?(user) && status == 0 + players.delete(user) + end + end + + # Configured methods ####################################################### + + def scoring + @scoring ||= "Scoring::#{self.scoring_method.camelcase}".constantize + end + + # Options for configured methods/modules ################################### + # We're conflicted about whether these should be `self.` or not. ########### + + def self.scoring_methods + make_methods "scoring" + end + def scoring_methods + self.class.scoring_methods + end + + def sampling_methods + self.class.make_methods("sampling").select do |name| + "Sampling::#{name.camelcase}".constantize.works_with?(self.game) + end + end + + def self.scheduling_methods + make_methods "scheduling" + end + def scheduling_methods + self.class.scheduling_methods + end + + def self.seeding_methods + make_methods "seeding" + end + def seeding_methods + self.class.seeding_methods + end + + private + def self.make_methods(dir) + @methods ||= {} + if @methods[dir].nil? or Rails.env.development? + @methods[dir] = Dir.glob("#{Rails.root}/lib/#{dir}/*.rb").map{|filename| File.basename(filename, ".rb") } + end + return @methods[dir] + end end |