2016-12-22 10:01:37 +08:00
class Contest < ActiveRecord :: Base
attr_accessible :description , :invite_code , :invite_code_halt , :is_delete , :is_public , :name , :user_id , :visits
2016-12-23 14:41:21 +08:00
include ContestsHelper
2016-12-22 10:01:37 +08:00
belongs_to :user
has_many :contest_members , :include = > [ :principal , :roles ] , :conditions = > " #{ Principal . table_name } .type='User' AND #{ Principal . table_name } .status= #{ Principal :: STATUS_ACTIVE } "
has_many :memberships , :class_name = > 'ContestMember'
has_many :member_principals , :class_name = > 'ContestMember' ,
:include = > :principal ,
:conditions = > " #{ Principal . table_name } .type='Group' OR ( #{ Principal . table_name } .type='User' AND #{ Principal . table_name } .status= #{ Principal :: STATUS_ACTIVE } ) "
has_many :principals , :through = > :member_principals , :source = > :principal
has_many :users , :through = > :members
has_many :contestants , :class_name = > 'ContestantForContest' , :source = > :user
2016-12-23 14:41:21 +08:00
has_many :works
2016-12-27 14:53:52 +08:00
has_many :contestant_work_projects , :dependent = > :destroy
2016-12-30 16:37:20 +08:00
has_many :boards , :dependent = > :destroy , :order = > " position ASC "
2017-01-06 15:03:01 +08:00
has_many :files
2017-01-11 10:16:25 +08:00
has_many :journals_for_messages , :as = > :jour , :dependent = > :destroy
2016-12-22 10:01:37 +08:00
2016-12-23 17:00:11 +08:00
has_many :news , :dependent = > :destroy , :include = > :author
2016-12-22 10:01:37 +08:00
has_many :contest_acts , :class_name = > 'ContestActivity' , :as = > :contest_act , :dependent = > :destroy
has_many :contest_activities
has_many :contest_messages , :class_name = > 'ContestMessage' , :as = > :contest_message , :dependent = > :destroy
2016-12-23 14:41:21 +08:00
acts_as_attachable
2016-12-22 10:01:37 +08:00
validates_format_of :name , :with = > / ^[^ ]+[a-zA-Z0-9_ \ u4e00- \ u9fa5 \ s \ S]*$ /
before_destroy :delete_all_members
2016-12-30 16:37:20 +08:00
after_create :create_board_sync
2016-12-22 10:01:37 +08:00
scope :visible , lambda { | * args | where ( Contest . where ( " is_delete =? " , 0 ) . visible_condition ( args . shift || User . current , * args ) ) }
2017-01-04 15:53:36 +08:00
def contest_judges
self . contest_members . select { | cm | cm . roles . to_s . include? ( " Judge " ) }
end
2016-12-22 10:01:37 +08:00
# 删除竞赛所有成员
def delete_all_members
if self . contest_members && self . contest_members . count > 0
me , mr = ContestMember . table_name , ContestMemberRole . table_name
connection . delete ( " DELETE FROM #{ mr } WHERE #{ mr } .contest_member_id IN (SELECT #{ me } .id FROM #{ me } WHERE #{ me } .contest_id = #{ id } ) " )
ContestMember . delete_all ( [ 'contest_id = ?' , id ] )
end
end
def self . visible_condition ( user , options = { } )
allowed_to_condition ( user , :view_course , options )
end
def self . allowed_to_condition ( user , permission , options = { } )
perm = Redmine :: AccessControl . permission ( permission )
base_statement = ( " #{ Contest . table_name } .is_delete <> 1 " )
if perm && perm . contest_module
base_statement << " AND #{ Contest . table_name } .id IN (SELECT em.contest_id FROM #{ EnabledModule . table_name } em WHERE em.name=' #{ perm . contest_module } ') "
end
if options [ :contest ]
contest_statement = " #{ Contest . table_name } .id = #{ options [ :contest ] . id } "
contest_statement << " OR ( #{ Contest . table_name } .lft > #{ options [ :contest ] . lft } AND #{ Contest . table_name } .rgt < #{ options [ :contest ] . rgt } ) " if options [ :with_subcontests ]
base_statement = " ( #{ contest_statement } ) AND ( #{ base_statement } ) "
end
if user . admin?
base_statement
else
statement_by_role = { }
unless options [ :contest_member ]
role = user . logged? ? Role . non_member : Role . anonymous
if role . allowed_to? ( permission )
statement_by_role [ role ] = " #{ Contest . table_name } .is_public = #{ connection . quoted_true } "
end
end
if user . logged?
user . contests_by_role . each do | role , contests |
if role . allowed_to? ( permission ) && contests . any?
statement_by_role [ role ] = " #{ Contest . table_name } .id IN ( #{ contests . collect ( & :id ) . join ( ',' ) } ) "
end
end
end
if statement_by_role . empty?
" 1=0 "
else
if block_given?
statement_by_role . each do | role , statement |
if s = yield ( role , user )
statement_by_role [ role ] = " ( #{ statement } AND ( #{ s } )) "
end
end
end
" (( #{ base_statement } ) AND ( #{ statement_by_role . values . join ( ' OR ' ) } )) "
end
end
end
# 竞赛动态公共表记录
def act_as_contest_activity
self . contest_acts << ContestActivity . new ( :user_id = > self . user_id , :contest_id = > self . id )
end
2016-12-22 15:17:02 +08:00
# 延迟生成邀请码
def invite_code
return generate_invite_code
end
# 生成邀请码
# 如果已有改邀请码,则重新生成
CODES = %W( 2 3 4 5 6 7 8 9 A B C D E F G H J K L N M O P Q R S T U V W X Y Z )
def generate_invite_code
code = read_attribute ( :invite_code )
if ! code || code . size < 4
code = CODES . sample ( 4 ) . join
return generate_invite_code if Project . where ( invite_code : code ) . present?
update_attribute ( :invite_code , code )
end
code
end
2016-12-30 16:37:20 +08:00
# 创建竞赛讨论区
def create_board_sync
@board = self . boards . build
#self.name=" #{l(:label_borad_course) }"
@board . name = " #{ l ( :label_board_contest ) } " #self.name
@board . description = self . name . to_s
@board . project_id = - 1
@board . course_id = - 1
if @board . save
logger . debug " [Contest Model] ===> #{ @board . to_json } "
else
logger . error " [Contest Model] ===> Auto create board when contest saved, because #{ @board . full_messages } "
end
end
2017-01-11 10:16:25 +08:00
# 新增竞赛留言
def self . add_new_jour ( user , notes , id , options = { } )
contest = Contest . find ( id )
if options . count == 0
pjfm = contest . journals_for_messages . build ( :user_id = > user . id , :notes = > notes , :reply_id = > 0 )
else
pjfm = contest . journals_for_messages . build ( options )
end
pjfm . save
pjfm
end
2016-12-22 10:01:37 +08:00
end