summaryrefslogtreecommitdiff
path: root/app/models/tournament.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/tournament.rb')
-rw-r--r--app/models/tournament.rb177
1 files changed, 177 insertions, 0 deletions
diff --git a/app/models/tournament.rb b/app/models/tournament.rb
index dcdb8d5..8a96dcc 100644
--- a/app/models/tournament.rb
+++ b/app/models/tournament.rb
@@ -1,3 +1,180 @@
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
+
+ # 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