mirror of
https://github.com/ENSL/ensl.org.git
synced 2025-01-26 03:01:00 +00:00
Merge rails-4 to rails4
This commit is contained in:
commit
2c71b1147d
165 changed files with 2162 additions and 1980 deletions
26
.env.dev
Normal file
26
.env.dev
Normal file
|
@ -0,0 +1,26 @@
|
|||
RACK_ENV=development
|
||||
RAILS_ENV=development
|
||||
APP_SECRET=fe837ea72667ec3d8ecb94cfba1a1bba
|
||||
|
||||
DEPLOY_PATH=/var/www
|
||||
|
||||
PUMA_WORKERS=1
|
||||
PUMA_MIN_THREADS=1
|
||||
PUMA_MAX_THREADS=16
|
||||
PUMA_PORT=4000
|
||||
PUMA_TIMEOUT=30
|
||||
|
||||
MYSQL_HOST=db
|
||||
MYSQL_DATABASE=ensl
|
||||
MYSQL_USERNAME=ensl
|
||||
MYSQL_PASSWORD=ensl
|
||||
MYSQL_ROOT_PASSWORD=ensl
|
||||
MYSQL_CONNECTION_POOL=8
|
||||
|
||||
NEW_RELIC_APP_NAME=ENSL
|
||||
NEW_RELIC_LICENSE_KEY=
|
||||
|
||||
EXCEPTIONAL_API_KEY=
|
||||
|
||||
GOOGLE_API_KEY=
|
||||
GOOGLE_CALENDAR_ID=
|
26
.env.test
Normal file
26
.env.test
Normal file
|
@ -0,0 +1,26 @@
|
|||
RACK_ENV=test
|
||||
RAILS_ENV=test
|
||||
APP_SECRET=fe837ea72667ec3d8ecb94cfba1a1bba
|
||||
|
||||
DEPLOY_PATH=/var/www
|
||||
|
||||
PUMA_WORKERS=1
|
||||
PUMA_MIN_THREADS=1
|
||||
PUMA_MAX_THREADS=16
|
||||
PUMA_PORT=4000
|
||||
PUMA_TIMEOUT=30
|
||||
|
||||
MYSQL_HOST=db
|
||||
MYSQL_DATABASE=ensl_test
|
||||
MYSQL_USERNAME=ensl
|
||||
MYSQL_PASSWORD=ensl
|
||||
MYSQL_ROOT_PASSWORD=ensl
|
||||
MYSQL_CONNECTION_POOL=8
|
||||
|
||||
NEW_RELIC_APP_NAME=ENSL
|
||||
NEW_RELIC_LICENSE_KEY=
|
||||
|
||||
EXCEPTIONAL_API_KEY=
|
||||
|
||||
GOOGLE_API_KEY=
|
||||
GOOGLE_CALENDAR_ID=
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -17,6 +17,7 @@
|
|||
# Database and files
|
||||
db_data/*
|
||||
!db_data/.placeholder
|
||||
*.sql
|
||||
|
||||
# ignore dkim keys
|
||||
dkim
|
||||
|
|
|
@ -18,8 +18,8 @@ RUN su -c "bundle config github.https true; cd /var/www && bundle install --path
|
|||
|
||||
WORKDIR /var/www
|
||||
USER web
|
||||
|
||||
RUN bundle config github.https true; cd /var/www && bundle install -- path /var/bundle --jobs 4
|
||||
|
||||
RUN bundle config github.https true; cd /var/www && bundle install --path /var/bundle --jobs 4
|
||||
|
||||
USER root
|
||||
CMD ["/var/www/script/entry.sh"]
|
||||
|
|
28
Gemfile
28
Gemfile
|
@ -1,11 +1,10 @@
|
|||
source 'http://rubygems.org'
|
||||
|
||||
ruby '2.2.10'
|
||||
#ruby '2.2.2'
|
||||
|
||||
gem 'dotenv-rails', '~> 0.10.0'
|
||||
gem 'rails', '~> 3.2.22'
|
||||
gem 'mysql2', '~> 0.3.17'
|
||||
gem 'rails', '~> 4.1.16'
|
||||
gem 'mysql2', '~> 0.3.18'
|
||||
gem 'dalli', '~> 2.7.0'
|
||||
gem 'puma', '~> 2.11.1'
|
||||
|
||||
|
@ -22,31 +21,35 @@ gem 'newrelic_rpm', '~> 3.13.0.299'
|
|||
gem 'will_paginate', '~> 3.0.5'
|
||||
gem 'dynamic_form', '~> 1.1.4'
|
||||
gem 'country_select', require: 'country_select_without_sort_alphabetical'
|
||||
gem 'i18n_country_select'
|
||||
gem 'active_link_to', '~> 1.0.2'
|
||||
gem 'rmagick', '~> 2.13.4', require: false
|
||||
gem 'steam-condenser', github: 'koraktor/steam-condenser-ruby'
|
||||
gem 'test-unit', '~> 3.1.3'
|
||||
gem 'google-api-client', '~> 0.10.3'
|
||||
gem 'steam-condenser', github: 'koraktor/steam-condenser-ruby'
|
||||
gem 'public_suffix', '~> 3.1.1'
|
||||
gem 'active_record_union'
|
||||
|
||||
# Dependency version fix
|
||||
gem 'signet', '0.11.0'
|
||||
|
||||
# Please install nodejs locally.
|
||||
#gem 'therubyracer', '~> 0.12.1' if RUBY_PLATFORM == 'x86_64-linux'
|
||||
|
||||
gem 'sprockets', '~> 2.2.1'
|
||||
gem 'coffee-rails', '~> 3.2.2'
|
||||
gem 'coffee-rails', '~> 4.0.0'
|
||||
gem 'jquery-rails', '~> 2.0.2'
|
||||
gem 'tinymce-rails', '~> 3.5.9'
|
||||
gem 'sass', '~> 3.3.4'
|
||||
gem 'sass-rails', '~> 3.2.6'
|
||||
gem 'sass-rails', '~> 5.0.3'
|
||||
|
||||
gem 'font-awesome-sass', '~> 4.1.0.0'
|
||||
gem 'bourbon', '~> 3.1.8'
|
||||
gem 'neat', '~> 1.6.0'
|
||||
gem 'haml', '~> 4.0.5'
|
||||
gem 'rails_autolink', '~> 1.1.5'
|
||||
gem 'uglifier', '~> 2.5.0'
|
||||
|
||||
group :assets do
|
||||
gem 'uglifier', '~> 2.5.0'
|
||||
end
|
||||
# Legacy feature shims
|
||||
gem 'protected_attributes', '~> 1.1.3'
|
||||
|
||||
group :development do
|
||||
gem 'capistrano', '~> 3.1.0'
|
||||
|
@ -67,9 +70,10 @@ group :test do
|
|||
gem 'rspec-rails', '~> 3.3.3'
|
||||
gem 'capybara', '~> 2.4.4'
|
||||
gem 'poltergeist', '~> 1.6.0'
|
||||
gem 'selenium-webdriver', '~> 2.41.0'
|
||||
gem 'selenium-webdriver', '~> 2.47.1'
|
||||
gem 'factory_girl_rails', '~> 4.4.1'
|
||||
gem 'timecop', '~> 0.7.1'
|
||||
gem 'rspec'
|
||||
end
|
||||
|
||||
group :development, :test do
|
||||
|
|
262
Gemfile.lock
262
Gemfile.lock
|
@ -1,6 +1,6 @@
|
|||
GIT
|
||||
remote: git://github.com/koraktor/steam-condenser-ruby.git
|
||||
revision: 5795d15152995cc6bada5265fa379cfc57103618
|
||||
revision: 2cb441f0518a0b8d20a017dfcc42783ae878311a
|
||||
specs:
|
||||
steam-condenser (1.3.11)
|
||||
multi_json (~> 1.6)
|
||||
|
@ -9,42 +9,43 @@ GIT
|
|||
GEM
|
||||
remote: http://rubygems.org/
|
||||
specs:
|
||||
actionmailer (3.2.22.5)
|
||||
actionpack (= 3.2.22.5)
|
||||
mail (~> 2.5.4)
|
||||
actionpack (3.2.22.5)
|
||||
activemodel (= 3.2.22.5)
|
||||
activesupport (= 3.2.22.5)
|
||||
builder (~> 3.0.0)
|
||||
actionmailer (4.1.16)
|
||||
actionpack (= 4.1.16)
|
||||
actionview (= 4.1.16)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
actionpack (4.1.16)
|
||||
actionview (= 4.1.16)
|
||||
activesupport (= 4.1.16)
|
||||
rack (~> 1.5.2)
|
||||
rack-test (~> 0.6.2)
|
||||
actionview (4.1.16)
|
||||
activesupport (= 4.1.16)
|
||||
builder (~> 3.1)
|
||||
erubis (~> 2.7.0)
|
||||
journey (~> 1.0.4)
|
||||
rack (~> 1.4.5)
|
||||
rack-cache (~> 1.2)
|
||||
rack-test (~> 0.6.1)
|
||||
sprockets (~> 2.2.1)
|
||||
active_link_to (1.0.5)
|
||||
actionpack
|
||||
addressable
|
||||
activemodel (3.2.22.5)
|
||||
activesupport (= 3.2.22.5)
|
||||
builder (~> 3.0.0)
|
||||
activerecord (3.2.22.5)
|
||||
activemodel (= 3.2.22.5)
|
||||
activesupport (= 3.2.22.5)
|
||||
arel (~> 3.0.2)
|
||||
tzinfo (~> 0.3.29)
|
||||
activeresource (3.2.22.5)
|
||||
activemodel (= 3.2.22.5)
|
||||
activesupport (= 3.2.22.5)
|
||||
activesupport (3.2.22.5)
|
||||
i18n (~> 0.6, >= 0.6.4)
|
||||
multi_json (~> 1.0)
|
||||
addressable (2.5.2)
|
||||
public_suffix (>= 2.0.2, < 4.0)
|
||||
active_record_union (1.3.0)
|
||||
activerecord (>= 4.0)
|
||||
activemodel (4.1.16)
|
||||
activesupport (= 4.1.16)
|
||||
builder (~> 3.1)
|
||||
activerecord (4.1.16)
|
||||
activemodel (= 4.1.16)
|
||||
activesupport (= 4.1.16)
|
||||
arel (~> 5.0.0)
|
||||
activesupport (4.1.16)
|
||||
i18n (~> 0.6, >= 0.6.9)
|
||||
json (~> 1.7, >= 1.7.7)
|
||||
minitest (~> 5.1)
|
||||
thread_safe (~> 0.1)
|
||||
tzinfo (~> 1.1)
|
||||
addressable (2.7.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
annotate (2.6.10)
|
||||
activerecord (>= 3.2, <= 4.3)
|
||||
rake (~> 10.4)
|
||||
arel (3.0.3)
|
||||
arel (5.0.1.20140414130214)
|
||||
bbcoder (1.0.1)
|
||||
better_errors (1.1.0)
|
||||
coderay (>= 1.0.0)
|
||||
|
@ -55,7 +56,7 @@ GEM
|
|||
bourbon (3.1.8)
|
||||
sass (>= 3.2.0)
|
||||
thor
|
||||
builder (3.0.4)
|
||||
builder (3.2.4)
|
||||
byebug (2.7.0)
|
||||
columnize (~> 0.3)
|
||||
debugger-linecache (~> 1.2)
|
||||
|
@ -66,7 +67,7 @@ GEM
|
|||
capistrano-bundler (1.1.4)
|
||||
capistrano (~> 3.1)
|
||||
sshkit (~> 1.2)
|
||||
capistrano-rails (1.3.1)
|
||||
capistrano-rails (1.4.0)
|
||||
capistrano (~> 3.1)
|
||||
capistrano-bundler (~> 1.1)
|
||||
capistrano-rbenv (2.0.4)
|
||||
|
@ -83,30 +84,29 @@ GEM
|
|||
activesupport (>= 3.2.0)
|
||||
json (>= 1.7)
|
||||
mime-types (>= 1.16)
|
||||
childprocess (0.8.0)
|
||||
childprocess (0.9.0)
|
||||
ffi (~> 1.0, >= 1.0.11)
|
||||
cliver (0.3.2)
|
||||
codeclimate-test-reporter (0.3.0)
|
||||
simplecov (>= 0.7.1, < 1.0.0)
|
||||
coderay (1.1.2)
|
||||
coffee-rails (3.2.2)
|
||||
coffee-rails (4.0.1)
|
||||
coffee-script (>= 2.2.0)
|
||||
railties (~> 3.2.0)
|
||||
railties (>= 4.0.0, < 5.0)
|
||||
coffee-script (2.4.1)
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.12.2)
|
||||
columnize (0.9.0)
|
||||
concurrent-ruby (1.0.5)
|
||||
countries (2.1.2)
|
||||
i18n_data (~> 0.8.0)
|
||||
money (~> 6.9)
|
||||
concurrent-ruby (1.1.6)
|
||||
countries (3.0.1)
|
||||
i18n_data (~> 0.10.0)
|
||||
sixarm_ruby_unaccent (~> 1.1)
|
||||
unicode_utils (~> 1.4)
|
||||
country_select (3.1.1)
|
||||
countries (~> 2.0)
|
||||
country_select (4.0.0)
|
||||
countries (~> 3.0)
|
||||
sort_alphabetical (~> 1.0)
|
||||
dalli (2.7.6)
|
||||
dalli (2.7.10)
|
||||
database_cleaner (1.2.0)
|
||||
debug_inspector (0.0.3)
|
||||
debugger-linecache (1.2.0)
|
||||
|
@ -128,7 +128,7 @@ GEM
|
|||
railties (>= 3.0.0)
|
||||
faraday (0.9.2)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
ffi (1.9.18)
|
||||
ffi (1.12.2)
|
||||
font-awesome-sass (4.1.0)
|
||||
sass (~> 3.2)
|
||||
google-api-client (0.10.3)
|
||||
|
@ -150,15 +150,20 @@ GEM
|
|||
signet (~> 0.7)
|
||||
haml (4.0.7)
|
||||
tilt
|
||||
hike (1.2.3)
|
||||
httpclient (2.8.3)
|
||||
hurley (0.2)
|
||||
i18n (0.9.1)
|
||||
i18n (0.9.5)
|
||||
concurrent-ruby (~> 1.0)
|
||||
i18n-js (3.0.11)
|
||||
i18n (>= 0.6.6, < 2)
|
||||
i18n_data (0.8.0)
|
||||
journey (1.0.4)
|
||||
i18n-country-translations (1.3.0)
|
||||
i18n (~> 0.9.3)
|
||||
railties (~> 4.0)
|
||||
i18n-js (3.6.0)
|
||||
i18n (>= 0.6.6)
|
||||
i18n_country_select (1.2.1)
|
||||
i18n (~> 0.9.3)
|
||||
i18n-country-translations (~> 1.0, >= 1.3.0)
|
||||
unicode_utils (~> 1.0, >= 1.0.0)
|
||||
i18n_data (0.10.0)
|
||||
jquery-rails (2.0.3)
|
||||
railties (>= 3.1.0, < 5.0)
|
||||
thor (~> 0.14)
|
||||
|
@ -168,25 +173,26 @@ GEM
|
|||
logging (2.2.2)
|
||||
little-plugger (~> 1.1)
|
||||
multi_json (~> 1.10)
|
||||
mail (2.5.5)
|
||||
mime-types (~> 1.16)
|
||||
treetop (~> 1.4.8)
|
||||
memoist (0.16.0)
|
||||
method_source (0.9.0)
|
||||
mime-types (1.25.1)
|
||||
mail (2.7.1)
|
||||
mini_mime (>= 0.1.1)
|
||||
memoist (0.16.2)
|
||||
method_source (0.9.2)
|
||||
mime-types (3.3.1)
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2019.1009)
|
||||
mini_mime (1.0.2)
|
||||
mini_portile2 (2.4.0)
|
||||
money (6.10.0)
|
||||
i18n (>= 0.6.4, < 1.0)
|
||||
multi_json (1.12.2)
|
||||
minitest (5.14.0)
|
||||
multi_json (1.14.1)
|
||||
multi_xml (0.6.0)
|
||||
multipart-post (2.0.0)
|
||||
multipart-post (2.1.1)
|
||||
mysql2 (0.3.21)
|
||||
neat (1.6.0)
|
||||
bourbon (>= 3.1)
|
||||
sass (>= 3.3)
|
||||
net-scp (1.2.1)
|
||||
net-ssh (>= 2.6.5)
|
||||
net-ssh (4.2.0)
|
||||
net-scp (2.0.0)
|
||||
net-ssh (>= 2.6.5, < 6.0.0)
|
||||
net-ssh (5.2.0)
|
||||
newrelic_rpm (3.13.0.299)
|
||||
nokogiri (1.9.1)
|
||||
mini_portile2 (~> 2.4.0)
|
||||
|
@ -197,52 +203,54 @@ GEM
|
|||
cliver (~> 0.3.1)
|
||||
multi_json (~> 1.0)
|
||||
websocket-driver (>= 0.2.0)
|
||||
polyglot (0.3.5)
|
||||
power_assert (1.1.1)
|
||||
pry (0.11.3)
|
||||
power_assert (1.1.6)
|
||||
protected_attributes (1.1.4)
|
||||
activemodel (>= 4.0.1, < 5.0)
|
||||
pry (0.12.2)
|
||||
coderay (~> 1.1.0)
|
||||
method_source (~> 0.9.0)
|
||||
pry-byebug (1.3.3)
|
||||
byebug (~> 2.7)
|
||||
pry (~> 0.10)
|
||||
public_suffix (3.0.1)
|
||||
public_suffix (3.1.1)
|
||||
puma (2.11.3)
|
||||
rack (>= 1.1, < 2.0)
|
||||
quiet_assets (1.0.3)
|
||||
railties (>= 3.1, < 5.0)
|
||||
rack (1.4.7)
|
||||
rack-cache (1.7.1)
|
||||
rack (>= 0.4)
|
||||
rack-ssl (1.3.4)
|
||||
rack
|
||||
rack (1.5.5)
|
||||
rack-test (0.6.3)
|
||||
rack (>= 1.0)
|
||||
rails (3.2.22.5)
|
||||
actionmailer (= 3.2.22.5)
|
||||
actionpack (= 3.2.22.5)
|
||||
activerecord (= 3.2.22.5)
|
||||
activeresource (= 3.2.22.5)
|
||||
activesupport (= 3.2.22.5)
|
||||
bundler (~> 1.0)
|
||||
railties (= 3.2.22.5)
|
||||
rails (4.1.16)
|
||||
actionmailer (= 4.1.16)
|
||||
actionpack (= 4.1.16)
|
||||
actionview (= 4.1.16)
|
||||
activemodel (= 4.1.16)
|
||||
activerecord (= 4.1.16)
|
||||
activesupport (= 4.1.16)
|
||||
bundler (>= 1.3.0, < 2.0)
|
||||
railties (= 4.1.16)
|
||||
sprockets-rails (~> 2.0)
|
||||
rails_autolink (1.1.6)
|
||||
rails (> 3.1)
|
||||
railties (3.2.22.5)
|
||||
actionpack (= 3.2.22.5)
|
||||
activesupport (= 3.2.22.5)
|
||||
rack-ssl (~> 1.3.2)
|
||||
railties (4.1.16)
|
||||
actionpack (= 4.1.16)
|
||||
activesupport (= 4.1.16)
|
||||
rake (>= 0.8.7)
|
||||
rdoc (~> 3.4)
|
||||
thor (>= 0.14.6, < 2.0)
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
rake (10.5.0)
|
||||
rdoc (3.12.2)
|
||||
json (~> 1.4)
|
||||
rb-fsevent (0.10.3)
|
||||
rb-inotify (0.10.1)
|
||||
ffi (~> 1.0)
|
||||
representable (3.0.4)
|
||||
declarative (< 0.1.0)
|
||||
declarative-option (< 0.2.0)
|
||||
uber (< 0.2.0)
|
||||
retriable (3.1.1)
|
||||
retriable (3.1.2)
|
||||
rmagick (2.13.4)
|
||||
rspec (3.3.0)
|
||||
rspec-core (~> 3.3.0)
|
||||
rspec-expectations (~> 3.3.0)
|
||||
rspec-mocks (~> 3.3.0)
|
||||
rspec-core (3.3.2)
|
||||
rspec-support (~> 3.3.0)
|
||||
rspec-expectations (3.3.1)
|
||||
|
@ -260,20 +268,26 @@ GEM
|
|||
rspec-mocks (~> 3.3.0)
|
||||
rspec-support (~> 3.3.0)
|
||||
rspec-support (3.3.0)
|
||||
rubyzip (1.2.1)
|
||||
sanitize (2.1.0)
|
||||
rubyzip (1.3.0)
|
||||
sanitize (2.1.1)
|
||||
nokogiri (>= 1.4.4)
|
||||
sass (3.3.14)
|
||||
sass-rails (3.2.6)
|
||||
railties (~> 3.2.0)
|
||||
sass (>= 3.1.10)
|
||||
tilt (~> 1.3)
|
||||
selenium-webdriver (2.41.0)
|
||||
childprocess (>= 0.5.0)
|
||||
sass (3.7.4)
|
||||
sass-listen (~> 4.0.0)
|
||||
sass-listen (4.0.0)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
sass-rails (5.0.7)
|
||||
railties (>= 4.0.0, < 6)
|
||||
sass (~> 3.1)
|
||||
sprockets (>= 2.8, < 4.0)
|
||||
sprockets-rails (>= 2.0, < 4.0)
|
||||
tilt (>= 1.1, < 3)
|
||||
selenium-webdriver (2.47.1)
|
||||
childprocess (~> 0.5)
|
||||
multi_json (~> 1.0)
|
||||
rubyzip (~> 1.0)
|
||||
websocket (~> 1.0.4)
|
||||
signet (0.8.1)
|
||||
websocket (~> 1.0)
|
||||
signet (0.11.0)
|
||||
addressable (~> 2.3)
|
||||
faraday (~> 0.9)
|
||||
jwt (>= 1.5, < 3.0)
|
||||
|
@ -285,34 +299,31 @@ GEM
|
|||
sixarm_ruby_unaccent (1.2.0)
|
||||
sort_alphabetical (1.1.0)
|
||||
unicode_utils (>= 1.2.2)
|
||||
sprockets (2.2.3)
|
||||
hike (~> 1.2)
|
||||
multi_json (~> 1.0)
|
||||
rack (~> 1.0)
|
||||
tilt (~> 1.1, != 1.3.0)
|
||||
sshkit (1.15.1)
|
||||
sprockets (3.7.2)
|
||||
concurrent-ruby (~> 1.0)
|
||||
rack (> 1, < 3)
|
||||
sprockets-rails (2.3.3)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
sprockets (>= 2.8, < 4.0)
|
||||
sshkit (1.21.0)
|
||||
net-scp (>= 1.1.2)
|
||||
net-ssh (>= 2.8.0)
|
||||
test-unit (3.1.9)
|
||||
power_assert
|
||||
thor (0.20.0)
|
||||
tilt (1.4.1)
|
||||
thor (0.20.3)
|
||||
thread_safe (0.3.6)
|
||||
tilt (2.0.10)
|
||||
timecop (0.7.4)
|
||||
tinymce-rails (3.5.11.1)
|
||||
railties (>= 3.1.1)
|
||||
treetop (1.4.15)
|
||||
polyglot
|
||||
polyglot (>= 0.3.1)
|
||||
tzinfo (0.3.53)
|
||||
tzinfo (1.2.6)
|
||||
thread_safe (~> 0.1)
|
||||
uber (0.1.0)
|
||||
uglifier (2.5.3)
|
||||
execjs (>= 0.3.0)
|
||||
json (>= 1.8.0)
|
||||
unicode_utils (1.4.0)
|
||||
<<<<<<< Updated upstream
|
||||
websocket (1.0.7)
|
||||
websocket-driver (0.7.0)
|
||||
=======
|
||||
web-console (2.3.0)
|
||||
activemodel (>= 4.0)
|
||||
binding_of_caller (>= 0.7.2)
|
||||
|
@ -320,9 +331,8 @@ GEM
|
|||
sprockets-rails (>= 2.0, < 4.0)
|
||||
websocket (1.2.8)
|
||||
websocket-driver (0.7.1)
|
||||
>>>>>>> Stashed changes
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.3)
|
||||
websocket-extensions (0.1.4)
|
||||
will_paginate (3.0.12)
|
||||
xpath (2.1.0)
|
||||
nokogiri (~> 1.3)
|
||||
|
@ -332,6 +342,7 @@ PLATFORMS
|
|||
|
||||
DEPENDENCIES
|
||||
active_link_to (~> 1.0.2)
|
||||
active_record_union
|
||||
annotate (~> 2.6.2)
|
||||
bbcoder (~> 1.0.1)
|
||||
better_errors (~> 1.1.0)
|
||||
|
@ -345,7 +356,7 @@ DEPENDENCIES
|
|||
capybara (~> 2.4.4)
|
||||
carrierwave (~> 0.10.0)
|
||||
codeclimate-test-reporter (~> 0.3.0)
|
||||
coffee-rails (~> 3.2.2)
|
||||
coffee-rails (~> 4.0.0)
|
||||
country_select
|
||||
dalli (~> 2.7.0)
|
||||
database_cleaner (~> 1.2.0)
|
||||
|
@ -358,26 +369,29 @@ DEPENDENCIES
|
|||
google-api-client (~> 0.10.3)
|
||||
haml (~> 4.0.5)
|
||||
i18n-js
|
||||
i18n_country_select
|
||||
jquery-rails (~> 2.0.2)
|
||||
mysql2 (~> 0.3.17)
|
||||
mysql2 (~> 0.3.18)
|
||||
neat (~> 1.6.0)
|
||||
newrelic_rpm (~> 3.13.0.299)
|
||||
nokogiri (~> 1.9.0)
|
||||
oj (~> 2.5.5)
|
||||
poltergeist (~> 1.6.0)
|
||||
protected_attributes (~> 1.1.3)
|
||||
pry-byebug (~> 1.3.2)
|
||||
public_suffix (~> 3.1.1)
|
||||
puma (~> 2.11.1)
|
||||
quiet_assets (~> 1.0.2)
|
||||
rails (~> 3.2.22)
|
||||
rails (~> 4.1.16)
|
||||
rails_autolink (~> 1.1.5)
|
||||
rmagick (~> 2.13.4)
|
||||
rspec
|
||||
rspec-rails (~> 3.3.3)
|
||||
sanitize (~> 2.1.0)
|
||||
sass (~> 3.3.4)
|
||||
sass-rails (~> 3.2.6)
|
||||
selenium-webdriver (~> 2.41.0)
|
||||
sass-rails (~> 5.0.3)
|
||||
selenium-webdriver (~> 2.47.1)
|
||||
signet (= 0.11.0)
|
||||
simplecov (~> 0.7.1)
|
||||
sprockets (~> 2.2.1)
|
||||
steam-condenser!
|
||||
test-unit (~> 3.1.3)
|
||||
timecop (~> 0.7.1)
|
||||
|
|
37
Makefile.dev
Normal file
37
Makefile.dev
Normal file
|
@ -0,0 +1,37 @@
|
|||
#REGISTRY ?= ensl
|
||||
PROJECT ?= ensl-plugin
|
||||
TAG ?= latest
|
||||
|
||||
.PHONY: all test clean build
|
||||
|
||||
ifdef REGISTRY
|
||||
IMAGE=$(REGISTRY)/$(PROJECT):$(TAG)
|
||||
else
|
||||
IMAGE=$(PROJECT)
|
||||
endif
|
||||
|
||||
all:
|
||||
@echo "Available targets:"
|
||||
@echo " * build - build a Docker image for $(IMAGE)"
|
||||
@echo " * pull - pull $(IMAGE)"
|
||||
@echo " * push - push $(IMAGE)"
|
||||
@echo " * test - build and test $(IMAGE)"
|
||||
|
||||
build:
|
||||
docker-compose build -f docker-compose.dev.yml
|
||||
|
||||
run: build
|
||||
docker-compose up -f docker-compose.dev.yml
|
||||
|
||||
pull:
|
||||
docker pull $(IMAGE) || true
|
||||
|
||||
push:
|
||||
docker push $(IMAGE)
|
||||
|
||||
clean:
|
||||
docker ps -a | awk '{ print $$1,$$2 }' | grep $(IMAGE) |awk '{print $$1 }' |xargs -I {} docker rm {}
|
||||
docker images -a |grep $(IMAGE) |awk '{print $$3}' |xargs -I {} docker rmi {}
|
||||
|
||||
test: build
|
||||
@echo "TODO"
|
|
@ -32,6 +32,12 @@ $(function() {
|
|||
$(this).scrollTop(scrollTop-Math.round(delta));
|
||||
});
|
||||
|
||||
|
||||
// Forums fast reply
|
||||
$("a#fastReply").live('click', function() {
|
||||
$('#reply').fadeIn('slow')
|
||||
});
|
||||
|
||||
// Gather stuff
|
||||
|
||||
$("a#gather-info-hide").live('click', function() {
|
||||
|
|
|
@ -10,9 +10,9 @@ class ContestsController < ApplicationController
|
|||
def historical
|
||||
case params[:id]
|
||||
when "NS1"
|
||||
@contests = Contest.with_contesters.ordered.where ["name LIKE ? OR name LIKE ?", "S%:%", "%Night%"]
|
||||
@contests = Contest.all.ordered.includes(:contesters).where("name LIKE ? OR name LIKE ?", "S%:%", "%Night%")
|
||||
else
|
||||
@contests = Contest.with_contesters.ordered.where ["id > ?", "113"]
|
||||
@contests = Contest.all.ordered.includes(:contesters).where("id > ?", "113")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -16,9 +16,9 @@ class IssuesController < ApplicationController
|
|||
qstring = 'category_id IN (?)'
|
||||
qstring += ' OR category_id IS NULL' if cuser.admin?
|
||||
|
||||
@open = Issue.where(qstring, allowed).with_status(Issue::STATUS_OPEN).all order: sort
|
||||
@solved = Issue.where(qstring, allowed).with_status(Issue::STATUS_SOLVED).all order: sort
|
||||
@rejected = Issue.where(qstring, allowed).with_status(Issue::STATUS_REJECTED).all order: sort
|
||||
@open = Issue.where(qstring, allowed).with_status(Issue::STATUS_OPEN).order(sort)
|
||||
@solved = Issue.where(qstring, allowed).with_status(Issue::STATUS_SOLVED).order(sort)
|
||||
@rejected = Issue.where(qstring, allowed).with_status(Issue::STATUS_REJECTED).order(sort)
|
||||
end
|
||||
|
||||
def show
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
class ShoutmsgsController < ApplicationController
|
||||
respond_to :html, :js
|
||||
|
||||
<<<<<<< Updated upstream
|
||||
=======
|
||||
def index
|
||||
@shoutmsgs = Shoutmsg.typebox
|
||||
@shoutmsgs = Shoutmsg.last.typebox
|
||||
end
|
||||
|
||||
>>>>>>> Stashed changes
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
class TeamersController < ApplicationController
|
||||
def index
|
||||
end
|
||||
|
||||
def create
|
||||
@old_application = (cuser.teamers.joining.count == 0) ? nil : cuser.teamers.joining.first
|
||||
@teamer = Teamer.new params[:teamer]
|
||||
|
|
|
@ -2,7 +2,7 @@ class TeamsController < ApplicationController
|
|||
before_filter :get_team, only: [:show, :edit, :update, :destroy, :recover]
|
||||
|
||||
def index
|
||||
@teams = Team.with_teamers_num(0).search(params[:search]).paginate(per_page: 80, page: params[:page]).ordered
|
||||
@teams = Team.search(params[:search]).paginate(per_page: 80, page: params[:page]).ordered
|
||||
end
|
||||
|
||||
def show
|
||||
|
@ -15,7 +15,7 @@ class TeamsController < ApplicationController
|
|||
raise AccessError unless @team.can_create? cuser
|
||||
end
|
||||
|
||||
def replace_teamer
|
||||
def replace_teamer
|
||||
redirect_to_back
|
||||
end
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ module ApplicationHelper
|
|||
when "Comment"
|
||||
model.commentable
|
||||
when "Post"
|
||||
model.topic
|
||||
model.topic
|
||||
else
|
||||
model
|
||||
end
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
# text_coding :integer default(0), not null
|
||||
#
|
||||
|
||||
require File.join(Rails.root, 'vendor', 'plugins', 'has_view_count', 'init.rb')
|
||||
|
||||
class Article < ActiveRecord::Base
|
||||
include Exceptions
|
||||
include Extra
|
||||
|
@ -38,26 +36,26 @@ class Article < ActiveRecord::Base
|
|||
|
||||
attr_protected :id, :updated_at, :created_at, :user_id, :version
|
||||
|
||||
scope :recent, order: 'created_at DESC', limit: 8
|
||||
scope :with_comments,
|
||||
select: "articles.*, COUNT(C.id) AS comment_num",
|
||||
joins: "LEFT JOIN comments C ON C.commentable_type = 'Article' AND C.commentable_id = articles.id",
|
||||
group: "articles.id"
|
||||
scope :ordered, order: 'articles.created_at DESC'
|
||||
scope :limited, limit: 5
|
||||
scope :nodrafts, conditions: { status: STATUS_PUBLISHED }
|
||||
scope :drafts, conditions: { status: STATUS_DRAFT }
|
||||
scope :articles, conditions: ["category_id IN (SELECT id FROM categories WHERE domain = ?)", Category::DOMAIN_ARTICLES]
|
||||
scope :onlynews, conditions: ["category_id IN (SELECT id FROM categories WHERE domain = ?)", Category::DOMAIN_NEWS]
|
||||
scope :category, lambda { |cat| { conditions: { category_id: cat } } }
|
||||
scope :domain, lambda { |domain| { includes: 'category', conditions: { "categories.domain" => domain } } }
|
||||
scope :nospecial, conditions: ["category_id != ?", Category::SPECIAL]
|
||||
scope :interviews, conditions: ["category_id = ?", Category::INTERVIEWS]
|
||||
scope :recent, -> { order('created_at DESC').limit(8) }
|
||||
scope :with_comments, -> {
|
||||
select("articles.*, COUNT(C.id) AS comment_num").
|
||||
joins("LEFT JOIN comments C ON C.commentable_type = 'Article' AND C.commentable_id = articles.id").
|
||||
group("articles.id") }
|
||||
scope :ordered, -> { order('articles.created_at DESC') }
|
||||
scope :limited, -> { limit(5) }
|
||||
scope :nodrafts, -> { where(status: STATUS_PUBLISHED) }
|
||||
scope :drafts, -> { where(status: STATUS_DRAFT) }
|
||||
scope :articles, -> { where(["category_id IN (SELECT id FROM categories WHERE domain = ?)", Category::DOMAIN_ARTICLES]) }
|
||||
scope :onlynews, -> { where(category_id: Category.select(:id).where.not(domain: Category::DOMAIN_NEWS)) }
|
||||
scope :category, -> (cat) { where(category_id: cat) }
|
||||
scope :domain, -> (domain) { includes(:category).where("categories.domain = '?'", domain) }
|
||||
#scope :nospecial, -> { where("category_id != ?", Category::SPECIAL) }
|
||||
scope :interviews, -> { where(category_id: Category::INTERVIEWS) }
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :category
|
||||
has_many :comments, as: :commentable, order: 'created_at ASC', dependent: :destroy
|
||||
has_many :files, class_name: 'DataFile', order: 'created_at DESC', dependent: :destroy
|
||||
has_many :comments, as: :commentable, dependent: :destroy
|
||||
has_many :files, class_name: 'DataFile', dependent: :destroy
|
||||
|
||||
validates_length_of :title, :in => 1..50
|
||||
validates_length_of :text, :in => 1..16000000
|
||||
|
@ -83,7 +81,7 @@ class Article < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def previous_article
|
||||
category.articles.nodrafts.first(conditions: ["id < ?", self.id], order: "id DESC")
|
||||
category.articles.nodrafts.first.where("id < ?", self.id).order("id DESC")
|
||||
end
|
||||
|
||||
def next_article
|
||||
|
|
|
@ -29,9 +29,9 @@ class Ban < ActiveRecord::Base
|
|||
attr_protected :id, :created_at, :updated_at
|
||||
attr_accessor :len, :user_name
|
||||
|
||||
scope :ordered, order: "created_at DESC"
|
||||
scope :effective, conditions: "expiry > UTC_TIMESTAMP()"
|
||||
scope :ineffective, conditions: "expiry < UTC_TIMESTAMP()"
|
||||
scope :ordered, -> {order("created_at DESC")}
|
||||
scope :effective, -> {where("expiry > UTC_TIMESTAMP()")}
|
||||
scope :ineffective, -> {where("expiry < UTC_TIMESTAMP()")}
|
||||
|
||||
before_validation :check_user
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ class Bracketer < ActiveRecord::Base
|
|||
belongs_to :match
|
||||
belongs_to :contester, :foreign_key => "team_id"
|
||||
|
||||
scope :pos, lambda { |row, col| {:conditions => {"row" => row, "column" => col}} }
|
||||
scope :pos, -> (row, col) { where(row: row, column: col) }
|
||||
|
||||
def to_s
|
||||
if self.match_id
|
||||
|
|
|
@ -33,16 +33,16 @@ class Category < ActiveRecord::Base
|
|||
validates_length_of :name, :in => 1..30
|
||||
validate :validate_domain
|
||||
|
||||
scope :ordered, :order => "sort ASC, created_at DESC"
|
||||
scope :domain, lambda { |domain| {:conditions => {:domain => domain}} }
|
||||
scope :nospecial, :conditions => ["name != 'Special'"]
|
||||
scope :newest, :include => :articles, :order => "articles.created_at DESC"
|
||||
scope :page, lambda { |page| {:limit => "#{(page-1)*PER_PAGE}, #{(page-1)*PER_PAGE+PER_PAGE}"} }
|
||||
scope :of_user, lambda { |user| {:conditions => {"articles.user_id" => user.id}, :include => :articles} }
|
||||
scope :ordered, -> { order("sort ASC, created_at DESC") }
|
||||
scope :domain, -> (domain) { where(domain: domain) }
|
||||
scope :nospecial, -> { where.not(name: 'Special') }
|
||||
scope :newest, -> { includes(:articles).order("articles.created_at DESC") }
|
||||
# scope :page, lambda { |page| {:limit => "#{(page-1)*PER_PAGE}, #{(page-1)*PER_PAGE+PER_PAGE}"} }
|
||||
scope :of_user, -> (user) { where("articles.user_id", user.id).includes(:articles) }
|
||||
|
||||
has_many :articles, :order => "created_at DESC"
|
||||
has_many :issues, :order => "created_at DESC"
|
||||
has_many :forums, :order => "forums.position"
|
||||
has_many :articles, -> { order("created_at DESC") }
|
||||
has_many :issues, -> { order("created_at DESC") }
|
||||
has_many :forums, -> { order("forums.position") }
|
||||
has_many :movies
|
||||
has_many :maps
|
||||
has_many :gathers
|
||||
|
|
|
@ -67,8 +67,8 @@ class Challenge < ActiveRecord::Base
|
|||
belongs_to :map2, :class_name => "Map"
|
||||
belongs_to :user
|
||||
belongs_to :server
|
||||
belongs_to :contester1, :class_name => "Contester", :include => 'team'
|
||||
belongs_to :contester2, :class_name => "Contester", :include => 'team'
|
||||
belongs_to :contester1, :class_name => "Contester"
|
||||
belongs_to :contester2, :class_name => "Contester"
|
||||
|
||||
def statuses
|
||||
{STATUS_PENDING => "Pending response",
|
||||
|
|
|
@ -17,12 +17,11 @@ class Comment < ActiveRecord::Base
|
|||
|
||||
attr_protected :id, :updated_at, :created_at, :user_id
|
||||
|
||||
scope :with_userteam, :include => {:user => :team}
|
||||
scope :recent, :order => "id DESC", :limit => 10
|
||||
scope :recent3, :order => "id DESC", :limit => 3
|
||||
scope :recent5, :order => "id DESC", :limit => 5, :group => "commentable_id, commentable_type"
|
||||
scope :filtered, :conditions => ["commentable_type != 'Issue'"]
|
||||
scope :ordered, :order => "id ASC"
|
||||
scope :with_userteam, -> { includes({:user => :team}) }
|
||||
scope :recent, -> (n) { order("id DESC").limit(n) }
|
||||
scope :recent5, -> { order("id DESC").limit(5).group("commentable_id, commentable_type") }
|
||||
scope :filtered, -> { where.not({"commentable_type" => 'Issue'}) }
|
||||
scope :ordered, -> { order("id ASC") }
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :commentable, :polymorphic => true
|
||||
|
|
|
@ -35,30 +35,30 @@ class Contest < ActiveRecord::Base
|
|||
|
||||
attr_protected :id, :updated_at, :created_at
|
||||
|
||||
scope :active, :conditions => ["status != ?", STATUS_CLOSED]
|
||||
scope :inactive, :conditions => {:status => STATUS_CLOSED}
|
||||
scope :joinable, :conditions => {:status => STATUS_OPEN}
|
||||
scope :with_contesters, :include => :contesters
|
||||
scope :ordered, :order => "start DESC"
|
||||
scope :nsls1, :conditions => ["name LIKE ?", "NSL S1:%"]
|
||||
scope :nsls2, :conditions => ["name LIKE ?", "NSL S2:%"]
|
||||
scope :ns1seasons, :conditions => ["name LIKE ?", "S%:%"]
|
||||
scope :active, -> { where.not(status: STATUS_CLOSED) }
|
||||
scope :inactive, -> { where(status: STATUS_CLOSED) }
|
||||
scope :joinable, -> { where(status: STATUS_OPEN) }
|
||||
scope :with_contesters, -> { includes(:contesters) }
|
||||
scope :ordered, -> { order("start DESC") }
|
||||
scope :nsls1, -> { where("name LIKE ?", "NSL S1:%") }
|
||||
scope :nsls2, -> { where("name LIKE ?", "NSL S2:%") }
|
||||
scope :ns1seasons, -> { where("name LIKE ?", "S%:%") }
|
||||
|
||||
has_many :matches, :dependent => :destroy
|
||||
has_many :weeks, :dependent => :destroy
|
||||
has_many :contesters, :dependent => :destroy, :include => :team
|
||||
has_many :contesters, -> { includes(:team) }, :dependent => :destroy
|
||||
has_many :predictions, :through => :matches
|
||||
has_many :brackets
|
||||
has_many :preds_with_score,
|
||||
:source => :predictions,
|
||||
:through => :matches,
|
||||
:select => "predictions.id, predictions.user_id,
|
||||
SUM(result) AS correct,
|
||||
SUM(result)/COUNT(*)*100 AS score,
|
||||
COUNT(*) AS total",
|
||||
:conditions => "result IS NOT NULL",
|
||||
:group => "predictions.user_id",
|
||||
:order => "correct DESC"
|
||||
has_many :preds_with_score, -> {
|
||||
select("predictions.id, predictions.user_id
|
||||
SUM(result) AS correct,
|
||||
SUM(result)/COUNT(*)*100 AS score,
|
||||
COUNT(*) AS total")
|
||||
.where("result IS NOT NULL")
|
||||
.group("predictions.user_id")
|
||||
.order("correct DESC") },
|
||||
:source => :predictions,
|
||||
:through => :matches
|
||||
has_and_belongs_to_many :maps
|
||||
belongs_to :demos, :class_name => "Directory"
|
||||
belongs_to :winner, :class_name => "Contester"
|
||||
|
|
|
@ -26,22 +26,24 @@ class Contester < ActiveRecord::Base
|
|||
attr_protected :id, :updated_at, :created_at, :trend
|
||||
attr_accessor :user
|
||||
|
||||
scope :active, :include => :team, :conditions => {"contesters.active" => true}
|
||||
belongs_to :team
|
||||
belongs_to :contest
|
||||
|
||||
scope :active, -> { includes(:team).where(active: true) }
|
||||
# ranked is used for ladder. lower score the higher the rank
|
||||
scope :ranked, :select => "contesters.*", :order => "score ASC, win ASC, win + draw + loss DESC"
|
||||
scope :ordered, :select => "contesters.*, (score + extra) AS total_score", :order => "total_score DESC, score DESC, win DESC, loss ASC"
|
||||
scope :chronological, :order => "created_at DESC"
|
||||
scope :of_contest, lambda { |contest| {:conditions => {"contesters.contest_id" => contest.id}} }
|
||||
scope :ranked, -> { order("score ASC, win DESC, loss ASC").select("contesters.*") }
|
||||
scope :ordered, -> { select("contesters.*, (score + extra) AS total_score").order("total_score DESC, score DESC, win DESC, loss ASC") }
|
||||
scope :chronological, -> { order("created_at DESC") }
|
||||
scope :of_contest, -> (contest) { where("contesters.contest_id", contest.id) }
|
||||
|
||||
has_many :challenges_sent, :class_name => "Challenge", :foreign_key => "contester1_id"
|
||||
has_many :challenges_received, :class_name => "Challenge", :foreign_key => "contester2_id"
|
||||
has_many :matches, :through => :contest, :conditions => "(contester1_id = contesters.id OR contester2_id = contesters.id)"
|
||||
belongs_to :team
|
||||
belongs_to :contest
|
||||
has_many :matches, -> { where("(contester1_id = contesters.id OR contester2_id = contesters.id)") }, :through => :contest
|
||||
|
||||
validates_presence_of :team, :contest
|
||||
validates_inclusion_of [:score, :win, :loss, :draw, :extra], :in => 0..9999, :allow_nil => true
|
||||
validates_uniqueness_of :team_id, :scope => :contest_id, :message => "You can't join same contest twice."
|
||||
|
||||
#validate_on_create:validate_member_participation
|
||||
validate :validate_contest, :on => :create
|
||||
#validate_on_create:validate_playernumber
|
||||
|
@ -95,7 +97,7 @@ class Contester < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def validate_playernumber
|
||||
if team.teamers.active.distinct.count < 6
|
||||
if team.teamers.active.unique_by_team.count < 6
|
||||
errors.add :team, I18n.t(:contests_join_need6)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
# article_id :integer
|
||||
#
|
||||
|
||||
require File.join(Rails.root, 'vendor', 'plugins', 'acts_as_rateable', 'init.rb')
|
||||
require 'digest/md5'
|
||||
|
||||
class DataFile < ActiveRecord::Base
|
||||
|
@ -26,12 +25,12 @@ class DataFile < ActiveRecord::Base
|
|||
attr_accessor :related_id
|
||||
attr_protected :id, :updated_at, :created_at, :path, :size, :md5
|
||||
|
||||
scope :recent, :order => "created_at DESC", :limit => 8
|
||||
scope :demos, :order => "created_at DESC", :conditions => ["directory_id IN (SELECT id FROM directories WHERE parent_id = ?)", Directory::DEMOS]
|
||||
scope :ordered, :order => "created_at DESC"
|
||||
scope :movies, :order => "created_at DESC", :conditions => {:directory_id => Directory::MOVIES}
|
||||
scope :not, lambda { |file| {:conditions => ["id != ?", file.id]} }
|
||||
scope :unrelated, :conditions => "related_id is null"
|
||||
scope :recent, -> { order("created_at DESC").limit(8) }
|
||||
scope :demos, -> { order("created_at DESC").where("directory_id IN (SELECT id FROM directories WHERE parent_id = ?)", Directory::DEMOS) }
|
||||
scope :ordered, -> { order("created_at DESC") }
|
||||
scope :movies, -> { order("created_at DESC").where({:directory_id => Directory::MOVIES}) }
|
||||
scope :not, -> (file) { where.not(id: file.id) }
|
||||
scope :unrelated, -> { where("related_id is null") }
|
||||
|
||||
has_many :related_files, :class_name => "DataFile", :foreign_key => :related_id
|
||||
has_many :comments, :as => :commentable
|
||||
|
@ -48,7 +47,7 @@ class DataFile < ActiveRecord::Base
|
|||
after_create :create_movie, :if => Proc.new {|file| file.directory_id == Directory::MOVIES and !file.location.include?("_preview.mp4") }
|
||||
after_save :update_relations, :if => Proc.new { |file| file.related_id_changed? and related_files.count > 0 }
|
||||
|
||||
acts_as_rateable
|
||||
# acts_as_rateable
|
||||
mount_uploader :name, FileUploader
|
||||
|
||||
def to_s
|
||||
|
|
|
@ -26,11 +26,11 @@ class Directory < ActiveRecord::Base
|
|||
|
||||
belongs_to :parent, :class_name => "Directory"
|
||||
has_many :subdirs, :class_name => "Directory", :foreign_key => :parent_id
|
||||
has_many :files, :class_name => "DataFile", :order => "name"
|
||||
has_many :files, -> { order("name") }, :class_name => "DataFile"
|
||||
|
||||
scope :ordered, :order => "name ASC"
|
||||
scope :filtered, :conditions => {:hidden => false}
|
||||
scope :of_parent, lambda { |parent| {:conditions => {:parent_id => parent.id}} }
|
||||
scope :ordered, -> { order("name ASC") }
|
||||
scope :filtered, -> { where(hidden: true) }
|
||||
scope :of_parent, -> (parent) { where(parent_id: parent.id) }
|
||||
|
||||
validates_length_of [:name, :path], :in => 1..255
|
||||
validates_format_of :name, :with => /\A[A-Za-z0-9]{1,20}\z/, :on => :create
|
||||
|
|
|
@ -19,13 +19,11 @@ class Forum < ActiveRecord::Base
|
|||
|
||||
attr_protected :id, :updated_at, :created_at
|
||||
|
||||
scope :public,
|
||||
:select => "forums.*",
|
||||
:joins => "LEFT JOIN forumers ON forumers.forum_id = forums.id AND forumers.access = #{Forumer::ACCESS_READ}",
|
||||
:conditions => "forumers.id IS NULL"
|
||||
scope :of_forum,
|
||||
lambda { |forum| {:conditions => {"forums.id" => forum.id}} }
|
||||
scope :ordered, :order => "position"
|
||||
scope :public_forums, -> { select("forums.*")
|
||||
.joins("LEFT JOIN forumers ON forumers.forum_id = forums.id AND forumers.access = #{Forumer::ACCESS_READ}")
|
||||
.where("forumers.id IS NULL") }
|
||||
scope :of_forum, -> (forum) { where("forums.id", forum.id) }
|
||||
scope :ordered, -> { order("position") }
|
||||
|
||||
has_many :topics
|
||||
has_many :posts, :through => :topics
|
||||
|
@ -50,7 +48,7 @@ class Forum < ActiveRecord::Base
|
|||
if cuser
|
||||
Forum.available_to(cuser, Forumer::ACCESS_READ).of_forum(self).first
|
||||
else
|
||||
Forum.public.of_forum(self).first
|
||||
Forum.public_forums.where(id: self.id).exists?
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -77,7 +75,7 @@ class Forum < ActiveRecord::Base
|
|||
is_admin = Grouper.where(user_id: cuser, group_id: Group::ADMINS)
|
||||
Forum.where("EXISTS (#{is_admin.to_sql}) OR
|
||||
id IN (SELECT q.id from (#{user_has_access.to_sql}) q ) OR
|
||||
id IN (SELECT q.id from (#{Forum.public.to_sql}) q )")
|
||||
id IN (SELECT q.id from (#{Forum.public_forums.to_sql}) q )")
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -29,12 +29,11 @@ class Gather < ActiveRecord::Base
|
|||
|
||||
attr_accessor :admin
|
||||
|
||||
scope :ordered, :order => "id DESC"
|
||||
scope :basic, :include => [:captain1, :captain2, :map1, :map2, :server]
|
||||
scope :active,
|
||||
:conditions => ["gathers.status IN (?, ?, ?) AND gathers.updated_at > ?",
|
||||
STATE_VOTING, STATE_PICKING, STATE_RUNNING, 12.hours.ago.utc]
|
||||
|
||||
scope :ordered, -> { order("id DESC") }
|
||||
scope :basic, -> { includes(:captain1, :captain2, :map1, :map2, :server) }
|
||||
scope :active, -> { where("gathers.status IN (?, ?, ?) AND gathers.updated_at > ?",
|
||||
STATE_VOTING, STATE_PICKING, STATE_RUNNING, 12.hours.ago.utc) }
|
||||
|
||||
belongs_to :server
|
||||
belongs_to :captain1, :class_name => "Gatherer"
|
||||
belongs_to :captain2, :class_name => "Gatherer"
|
||||
|
@ -94,11 +93,11 @@ class Gather < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def previous_gather
|
||||
Gather.first(:conditions => ["id < ? AND category_id = ?", self.id, category_id], :order => "id DESC")
|
||||
Gather.first.where("id < ? AND category_id = ?", self.id, category_id).order("id DESC")
|
||||
end
|
||||
|
||||
def next_gather
|
||||
Gather.first(:conditions => ["id > ? AND category_id = ?", self.id, category_id], :order => "id ASC")
|
||||
Gather.first.where("id > ? AND category_id = ?", self.id, category_id).order("id ASC")
|
||||
end
|
||||
|
||||
def last
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#
|
||||
|
||||
class GatherMap < ActiveRecord::Base
|
||||
scope :ordered, :order => "votes DESC, id DESC"
|
||||
scope :ordered, -> { order("votes DESC, id DESC") }
|
||||
|
||||
belongs_to :gather
|
||||
belongs_to :map
|
||||
|
|
|
@ -58,19 +58,12 @@ class Group < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def self.admins
|
||||
admins = []
|
||||
admin_group = where(id: ADMINS).first
|
||||
return admins unless admin_group
|
||||
|
||||
(admin_group.groupers).each do |g|
|
||||
admins << g unless admins.include? g
|
||||
end
|
||||
admins
|
||||
find(ADMINS).groupers.valid_users
|
||||
end
|
||||
|
||||
def self.referees
|
||||
referees = []
|
||||
referee_group = where(id: REFEREES).first
|
||||
referee_group = where(id: REFEREES).firsto
|
||||
return referees unless referee_group
|
||||
|
||||
(referee_group.groupers).each do |g|
|
||||
|
|
|
@ -21,6 +21,8 @@ class Grouper < ActiveRecord::Base
|
|||
validates :group, :user, :presence => true
|
||||
validates :task, :length => {:maximum => 25}
|
||||
|
||||
scope :valid_users, -> { joins(:user).where.not(users: { id: nil }) }
|
||||
|
||||
before_validation :fetch_user, :if => Proc.new {|grouper| grouper.username and !grouper.username.empty?}
|
||||
|
||||
def to_s
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
# text_parsed :text
|
||||
#
|
||||
|
||||
require File.join(Rails.root, 'vendor', 'plugins', 'acts-as-readable', 'init.rb')
|
||||
|
||||
class Issue < ActiveRecord::Base
|
||||
include Extra
|
||||
|
||||
|
@ -41,7 +39,7 @@ class Issue < ActiveRecord::Base
|
|||
lambda { |user| {
|
||||
:joins => "LEFT JOIN readings ON readable_type = 'Issue' AND readable_id = issues.id AND readings.user_id = #{user.id}",
|
||||
:conditions => "readings.user_id IS NULL"} }
|
||||
scope :with_status, lambda { |s| { :conditions => {:status => s}} }
|
||||
scope :with_status, -> (s) { where(status: s) }
|
||||
|
||||
validates_length_of :title, :in => 1..50
|
||||
validates_length_of :text, :in => 1..65000
|
||||
|
|
|
@ -38,84 +38,60 @@ class Match < ActiveRecord::Base
|
|||
attr_accessor :lineup, :method, :motm_name, :friendly
|
||||
attr_protected :id, :updated_at, :created_at, :diff, :points1, :points2
|
||||
|
||||
has_many :matchers, dependent: :destroy
|
||||
has_many :users, through: :matchers
|
||||
has_many :predictions, dependent: :destroy
|
||||
has_many :comments, as: :commentable, order: "created_at", dependent: :destroy
|
||||
has_many :match_proposals, inverse_of: :match, dependent: :destroy
|
||||
has_many :matchers, :dependent => :destroy
|
||||
has_many :users, :through => :matchers
|
||||
has_many :predictions, :dependent => :destroy
|
||||
has_many :comments, -> { order("created_at") }, :as => :commentable, :dependent => :destroy
|
||||
belongs_to :challenge
|
||||
belongs_to :contest
|
||||
belongs_to :contester1, class_name: "Contester", include: "team"
|
||||
belongs_to :contester2, class_name: "Contester", include: "team"
|
||||
belongs_to :map1, class_name: "Map"
|
||||
belongs_to :map2, class_name: "Map"
|
||||
belongs_to :contester1, -> { includes('team') }, :class_name => "Contester"
|
||||
belongs_to :contester2, -> { includes('team') }, :class_name => "Contester"
|
||||
belongs_to :map1, :class_name => "Map"
|
||||
belongs_to :map2, :class_name => "Map"
|
||||
belongs_to :server
|
||||
belongs_to :referee, class_name: "User"
|
||||
belongs_to :motm, class_name: "User"
|
||||
belongs_to :demo, class_name: "DataFile"
|
||||
belongs_to :week
|
||||
belongs_to :hltv, class_name: "Server"
|
||||
belongs_to :stream, class_name: "Movie"
|
||||
belongs_to :caster, class_name: "User"
|
||||
belongs_to :hltv, :class_name => "Server"
|
||||
belongs_to :stream, :class_name => "Movie"
|
||||
belongs_to :caster, :class_name => "User"
|
||||
|
||||
scope :future, conditions: ["match_time > UTC_TIMESTAMP()"]
|
||||
scope :future5, conditions: ["match_time > UTC_TIMESTAMP()"], limit: 5
|
||||
scope :finished, conditions: ["score1 != 0 OR score2 != 0"]
|
||||
scope :realfinished, conditions: ["score1 IS NOT NULL AND score2 IS NOT NULL"]
|
||||
scope :unfinished, conditions: ["score1 IS NULL AND score2 IS NULL"]
|
||||
scope :unreffed, conditions: ["referee_id IS NULL"]
|
||||
scope :ordered, order: "match_time DESC"
|
||||
scope :chrono, order: "match_time ASC"
|
||||
scope :recent, limit: "8"
|
||||
scope :bigrecent, limit: "50"
|
||||
scope :active, conditions: ["contest_id IN (?)", Contest.active]
|
||||
scope :on_day,
|
||||
->(day) { where("match_time > ? and match_time < ?", day.beginning_of_day, day.end_of_day) }
|
||||
scope :on_week,
|
||||
lambda { |time|
|
||||
where("match_time > ? and match_time < ?", time.beginning_of_week, time.end_of_week)
|
||||
}
|
||||
scope :of_contester,
|
||||
->contester { where("contester1_id = ? OR contester2_id = ?", contester.id, contester.id) }
|
||||
scope :of_user,
|
||||
->user { includes(:matchers).where("matchers.user_id = ?", user.id) }
|
||||
scope :of_team,
|
||||
lambda { |team|
|
||||
includes(contester1: :team, contester2: :team)
|
||||
.where("teams.id = ? OR teams_contesters.id = ?", team.id, team.id)
|
||||
}
|
||||
scope :of_userteam,
|
||||
lambda { |user, team|
|
||||
includes(matchers: { contester: :team })
|
||||
.where("teams.id = ? AND matchers.user_id = ?", team.id, user.id)
|
||||
}
|
||||
scope :within_time,
|
||||
->(from, to) { where("match_time > ? AND match_time < ?", from.utc, to.utc) }
|
||||
scope :around,
|
||||
lambda { |time|
|
||||
where("match_time > ? AND match_time < ?",
|
||||
time.ago(MATCH_LENGTH).utc, time.ago(-MATCH_LENGTH).utc)
|
||||
}
|
||||
scope :after,
|
||||
->time { where("match_time > ? AND match_time < ?", time.utc, time.ago(-MATCH_LENGTH).utc) }
|
||||
scope :map_stats,
|
||||
select: "map1_id, COUNT(*) as num, maps.name",
|
||||
joins: "LEFT JOIN maps ON maps.id = map1_id",
|
||||
group: "map1_id",
|
||||
having: "map1_id is not null",
|
||||
order: "num DESC"
|
||||
scope :year_stats,
|
||||
select: "id, DATE_FORMAT(match_time, '%Y') as year, COUNT(*) as num",
|
||||
conditions: "match_time > '2000-01-01 01:01:01'",
|
||||
group: "year",
|
||||
order: "num DESC"
|
||||
scope :month_stats,
|
||||
select: "id, DATE_FORMAT(match_time, '%m') as month_n,
|
||||
DATE_FORMAT(match_time, '%M') as month,
|
||||
COUNT(*) as num",
|
||||
conditions: "match_time > '2000-01-01 01:01:01'",
|
||||
group: "month",
|
||||
order: "month_n"
|
||||
scope :future, -> { where("match_time > UTC_TIMESTAMP()") }
|
||||
scope :future5, -> { where("match_time > UTC_TIMESTAMP()").limit(5) }
|
||||
scope :finished, -> { where("score1 != 0 OR score2 != 0") }
|
||||
scope :realfinished, -> { where("score1 IS NOT NULL AND score2 IS NOT NULL") }
|
||||
scope :unfinished, -> { where("score1 IS NULL AND score2 IS NULL") }
|
||||
scope :unreffed, -> { where.not(referee_id: nil) }
|
||||
scope :ordered, -> { order("match_time DESC") }
|
||||
scope :chrono, -> { order("match_time ASC") }
|
||||
scope :recent, -> { limit("8") }
|
||||
scope :bigrecent, -> { limit("50") }
|
||||
scope :active, -> { where("contest_id IN (?)", Contest.active) }
|
||||
scope :on_day, -> (day) { where("match_time > ? and match_time < ?", day.beginning_of_day, day.end_of_day) }
|
||||
scope :on_week, -> (time) { where("match_time > ? and match_time < ?", time.beginning_of_week, time.end_of_week) }
|
||||
scope :of_contester, -> (contester) { where("contester1_id = ? OR contester2_id = ?", contester.id, contester.id) }
|
||||
scope :of_user, -> (user) { includes(:matchers).where("matchers.user_id = ?", user.id) }
|
||||
scope :of_team, -> (team) { includes({:contester1 => :team, :contester2 => :team}).where("teams.id = ? OR teams_contesters.id = ?", team.id, team.id) }
|
||||
scope :of_userteam, -> (user, team) { includes({:matchers => {:contester => :team}}).where("teams.id = ? AND matchers.user_id = ?", team.id, user.id) }
|
||||
scope :within_time, -> (from, to) { where("match_time > ? AND match_time < ?", from.utc, to.utc) }
|
||||
scope :around, -> (time) { where("match_time > ? AND match_time < ?", time.ago(MATCH_LENGTH).utc, time.ago(-MATCH_LENGTH).utc) }
|
||||
scope :after, -> (time) { where("match_time > ? AND match_time < ?", time.utc, time.ago(-MATCH_LENGTH).utc) }
|
||||
scope :map_stats, -> { select("map1_id, COUNT(*) as num, maps.name").
|
||||
joins("LEFT JOIN maps ON maps.id = map1_id").
|
||||
group("map1_id").
|
||||
having("map1_id is not null").
|
||||
order("num DESC") }
|
||||
scope :year_stats, -> { select("id, DATE_FORMAT(match_time, '%Y') as year, COUNT(*) as num").
|
||||
where("match_time > '2000-01-01 01:01:01'").
|
||||
group("year").
|
||||
order("num DESC") }
|
||||
scope :month_stats, -> { select("id, DATE_FORMAT(match_time, '%m') as month_n,
|
||||
DATE_FORMAT(match_time, '%M') as month,
|
||||
COUNT(*) as num").
|
||||
where("match_time > '2000-01-01 01:01:01'").
|
||||
group("month").
|
||||
order("month_n") }
|
||||
|
||||
validates :contester1, :contester2, :contest, presence: true
|
||||
validates :score1, :score2, format: /\A[1-9]?[0-9]\z/, allow_nil: true
|
||||
|
@ -144,6 +120,7 @@ class Match < ActiveRecord::Base
|
|||
"red" if contester2.team == friendly && score2 < score1
|
||||
end
|
||||
|
||||
<<<<<<< HEAD
|
||||
def preds(contester)
|
||||
perc = Prediction.count(conditions: ["match_id = ? AND score#{contester} > 2", id])
|
||||
perc != 0 ? (perc / predictions.count.to_f * 100).round : 0
|
||||
|
@ -151,6 +128,15 @@ class Match < ActiveRecord::Base
|
|||
|
||||
def mercs(contester)
|
||||
matchers.all conditions: { merc: true, contester_id: contester.id }
|
||||
=======
|
||||
def preds contester
|
||||
perc = Prediction.where("match_id = ? AND score#{contester} > 2", id).count()
|
||||
perc != 0 ? (perc/predictions.count.to_f*100).round : 0
|
||||
end
|
||||
|
||||
def mercs contester
|
||||
matchers.where(merc: true, contester_id: contester.id)
|
||||
>>>>>>> feature/rails-4
|
||||
end
|
||||
|
||||
def get_hltv
|
||||
|
@ -162,11 +148,19 @@ class Match < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def team1_lineup
|
||||
<<<<<<< HEAD
|
||||
matchers.all(conditions: { contester_id: contester1_id })
|
||||
end
|
||||
|
||||
def team2_lineup
|
||||
matchers.all(conditions: { contester_id: contester2_id })
|
||||
=======
|
||||
matchers.where(contester_id: contester1_id)
|
||||
end
|
||||
|
||||
def team2_lineup
|
||||
matchers.where(contester_id: contester2_id)
|
||||
>>>>>>> feature/rails-4
|
||||
end
|
||||
|
||||
def get_friendly(param = nil)
|
||||
|
@ -199,7 +193,11 @@ class Match < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def send_notifications
|
||||
<<<<<<< HEAD
|
||||
Profile.includes(:user).where(notify_any_match: 1).find_each do |p|
|
||||
=======
|
||||
Profile.where("notify_any_match", 1).includes(:user).each do |p|
|
||||
>>>>>>> feature/rails-4
|
||||
Notifications.match p.user, self if p.user
|
||||
end
|
||||
contester2.team.teamers.active.each do |teamer|
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
# category_id :integer
|
||||
#
|
||||
|
||||
require 'data_file'
|
||||
|
||||
class Movie < ActiveRecord::Base
|
||||
include Extra
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
class Poll < ActiveRecord::Base
|
||||
include Extra
|
||||
|
||||
default_scope -> { order("created_at DESC") }
|
||||
|
||||
attr_protected :id, :updated_at, :created_at, :votes, :user_id
|
||||
|
||||
validates_length_of :question, :in => 1..50
|
||||
|
|
|
@ -16,7 +16,7 @@ class Post < ActiveRecord::Base
|
|||
|
||||
attr_protected :id, :updated_at, :created_at, :votes, :user_id
|
||||
|
||||
scope :basic, :include => [{:user => [:team, :profile]}, :topic]
|
||||
scope :basic, -> {includes([{:user => [:team, :profile]}, :topic])}
|
||||
|
||||
validates_presence_of :topic, :user
|
||||
validates_length_of :text, :in => 1..10000
|
||||
|
|
|
@ -19,28 +19,10 @@ class Shoutmsg < ActiveRecord::Base
|
|||
validates_length_of :text, :in => 1..100
|
||||
validates_presence_of :user
|
||||
|
||||
scope :recent,
|
||||
:include => :user,
|
||||
:order => "id DESC",
|
||||
:limit => 8
|
||||
scope :box,
|
||||
:conditions => "shoutable_type IS NULL AND shoutable_id IS NULL",
|
||||
:limit => 8
|
||||
scope :typebox,
|
||||
:conditions => "shoutable_type IS NULL AND shoutable_id IS NULL"
|
||||
scope :lastXXX,
|
||||
:include => :user,
|
||||
:order => "id DESC",
|
||||
:limit => 500
|
||||
scope :of_object,
|
||||
lambda { |object, id| {:conditions => {:shoutable_type => object, :shoutable_id => id}} }
|
||||
scope :ordered, :order => "id"
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :shoutable, :polymorphic => true
|
||||
|
||||
<<<<<<< Updated upstream
|
||||
=======
|
||||
|
||||
scope :recent, -> { includes(:user).order("id DESC").limit(8) }
|
||||
scope :box, -> { where(shoutable_type: nil, shoutable_id: nil).limit(8) }
|
||||
scope :typebox, -> { where(shoutable_type: nil, shoutable_id: nil) }
|
||||
|
@ -48,7 +30,6 @@ class Shoutmsg < ActiveRecord::Base
|
|||
scope :of_object, -> (object, id) { where(shoutable_type: object, shoutable_id: id) }
|
||||
scope :ordered, order("id")
|
||||
|
||||
>>>>>>> Stashed changes
|
||||
def domain
|
||||
self[:shoutable_type] ? "shout_#{shoutable_type}_#{shoutable_id}" : "shoutbox"
|
||||
end
|
||||
|
|
|
@ -30,36 +30,39 @@ class Team < ActiveRecord::Base
|
|||
validates_length_of :name, :tag, :in => 2..20
|
||||
validates_length_of :irc, :maximum => 20, :allow_blank => true
|
||||
validates_length_of :web, :maximum => 50, :allow_blank => true
|
||||
validates_format_of :country, :with => /\A[A-Z]{2}\z$/, :allow_blank => true
|
||||
validates_format_of :country, :with => /\A[A-Z]{2}\z/, :allow_blank => true
|
||||
validates_length_of [:comment, :recruiting], :in => 0..75, :allow_blank => true
|
||||
|
||||
scope :with_teamers_num,
|
||||
lambda { |num| {
|
||||
:select => "teams.*, COUNT(T.id) AS teamers_num",
|
||||
:joins => "LEFT JOIN teamers T ON T.team_id = teams.id AND T.rank >= #{Teamer::RANK_MEMBER}",
|
||||
:group => "teams.id",
|
||||
:having => ["teamers_num >= ?", num]} }
|
||||
scope :with_teamers, :include => :teamers
|
||||
scope :active, :conditions => {:active => true}
|
||||
scope :inactive, :conditions => {:active => false}
|
||||
scope :ordered, :order => "name"
|
||||
scope :recruiting, :conditions => "recruiting IS NOT NULL AND recruiting != ''"
|
||||
scope :with_teamers_num, -> (num) {
|
||||
select("teams.*, COUNT(T.id) AS teamers_num").
|
||||
joins("LEFT JOIN teamers T ON T.team_id = teams.id AND T.rank >= #{Teamer::RANK_MEMBER}").
|
||||
group("teams.id").
|
||||
having("teamers_num >= ?", num) }
|
||||
scope :non_empty_teams, -> { joins(:teamers).where("teamers.rank >= #{Teamer::RANK_MEMBER}").distinct }
|
||||
scope :with_teamers, -> { includes(:teamers) }
|
||||
scope :active, -> { where(active: true) }
|
||||
scope :inactive, -> { where(active: false) }
|
||||
scope :ordered, -> { order("name") }
|
||||
scope :recruiting, -> { where("recruiting IS NOT NULL AND recruiting != ''") }
|
||||
|
||||
belongs_to :founder, :class_name => "User"
|
||||
has_many :teamers, :dependent => :destroy
|
||||
has_many :leaders, :class_name => "Teamer", :conditions => ["rank = ?", Teamer::RANK_LEADER]
|
||||
|
||||
has_many :active_teamers, -> { where("rank >= ?", Teamer::RANK_MEMBER) }
|
||||
has_many :teamers, :dependent => :destroy, :counter_cache => true
|
||||
has_many :leaders, -> { where("rank = ?", Teamer::RANK_LEADER) }, :class_name => "Teamer"
|
||||
has_many :contesters, :dependent => :destroy
|
||||
has_many :contests, :through => :contesters, :conditions => {"contesters.active" => true}
|
||||
has_many :contests, -> { where("contesters.active", true) }, :through => :contesters
|
||||
has_many :received_messages, :class_name => "Message", :as => "recipient"
|
||||
has_many :sent_messages, :class_name => "Message", :as => "sender"
|
||||
has_many :matches, :through => :contesters
|
||||
has_many :matches_finished, :through => :contesters, :source => :matches, :conditions => "(score1 != 0 OR score2 != 0)"
|
||||
has_many :matches_won, :through => :contesters, :source => :matches,
|
||||
:conditions => "((score1 > score2 AND contester1_id = contesters.id) OR (score2 > score1 AND contester2_id = contesters.id)) AND (score1 != 0 OR score2 != 0)"
|
||||
has_many :matches_lost, :through => :contesters, :source => :matches,
|
||||
:conditions => "((score1 < score2 AND contester1_id = contesters.id) OR (score2 < score1 AND contester2_id = contesters.id)) AND (score1 != 0 OR score2 != 0)"
|
||||
has_many :matches_draw, :through => :contesters, :source => :matches,
|
||||
:conditions => "(score1 = score2 AND score1 > 0) AND (score1 != 0 OR score2 != 0)"
|
||||
has_many :matches_finished, -> { where("(score1 != 0 OR score2 != 0)") },
|
||||
:through => :contesters, :source => :matches
|
||||
has_many :matches_won, -> { where("((score1 > score2 AND contester1_id = contesters.id) OR (score2 > score1 AND contester2_id = contesters.id)) AND (score1 != 0 OR score2 != 0)") },
|
||||
:through => :contesters, :source => :matches
|
||||
has_many :matches_lost, -> { where("((score1 < score2 AND contester1_id = contesters.id) OR (score2 < score1 AND contester2_id = contesters.id)) AND (score1 != 0 OR score2 != 0)") },
|
||||
:through => :contesters, :source => :matches
|
||||
has_many :matches_draw, -> { where("(score1 = score2 AND score1 > 0) AND (score1 != 0 OR score2 != 0)") },
|
||||
:through => :contesters, :source => :matches
|
||||
|
||||
mount_uploader :logo, TeamUploader
|
||||
|
||||
|
@ -89,7 +92,7 @@ class Team < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def self.search(search)
|
||||
search ? where("LOWER(name) LIKE LOWER(?)", "%#{search}%") : scoped
|
||||
search ? where("LOWER(name) LIKE LOWER(?)", "%#{search}%") : all
|
||||
end
|
||||
|
||||
def destroy
|
||||
|
|
|
@ -29,80 +29,67 @@ class Teamer < ActiveRecord::Base
|
|||
#validate_on_create:validate_contests
|
||||
validate :validate_team
|
||||
|
||||
scope :basic,
|
||||
:include => :user,
|
||||
:order => "rank DESC, created_at ASC"
|
||||
scope :past,
|
||||
:conditions => ["teamers.rank = ?", RANK_REMOVED]
|
||||
scope :joining,
|
||||
:conditions => ["teamers.rank = ?", RANK_JOINER]
|
||||
scope :present,
|
||||
:conditions => ["teamers.rank >= ?", RANK_JOINER]
|
||||
scope :active,
|
||||
:conditions => ["teamers.rank >= ?", RANK_MEMBER]
|
||||
scope :leaders,
|
||||
:conditions => ["teamers.rank >= ?", RANK_DEPUTEE]
|
||||
scope :of_team,
|
||||
lambda { |team| {:conditions => {"teamers.team_id" => team.id}} }
|
||||
scope :active_teams,
|
||||
:include => :team,
|
||||
:conditions => ["teams.active = ?", true]
|
||||
scope :distinct,
|
||||
:group => "user_id, team_id"
|
||||
scope :ordered,
|
||||
:order => "`rank` DESC, `created_at` ASC"
|
||||
scope :historic,
|
||||
lambda { |user, time|
|
||||
{:conditions => ["user_id = ? AND created_at < ? AND ((updated_at > ? AND rank = ?) OR rank >= ?)",
|
||||
user.id, time.utc, time.utc, RANK_REMOVED, RANK_MEMBER]} }
|
||||
scope :basic, -> { includes(:user).order("rank DESC, created_at ASC") }
|
||||
scope :past, -> { where("teamers.rank = ?", RANK_REMOVED) }
|
||||
scope :joining,-> { where("teamers.rank = ?", RANK_JOINER) }
|
||||
scope :present, -> { where("teamers.rank >= ?", RANK_JOINER) }
|
||||
scope :active, -> { where("teamers.rank >= ?", RANK_MEMBER) }
|
||||
scope :leaders, -> { where("teamers.rank >= ?", RANK_DEPUTEE) }
|
||||
scope :of_team, -> (team) { where("teamers.team_id" => team.id) }
|
||||
scope :active_teams, -> { includes(:team).where("teams.active = ?", true) }
|
||||
scope :unique_by_team, -> { group("user_id, team_id") }
|
||||
scope :ordered, -> { order("rank DESC, created_at ASC") }
|
||||
scope :historic, -> (user, time) {
|
||||
where("user_id = ? AND created_at < ? AND ((updated_at > ? AND rank = ?) OR rank >= ?)",
|
||||
user.id, time.utc, time.utc, RANK_REMOVED, RANK_MEMBER) }
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :team
|
||||
has_many :other_teamers, :through => :user, :source => :teamers, :conditions => ["teamers.id != ?", object_id]
|
||||
has_many :contesters, :through => :team
|
||||
belongs_to :user
|
||||
belongs_to :team
|
||||
has_many :other_teamers, -> { where("teamers.id != ?", object_id) }, :through => :user, :source => :teamers
|
||||
has_many :contesters, :through => :team
|
||||
|
||||
before_create :init_variables
|
||||
before_create :init_variables
|
||||
|
||||
def to_s
|
||||
user.to_s
|
||||
def to_s
|
||||
user.to_s
|
||||
end
|
||||
|
||||
def ranks
|
||||
{RANK_JOINER => "Joining", RANK_MEMBER => "Member", RANK_DEPUTEE => "Deputee", RANK_LEADER => "Leader"}
|
||||
end
|
||||
|
||||
def validate_team
|
||||
if user.teamers.of_team(team).present.count > 0
|
||||
errors.add :team, I18n.t(:teams_join_twice)
|
||||
end
|
||||
end
|
||||
|
||||
def ranks
|
||||
{RANK_JOINER => "Joining", RANK_MEMBER => "Member", RANK_DEPUTEE => "Deputee", RANK_LEADER => "Leader"}
|
||||
end
|
||||
def validate_contests
|
||||
# TODO
|
||||
end
|
||||
|
||||
def validate_team
|
||||
if user.teamers.of_team(team).present.count > 0
|
||||
errors.add :team, I18n.t(:teams_join_twice)
|
||||
end
|
||||
end
|
||||
def init_variables
|
||||
self.rank = RANK_JOINER unless self.rank
|
||||
end
|
||||
|
||||
def validate_contests
|
||||
# TODO
|
||||
def destroy
|
||||
user.update_attribute :team, nil if user.team == team
|
||||
if rank == Teamer::RANK_JOINER
|
||||
super
|
||||
else
|
||||
update_attribute :rank, Teamer::RANK_REMOVED
|
||||
end
|
||||
end
|
||||
|
||||
def init_variables
|
||||
self.rank = RANK_JOINER unless self.rank
|
||||
end
|
||||
def can_create? cuser, params
|
||||
cuser and Verification.contain params, [:user_id, :team_id]
|
||||
end
|
||||
|
||||
def destroy
|
||||
user.update_attribute :team, nil if user.team == team
|
||||
if rank == Teamer::RANK_JOINER
|
||||
super
|
||||
else
|
||||
update_attribute :rank, Teamer::RANK_REMOVED
|
||||
end
|
||||
end
|
||||
def can_update? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
|
||||
def can_create? cuser, params
|
||||
cuser and Verification.contain params, [:user_id, :team_id]
|
||||
end
|
||||
|
||||
def can_update? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
|
||||
def can_destroy? cuser
|
||||
cuser and (user == cuser or team.is_leader? cuser or cuser.admin?)
|
||||
end
|
||||
def can_destroy? cuser
|
||||
cuser and (user == cuser or team.is_leader? cuser or cuser.admin?)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -26,12 +26,12 @@ class Topic < ActiveRecord::Base
|
|||
belongs_to :user
|
||||
belongs_to :forum
|
||||
has_one :lock, :as => :lockable
|
||||
has_one :latest, :class_name => "Post", :order => "id DESC"
|
||||
has_many :posts, :order => "id ASC", :dependent => :destroy
|
||||
has_one :latest, -> { order("id DESC") }, :class_name => "Post"
|
||||
has_many :posts, -> { order("id ASC") }, :dependent => :destroy
|
||||
has_many :view_counts, :as => :viewable, :dependent => :destroy
|
||||
|
||||
scope :basic, :include => [:latest, { forum: :forumer }, :user]
|
||||
scope :ordered, :order => "state DESC, posts.id DESC"
|
||||
scope :basic, -> { includes([:latest, { forum: :forumer }, :user]) }
|
||||
scope :ordered, -> { order("state DESC, posts.id DESC") }
|
||||
|
||||
validates_presence_of :user_id, :forum_id
|
||||
validates_length_of :title, :in => 1..50
|
||||
|
|
|
@ -21,9 +21,7 @@
|
|||
# public_email :boolean default(FALSE), not null
|
||||
#
|
||||
|
||||
|
||||
require 'digest/md5'
|
||||
require File.join(Rails.root, 'vendor', 'plugins', 'acts_as_versioned', 'lib', 'acts_as_versioned.rb')
|
||||
|
||||
class User < ActiveRecord::Base
|
||||
include Extra
|
||||
|
@ -47,71 +45,68 @@ class User < ActiveRecord::Base
|
|||
has_many :groups, :through => :groupers
|
||||
has_many :shoutmsgs, :dependent => :destroy
|
||||
has_many :issues, :foreign_key => "author_id", :dependent => :destroy
|
||||
has_many :open_issues, :class_name => "Issue", :foreign_key => "assigned_id",
|
||||
:conditions => ["issues.status = ?", Issue::STATUS_OPEN]
|
||||
has_many :assigned_issues, :class_name => "Issue", :foreign_key => "assigned_id"
|
||||
has_many :posted_comments, :dependent => :destroy, :class_name => "Comment"
|
||||
has_many :comments, :class_name => "Comment", :as => :commentable, :order => "created_at ASC", :dependent => :destroy
|
||||
has_many :comments, -> { order("created_at ASC") }, :class_name => "Comment", :as => :commentable, :dependent => :destroy
|
||||
has_many :teamers, :dependent => :destroy
|
||||
has_many :active_teams, :through => :teamers, :source => "team",
|
||||
:conditions => ["teamers.rank >= ? AND teams.active = ?", Teamer::RANK_MEMBER, true]
|
||||
has_many :active_contesters, :through => :active_teams, :source => "contesters",
|
||||
:conditions => {"contesters.active" => true}
|
||||
has_many :active_contests, :through => :active_contesters, :source => "contest",
|
||||
:conditions => ["contests.status != ?", Contest::STATUS_CLOSED]
|
||||
has_many :past_teams, :through => :teamers, :source => "team", :group => "user_id, team_id"
|
||||
has_many :active_teams, -> { where("teamers.rank >= ? AND teams.active = ?", Teamer::RANK_MEMBER, true) }, \
|
||||
:through => :teamers, :source => "team"
|
||||
has_many :active_contesters, -> { where("contesters.active = ?", true) }, \
|
||||
:through => :active_teams, :source => "contesters"
|
||||
has_many :active_contests, -> { where("contests.status != ?", Contest::STATUS_CLOSED) }, \
|
||||
:through => :active_contesters, :source => "contest"
|
||||
has_many :matchers, :dependent => :destroy
|
||||
has_many :matches, :through => :matchers
|
||||
has_many :predictions, :dependent => :destroy
|
||||
has_many :challenges_received, :through => :active_contesters, :source => "challenges_received"
|
||||
has_many :challenges_sent, :through => :active_contesters, :source => "challenges_sent"
|
||||
has_many :upcoming_team_matches, :through => :active_contesters, :source => "matches",
|
||||
:conditions => "match_time > UTC_TIMESTAMP()"
|
||||
has_many :upcoming_ref_matches, :class_name => "Match", :foreign_key => "referee_id",
|
||||
:conditions => "match_time > UTC_TIMESTAMP()"
|
||||
has_many :past_team_matches, :through => :active_contesters, :source => "matches",
|
||||
:conditions => "match_time < UTC_TIMESTAMP()"
|
||||
has_many :past_ref_matches, :class_name => "Match", :foreign_key => "referee_id",
|
||||
:conditions => "match_time < UTC_TIMESTAMP()"
|
||||
has_many :upcoming_team_matches, -> { where("match_time > UTC_TIMESTAMP()") },
|
||||
:through => :active_teams, :source => "matches"
|
||||
has_many :upcoming_ref_matches, -> { where("match_time > UTC_TIMESTAMP()") },
|
||||
:class_name => "Match", :foreign_key => "referee_id"
|
||||
has_many :past_team_matches, -> { where("match_time < UTC_TIMESTAMP()") },
|
||||
:through => :active_contesters, :source => "matches"
|
||||
has_many :past_ref_matches, -> { where("match_time < UTC_TIMESTAMP()") },
|
||||
:class_name => "Match", :foreign_key => "referee_id"
|
||||
has_many :received_personal_messages, :class_name => "Message", :as => "recipient", :dependent => :destroy
|
||||
has_many :sent_personal_messages, :class_name => "Message", :as => "sender", :dependent => :destroy
|
||||
has_many :sent_team_messages, :through => :active_teams, :source => :sent_messages
|
||||
has_many :match_teams, :through => :matchers, :source => :teams, :uniq => true
|
||||
has_many :match_teams, :through => :matchers, :source => :teams
|
||||
|
||||
scope :active, :conditions => {:banned => false}
|
||||
scope :with_age,
|
||||
:select => "DATE_FORMAT(FROM_DAYS(TO_DAYS(NOW())-TO_DAYS(birthdate)), '%Y')+0 AS aged, COUNT(*) as num, username",
|
||||
:group => "aged",
|
||||
:having => "num > 8 AND aged > 0"
|
||||
scope :country_stats,
|
||||
:select => "country, COUNT(*) as num",
|
||||
:conditions => "country is not null and country != '' and country != '--'",
|
||||
:group => "country",
|
||||
:having => "num > 15",
|
||||
:order => "num DESC"
|
||||
scope :posts_stats,
|
||||
:select => "users.id, username, COUNT(posts.id) as num",
|
||||
:joins => "LEFT JOIN posts ON posts.user_id = users.id",
|
||||
:group => "users.id",
|
||||
:order => "num DESC"
|
||||
scope :banned,
|
||||
:joins => "LEFT JOIN bans ON bans.user_id = users.id AND expiry > UTC_TIMESTAMP()",
|
||||
:conditions => "bans.id IS NOT NULL"
|
||||
scope :idle,
|
||||
:conditions => ["lastvisit < ?", 30.minutes.ago.utc]
|
||||
scope :lately,
|
||||
:conditions => ["lastvisit > ?", 30.days.ago.utc]
|
||||
scope :active, -> { where(banned: false) }
|
||||
scope :with_age, -> {
|
||||
where("DATE_FORMAT(FROM_DAYS(TO_DAYS(NOW())-TO_DAYS(birthdate)), '%Y')+0 AS aged, COUNT(*) as num, username")
|
||||
.group("aged")
|
||||
.having("num > 8 AND aged > 0") }
|
||||
scope :country_stats, -> {
|
||||
select("country, COUNT(*) as num")
|
||||
.where("country is not null and country != '' and country != '--'")
|
||||
.group("country")
|
||||
.having("num > 15")
|
||||
.order("num DESC") }
|
||||
scope :posts_stats, -> {
|
||||
select("users.id, username, COUNT(posts.id) as num")
|
||||
.joins("LEFT JOIN posts ON posts.user_id = users.id")
|
||||
.group("users.id")
|
||||
.order("num DESC") }
|
||||
scope :banned, -> {
|
||||
joins("LEFT JOIN bans ON bans.user_id = users.id AND expiry > UTC_TIMESTAMP()")
|
||||
.conditions("bans.id IS NOT NULL") }
|
||||
scope :idle, -> {
|
||||
joins("lastvisit < ?", 30.minutes.ago.utc) }
|
||||
|
||||
before_validation :update_password
|
||||
|
||||
validates :username, uniqueness: true, length: {in: 2..20}, format: /\A[A-Za-z0-9_\-\+]{2,20}\Z/
|
||||
validates :firstname, length: {in: 1..15}, allow_blank: true
|
||||
validates :lastname, length: {in: 1..25}, allow_blank: true
|
||||
validates :raw_password, presence: {on: :create}
|
||||
validates :email, uniqueness: true, length: {maximum: 50}, format: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
|
||||
validates :steamid, uniqueness: {allow_nil: true}, length: {maximum: 14}, presence: {on: :create}
|
||||
validate :validate_steamid
|
||||
validates :time_zone, length: {maximum: 100}, allow_blank: true
|
||||
validates :public_email, inclusion: [true, false], allow_nil: true
|
||||
validates_uniqueness_of :username, :email, :steamid
|
||||
validates_length_of :firstname, :in => 1..15, :allow_blank => true
|
||||
validates_length_of :lastname, :in => 1..25, :allow_blank => true
|
||||
validates_length_of :username, :in => 2..20
|
||||
validates_format_of :username, :with => /\A[A-Za-z0-9_\-\+]{2,20}\Z/
|
||||
validates_presence_of :raw_password, :on => :create
|
||||
validates_length_of :email, :maximum => 50
|
||||
validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
|
||||
validates_length_of :steamid, :maximum => 30
|
||||
validates_format_of :steamid, :with => /\A([0-9]{1,10}:){2}[0-9]{1,10}\Z/
|
||||
validates_length_of :time_zone, :maximum => 100, :allow_blank => true, :allow_nil => true
|
||||
validates_inclusion_of [:public_email], :in => [true, false], :allow_nil => true
|
||||
validate :validate_team
|
||||
|
||||
before_create :init_variables
|
||||
|
@ -143,8 +138,8 @@ class User < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def country_s
|
||||
country = ISO3166::Country[self.country]
|
||||
country ? country.name : 'Earth'
|
||||
country_object = ISO3166::Country[country]
|
||||
country_object.translations[I18n.locale.to_s] || country_object.name
|
||||
end
|
||||
|
||||
def realname
|
||||
|
@ -183,7 +178,7 @@ class User < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def banned? type = Ban::TYPE_SITE
|
||||
Ban.first :conditions => ["expiry > UTC_TIMESTAMP() AND user_id = ? AND ban_type = ?", self.id, type]
|
||||
Ban.where("expiry > UTC_TIMESTAMP() AND user_id = ? AND ban_type = ?", self.id, type).exists?
|
||||
end
|
||||
|
||||
def admin?
|
||||
|
@ -220,20 +215,19 @@ class User < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def verified?
|
||||
# created_at < DateTime.now.ago(VERIFICATION_TIME)
|
||||
true
|
||||
end
|
||||
|
||||
def has_access? group
|
||||
def has_access? groups
|
||||
admin? or groups.exists?(:id => group)
|
||||
end
|
||||
|
||||
def new_messages
|
||||
received_personal_messages.unread_by(self) + received_team_messages.unread_by(self)
|
||||
received_personal_messages.union(received_team_messages).unread_by(self)
|
||||
end
|
||||
|
||||
def received_messages
|
||||
received_personal_messages + received_team_messages
|
||||
received_personal_messages.union(received_team_messages)
|
||||
end
|
||||
|
||||
def received_team_messages
|
||||
|
@ -241,7 +235,7 @@ class User < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def sent_messages
|
||||
sent_personal_messages + sent_team_messages
|
||||
sent_personal_messages.union(sent_team_messages)
|
||||
end
|
||||
|
||||
def upcoming_matches
|
||||
|
@ -328,7 +322,7 @@ class User < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def self.search(search)
|
||||
search ? where("LOWER(username) LIKE LOWER(?) OR steamid LIKE ?", "%#{search}%", "%#{search}%") : scoped
|
||||
search ? where("LOWER(username) LIKE LOWER(?) OR steamid LIKE ?", "%#{search}%", "%#{search}%") : all
|
||||
end
|
||||
|
||||
def self.refadmins
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
</tr>
|
||||
<% Group.admins.each do |grouper| %>
|
||||
<tr>
|
||||
<td class="country"><%= flag grouper.user.country %></td>
|
||||
<td class="country"><%= flag grouper.user.country_s %></td>
|
||||
<td class="username"><%= namelink grouper.user %></td>
|
||||
<% if grouper.user.public_email %>
|
||||
<td><%= h grouper.user.email_s %></td>
|
||||
|
|
|
@ -10,5 +10,4 @@
|
|||
<%= render partial: "list", locals: { bans: @bans.ineffective } %>
|
||||
|
||||
<%= link_to 'New Ban', new_ban_path, class: 'button' %>
|
||||
</div>
|
||||
|
||||
</div>
|
|
@ -10,7 +10,7 @@
|
|||
</h1>
|
||||
<div class="controls">
|
||||
<% if cuser %>
|
||||
<%= link_to_function icon('comment'), "QuoteText(#{comment.id}, 'comments')" %>
|
||||
<%= link_to '#', data:{on: :click, call: 'QuoteText',args: "#{comment.id}, 'comments'"} %>
|
||||
<% if comment.can_update? cuser %>
|
||||
<%= link_to icon('pencil'), edit_comment_path(comment) %>
|
||||
<% end %>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<div id="categories">
|
||||
<% @categories.each do |cat| %>
|
||||
<% forums = cuser ? cat.forums.available_to(cuser, Forumer::ACCESS_READ).ordered : cat.forums.public.ordered %>
|
||||
<% forums = cuser ? cat.forums.available_to(cuser, Forumer::ACCESS_READ).ordered : cat.forums.public_forums.ordered %>
|
||||
<% next if forums.length == 0 %>
|
||||
|
||||
<div class="category">
|
||||
|
@ -58,7 +58,7 @@
|
|||
<strong><%= Topic.count %></strong> topics, and <strong><%= User.count %></strong> users.
|
||||
</p>
|
||||
<p>
|
||||
Our newest member is <%= namelink User.last %> and most active member is <%= namelink User.posts_stats.first %>.
|
||||
Our newest member is <%= namelink User.last %> and most active member is <%= namelink User.posts_stats(1).first %>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
</div>
|
||||
<div class="fields horizontal">
|
||||
<%= f.label :assigned %>
|
||||
<%= f.text_field :assigned_name, {:value => User.first(:conditions => {:id => @issue.assigned})} %>
|
||||
<%= f.text_field :assigned_name, {:value => User.where(id: @issue.assigned)} %>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="fields horizontal">
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
</div>
|
||||
<div id="sidebar">
|
||||
<%= yield :sidebar %>
|
||||
<% ['calendar','shoutbox', 'posts', 'poll'].each do |widget| %>
|
||||
<%= render partial: "widgets/#{widget}" %>
|
||||
<% ['shoutbox', 'posts', 'poll'].each do |widget| %>
|
||||
<%= render partial: "widgets/#{widget}" %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
|
||||
<div class="controls">
|
||||
<% if post.topic.posts.build.can_create? cuser %>
|
||||
<%= link_to_function 'Quote Reply', "QuoteText(#{post.id}); $('#reply').fadeIn('slow')", class: 'button tiny' %>
|
||||
<%= link_to '#', data:{on: :click, call: 'QuoteText', args: "#{post.id}"}, class: 'button tiny' %>
|
||||
<% end %>
|
||||
<% if post.can_update? cuser %>
|
||||
<%= link_to 'Edit', edit_post_path(post), class: 'button tiny' %>
|
||||
|
|
|
@ -10,12 +10,11 @@
|
|||
</tr>
|
||||
|
||||
<% for team in teams %>
|
||||
<% if team.teamers_num > 0 %>
|
||||
<tr>
|
||||
<td><%= flag team.country %></td>
|
||||
<td><%= namelink team %></td>
|
||||
<td><%= h team.irc if team.irc %></td>
|
||||
<td><%= h team.teamers_num %></td>
|
||||
<td><%= h team.teamers.count %></td>
|
||||
<% if cuser and cuser.admin? %>
|
||||
<td class="actions">
|
||||
<%= link_to edit_team_path(team) do %>
|
||||
|
@ -33,6 +32,5 @@
|
|||
</td>
|
||||
<% end %>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</table>
|
||||
|
|
|
@ -59,14 +59,14 @@
|
|||
</div>
|
||||
|
||||
<div class="tab" id="members">
|
||||
<% if @team.teamers.active.ordered.distinct.length > 0 %>
|
||||
<% if @team.teamers.active.ordered.unique_by_team.length > 0 %>
|
||||
<h3>Current Members</h3>
|
||||
<%= render partial: "teamers/list", locals: { teamers: @team.teamers.active.ordered.distinct, blacklist: false, comment: true } %>
|
||||
<%= render partial: "teamers/list", locals: { teamers: @team.teamers.active.ordered.unique_by_team, blacklist: false, comment: true } %>
|
||||
<% end %>
|
||||
|
||||
<% if @team.teamers.past.distinct.length > 0 %>
|
||||
<% if @team.teamers.past.unique_by_team.length > 0 %>
|
||||
<h3>Past Members</h3>
|
||||
<%= render partial: "teamers/list", locals: { teamers: @team.teamers.past.distinct, blacklist: @team.teamers.active.ordered.distinct, comment: false } %>
|
||||
<%= render partial: "teamers/list", locals: { teamers: @team.teamers.past.unique_by_team, blacklist: @team.teamers.active.ordered.unique_by_team, comment: false } %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
|
||||
<div>
|
||||
<% if @newpost.can_create? cuser %>
|
||||
<%= link_to_function 'Fast Reply', "$('#reply').fadeIn('slow')", class: 'button' %>
|
||||
<%= link_to 'Fast Reply', "#", class: 'button fastReply' %>
|
||||
<%= link_to 'Reply', new_post_path(@newpost, id: @topic), class: 'button' %>
|
||||
<% end %>
|
||||
<% if @topic.can_update? cuser %>
|
||||
|
|
|
@ -224,9 +224,9 @@
|
|||
<%= render partial: "issues/list", locals: { issues: @user.issues } %>
|
||||
<% end %>
|
||||
|
||||
<% if @user.open_issues.size > 0 %>
|
||||
<% if @user.asssigned_issues.size > 0 %>
|
||||
<h4>Open issues assigned to you</h4>
|
||||
<%= render partial: "issues/list", locals: { issues: @user.open_issues } %>
|
||||
<%= render partial: "issues/list", locals: { issues: @user.asssigned_issues } %>
|
||||
<% end %>
|
||||
|
||||
<%= link_to 'New issue', new_issue_path, class: 'button' %>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<ol>
|
||||
<% Comment.recent3.filtered.each do |comment| %>
|
||||
<% Comment.recent(3).filtered.each do |comment| %>
|
||||
<li>
|
||||
<b>
|
||||
<%= namelink comment.commentable, 15 %>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div class="widget poll">
|
||||
<h4><%= t('widget.poll') %></h4>
|
||||
|
||||
<% @poll = Poll.first(order: "created_at DESC") %>
|
||||
<% @poll = Poll.first %>
|
||||
<%= render(partial: "polls/show") if @poll %>
|
||||
</div>
|
||||
<% end %>
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
<div class="separator">Latest comments</div>
|
||||
<ol>
|
||||
<% Comment.recent.filtered.each do |comment| %>
|
||||
<% Comment.recent(3).each do |comment| %>
|
||||
<li>
|
||||
<%= namelink comment.commentable, 15 %>
|
||||
by <%= namelink comment.user, 10 %>
|
||||
|
|
3
bin/bundle
Executable file
3
bin/bundle
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/usr/bin/env ruby
|
||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
|
||||
load Gem.bin_path('bundler', 'bundle')
|
4
bin/rails
Executable file
4
bin/rails
Executable file
|
@ -0,0 +1,4 @@
|
|||
#!/usr/bin/env ruby
|
||||
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
||||
require_relative '../config/boot'
|
||||
require 'rails/commands'
|
4
bin/rake
Executable file
4
bin/rake
Executable file
|
@ -0,0 +1,4 @@
|
|||
#!/usr/bin/env ruby
|
||||
require_relative '../config/boot'
|
||||
require 'rake'
|
||||
Rake.application.run
|
|
@ -31,13 +31,12 @@ Ensl::Application.configure do
|
|||
# Use a different cache store
|
||||
config.cache_store = :dalli_store
|
||||
|
||||
<<<<<<< Updated upstream
|
||||
# Enable threaded mode
|
||||
# config.threadsafe!
|
||||
=======
|
||||
config.eager_load = false
|
||||
|
||||
config.web_console.permissions = '172.18.0.0/16'
|
||||
config.web_console.whiny_requests = true
|
||||
>>>>>>> Stashed changes
|
||||
|
||||
config.eager_load = false
|
||||
end
|
||||
|
|
|
@ -68,8 +68,7 @@ Ensl::Application.configure do
|
|||
config.active_support.deprecation = :notify
|
||||
|
||||
# Custom Session Store config to allow gathers.staging.ensl.org
|
||||
config.session_store :cookie_store, key: "_ENSL_session_key", expire_after: 30.days.to_i, domain: ".ensl.org"
|
||||
# config.session_store :cookie_store, key: '_ENSL_session_key', expire_after: 30.days.to_i, domain: "gathers.ensl.org"
|
||||
|
||||
# config.cache_store = :dalli_store, 'cache', 'cache-2.example.com:11211:2',
|
||||
# { :namespace => NAME_OF_RAILS_APP, :expires_in => 1.day, :compress => true }
|
||||
config.eager_load = true
|
||||
end
|
||||
|
|
|
@ -64,4 +64,6 @@ Ensl::Application.configure do
|
|||
|
||||
# Custom Session Store config to allow gathers.staging.ensl.org
|
||||
config.session_store :cookie_store, key: "_ENSL_session_key_staging", expire_after: 30.days.to_i, domain: ".staging.ensl.org"
|
||||
|
||||
config.eager_load = true
|
||||
end
|
||||
|
|
|
@ -32,4 +32,6 @@ Ensl::Application.configure do
|
|||
|
||||
# Print deprecation notices to the stderr
|
||||
config.active_support.deprecation = :stderr
|
||||
|
||||
config.eager_load = true
|
||||
end
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
require 'active_record/connection_adapters/mysql2_adapter'
|
||||
|
||||
class ActiveRecord::ConnectionAdapters::Mysql2Adapter
|
||||
NATIVE_DATABASE_TYPES[:primary_key] = "int(11) auto_increment PRIMARY KEY"
|
||||
end
|
||||
|
|
7
config/initializers/backtrace_silencers.rb
Normal file
7
config/initializers/backtrace_silencers.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
|
||||
# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
|
||||
|
||||
# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
|
||||
# Rails.backtrace_cleaner.remove_silencers!
|
4
config/initializers/filter_parameter_logging.rb
Normal file
4
config/initializers/filter_parameter_logging.rb
Normal file
|
@ -0,0 +1,4 @@
|
|||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Configure sensitive parameters which will be filtered from the log file.
|
||||
Rails.application.config.filter_parameters += [:password]
|
16
config/initializers/inflections.rb
Normal file
16
config/initializers/inflections.rb
Normal file
|
@ -0,0 +1,16 @@
|
|||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Add new inflection rules using the following format. Inflections
|
||||
# are locale specific, and you may define rules for as many different
|
||||
# locales as you wish. All of these examples are active by default:
|
||||
# ActiveSupport::Inflector.inflections(:en) do |inflect|
|
||||
# inflect.plural /^(ox)$/i, '\1en'
|
||||
# inflect.singular /^(ox)en/i, '\1'
|
||||
# inflect.irregular 'person', 'people'
|
||||
# inflect.uncountable %w( fish sheep )
|
||||
# end
|
||||
|
||||
# These inflection rules are supported but not enabled by default:
|
||||
# ActiveSupport::Inflector.inflections(:en) do |inflect|
|
||||
# inflect.acronym 'RESTful'
|
||||
# end
|
17
config/initializers/legacy.rb
Normal file
17
config/initializers/legacy.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
Dir.glob(File.join(Rails.root, "lib/plugins/*")).sort.each do |directory|
|
||||
if File.directory?(directory)
|
||||
lib = File.join(directory, "lib")
|
||||
|
||||
if File.directory?(lib)
|
||||
$:.unshift lib
|
||||
ActiveSupport::Dependencies.autoload_paths += [lib]
|
||||
end
|
||||
|
||||
initializer = File.join(directory, "init.rb")
|
||||
|
||||
if File.file?(initializer)
|
||||
config = Ensl::Application.config
|
||||
eval(File.read(initializer), binding, initializer)
|
||||
end
|
||||
end
|
||||
end
|
5
config/initializers/mime_types.rb
Normal file
5
config/initializers/mime_types.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Add new mime types for use in respond_to blocks:
|
||||
# Mime::Type.register "text/richtext", :rtf
|
||||
# Mime::Type.register_alias "text/html", :iphone
|
12
config/initializers/secret_token.rb
Normal file
12
config/initializers/secret_token.rb
Normal file
|
@ -0,0 +1,12 @@
|
|||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Your secret key is used for verifying the integrity of signed cookies.
|
||||
# If you change this key, all old signed cookies will become invalid!
|
||||
|
||||
# Make sure the secret is at least 30 characters and all random,
|
||||
# no regular words or you'll be exposed to dictionary attacks.
|
||||
# You can use `rake secret` to generate a secure secret key.
|
||||
|
||||
# Make sure your secret_key_base is kept private
|
||||
# if you're sharing your code publicly.
|
||||
Ensl::Application.config.secret_key_base = '356eee0f950cf925a0c1cbc8f15c1dfddc337a55f177388056906aea7de379f8bc5155e3f8a9d6d716f708b74f912305fc3276d4f290bdf66eadf56a61679c4c'
|
3
config/initializers/session_store.rb
Normal file
3
config/initializers/session_store.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
Ensl::Application.config.session_store :cookie_store, key: '_ensl_session'
|
|
@ -4,22 +4,22 @@ Dotenv.load()
|
|||
base_path = (ENV['DEPLOY_PATH'] || Dir.pwd)
|
||||
#current_path = "#{base_path}/current"
|
||||
#shared_path = "#{base_path}/shared"
|
||||
stderr_path = "#{base_path}/lpuma.stderr.log"
|
||||
stdout_path = "#{base_path}/lpuma.stdout.log"
|
||||
stderr_path = "#{base_path}/log/puma.stderr.log"
|
||||
stdout_path = "#{base_path}/log/puma.stdout.log"
|
||||
|
||||
tag 'ENSL'
|
||||
|
||||
preload_app!
|
||||
daemonize false
|
||||
directory base_path
|
||||
pidfile "#{base_path}/tmp/puma.pid"
|
||||
state_path "#{base_path}/tmp/puma.state"
|
||||
pidfile "#{base_path}/tmp/pids/puma.pid"
|
||||
state_path "#{base_path}/tmp/pids/puma.state"
|
||||
stdout_redirect stdout_path, stderr_path
|
||||
|
||||
environment ENV['RACK_ENV'] || 'production'
|
||||
rackup DefaultRackup
|
||||
|
||||
bind "unix://#{base_path}/tmp/puma.sock"
|
||||
bind "unix://#{base_path}/tmp/sockets/puma.sock"
|
||||
port Integer(ENV['PUMA_PORT'] || 4000)
|
||||
|
||||
worker_timeout Integer(ENV['PUMA_TIMEOUT'] || 30)
|
||||
|
|
114
config/routes.rb
114
config/routes.rb
|
@ -1,5 +1,4 @@
|
|||
Ensl::Application.routes.draw do
|
||||
|
||||
%w(403 404 422 500).each do |code|
|
||||
get code, to: "errors#show", code: code
|
||||
end
|
||||
|
@ -19,9 +18,9 @@ Ensl::Application.routes.draw do
|
|||
resources :versions
|
||||
end
|
||||
|
||||
match "contests/del_map"
|
||||
match "contests/scores"
|
||||
match "contests/historical", to: "contests#historical"
|
||||
get 'contests/del_map'
|
||||
get 'contests/scores'
|
||||
get 'contests/historical', to: "contests#historical"
|
||||
|
||||
resources :contests do
|
||||
get "current", on: :collection
|
||||
|
@ -32,7 +31,7 @@ Ensl::Application.routes.draw do
|
|||
resources :options
|
||||
resources :polls
|
||||
|
||||
match "comments/quote"
|
||||
get 'comments/quote'
|
||||
|
||||
resources :comments
|
||||
resources :shoutmsgs, except: :index
|
||||
|
@ -44,9 +43,10 @@ Ensl::Application.routes.draw do
|
|||
resources :groupers
|
||||
resources :forumers
|
||||
resources :topics
|
||||
resources :matches
|
||||
|
||||
match "forums/up"
|
||||
match "forums/down"
|
||||
get 'forums/up'
|
||||
get 'forums/down'
|
||||
|
||||
resources :forums
|
||||
resources :users
|
||||
|
@ -59,11 +59,9 @@ Ensl::Application.routes.draw do
|
|||
resources :servers
|
||||
resources :predictions
|
||||
resources :rounds
|
||||
|
||||
get "matches/ref/:id" => "matches#ref", as: :match_ref
|
||||
resources :matches do
|
||||
get :admin, to: "matches#admin", on: :collection
|
||||
resources :match_proposals, path: "proposals", as: :proposals, only: [:index, :new, :create, :update]
|
||||
resources :getes do |m|
|
||||
get :admin, to: "getes#admin", on: :collection
|
||||
get :ref, to: "getes#ref"
|
||||
end
|
||||
|
||||
resources :maps
|
||||
|
@ -80,71 +78,61 @@ Ensl::Application.routes.draw do
|
|||
resources :tweets
|
||||
resources :issues
|
||||
|
||||
match "posts/quote"
|
||||
|
||||
resources :posts
|
||||
resources :brackets
|
||||
get 'about/action'
|
||||
get 'about/staff'
|
||||
get 'about/statistics'
|
||||
|
||||
match "about/action"
|
||||
match "about/staff"
|
||||
match "about/statistics"
|
||||
get 'refresh', to: "application#refresh"
|
||||
get 'search', to: "application#search"
|
||||
|
||||
match "refresh", to: "application#refresh"
|
||||
match "search", to: "application#search"
|
||||
get 'news', to: "articles#news_index"
|
||||
get 'news/archive', to: "articles#news_archive"
|
||||
get 'news/admin', to: "articles#admin"
|
||||
get 'articles/cleanup'
|
||||
|
||||
match "news", to: "articles#news_index"
|
||||
match "news/archive", to: "articles#news_archive"
|
||||
match "news/admin", to: "articles#admin"
|
||||
match "articles/cleanup"
|
||||
get 'data_files/admin'
|
||||
get 'data_files/addFile'
|
||||
get 'data_files/delFile'
|
||||
get 'data_files/trash'
|
||||
|
||||
match "data_files/admin"
|
||||
match "data_files/addFile"
|
||||
match "data_files/delFile"
|
||||
match "data_files/trash"
|
||||
get 'contesters/recalc'
|
||||
|
||||
match "contesters/recalc"
|
||||
get 'directories', to: "directories#show", id: 1
|
||||
|
||||
match "directories", to: "directories#show", id: 1
|
||||
get 'gathers/refresh'
|
||||
get 'gathers/latest/:game', to: "gathers#latest", via: :get
|
||||
get 'gather', to: "gathers#latest", game: "ns2", via: :get
|
||||
|
||||
match "gathers/refresh"
|
||||
match "gathers/latest/:game", to: "gathers#latest", via: :get
|
||||
match "gather", to: "gathers#latest", game: "ns2", via: :get
|
||||
get 'gatherers/:id/status', to: "gatherers#status", via: :post
|
||||
|
||||
match "gatherers/:id/status", to: "gatherers#status", via: :post
|
||||
get 'groups/addUser'
|
||||
get 'groups/delUser'
|
||||
|
||||
match "groups/addUser"
|
||||
match "groups/delUser"
|
||||
get 'movies/download'
|
||||
get 'movies/preview'
|
||||
get 'movies/snapshot'
|
||||
|
||||
match "movies/download"
|
||||
match "movies/preview"
|
||||
match "movies/snapshot"
|
||||
get 'plugin/user'
|
||||
|
||||
match "plugin/user"
|
||||
get 'users/forgot'
|
||||
get 'users/recover'
|
||||
get 'users/agenda'
|
||||
post 'users/logout'
|
||||
post 'users/login'
|
||||
|
||||
match "users/forgot"
|
||||
match "users/recover"
|
||||
match "users/agenda"
|
||||
match "users/logout"
|
||||
match "users/login"
|
||||
get 'users/agenda'
|
||||
get 'users/login'
|
||||
get 'users/logout'
|
||||
get 'users/popup'
|
||||
get 'users/forgot', to: "users#forgot"
|
||||
|
||||
match "users/agenda"
|
||||
match "users/login"
|
||||
match "users/logout"
|
||||
match "users/popup"
|
||||
match "users/forgot", to: "users#forgot"
|
||||
get 'votes/create'
|
||||
|
||||
match "votes/create"
|
||||
match "polls/showvotes/:id", to: "polls#showvotes", as: "polls_showvotes"
|
||||
get ':controller/:action', requirements: { action: /A-Za-z/ }
|
||||
get ':controller/:action/:id'
|
||||
get ':controller/:action/:id.:format'
|
||||
get ':controller/:action/:id/:id2'
|
||||
|
||||
get "custom_urls", to: "custom_urls#administrate"
|
||||
resources :custom_urls, only: [:create, :update, :destroy]
|
||||
|
||||
get ":name", to: "custom_urls#show", requirements: {name: /\A[a-z\-]{2,10}\Z/}
|
||||
|
||||
match ":controller/:action", requirements: { action: /A-Za-z/ }
|
||||
match ":controller/:action/:id"
|
||||
match ":controller/:action/:id.:format"
|
||||
match ":controller/:action/:id/:id2"
|
||||
|
||||
match "teamers/replace", to: "teamers#replace", as: "teamers_replace"
|
||||
get 'teamers/replace', to: 'teamers#replace', as: 'teamers_replace'
|
||||
end
|
||||
|
|
5
db/migrate/20190917222520_add_teamers_count_to_teams.rb
Normal file
5
db/migrate/20190917222520_add_teamers_count_to_teams.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
class AddTeamersCountToTeams < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :teams, :teamers_count, :integer
|
||||
end
|
||||
end
|
578
db/schema.rb
578
db/schema.rb
File diff suppressed because it is too large
Load diff
|
@ -3,8 +3,8 @@ version: "3"
|
|||
services:
|
||||
web:
|
||||
# Debug
|
||||
command: /bin/bash
|
||||
tty: true
|
||||
#command: /bin/bash
|
||||
#tty: true
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: Dockerfile.dev
|
||||
|
@ -19,10 +19,10 @@ services:
|
|||
- memcached
|
||||
# - redis
|
||||
db:
|
||||
# Debugd
|
||||
# Debug
|
||||
# command: bash
|
||||
#tty: true
|
||||
# command: mysqld_safe --skip-grant-tables
|
||||
command: mysqld_safe --skip-grant-tables
|
||||
image: mariadb:latest
|
||||
volumes:
|
||||
- "./db_data:/var/lib/mysql"
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
require File.dirname(__FILE__) + '/lib/acts_as_rateable'
|
||||
require 'acts_as_rateable'
|
||||
|
||||
ActiveRecord::Base.send(:include, ActiveRecord::Acts::Rateable)
|
70
lib/plugins/acts_as_rateable/lib/acts_as_rateable.rb
Normal file
70
lib/plugins/acts_as_rateable/lib/acts_as_rateable.rb
Normal file
|
@ -0,0 +1,70 @@
|
|||
module ActiveRecord
|
||||
module Acts
|
||||
module Rateable
|
||||
def self.included(base)
|
||||
base.extend(ClassMethods)
|
||||
end
|
||||
|
||||
module AssignRateWithUserId
|
||||
def <<( rate )
|
||||
r = Rating.new
|
||||
r.rate = rate
|
||||
r.rateable = proxy_owner
|
||||
r.user_id = rate.user_id
|
||||
r.save
|
||||
end
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
def acts_as_rateable(options = {})
|
||||
has_many :ratings, :as => :rateable, :dependent => :destroy, :include => :rate
|
||||
has_many :rates, :through => :ratings, :extend => AssignRateWithUserId
|
||||
|
||||
include ActiveRecord::Acts::Rateable::InstanceMethods
|
||||
extend ActiveRecord::Acts::Rateable::SingletonMethods
|
||||
end
|
||||
end
|
||||
|
||||
module SingletonMethods
|
||||
# Find all objects rated by score.
|
||||
def find_average_of( score )
|
||||
find(:all, :include => [:rates] ).collect {|i| i if i.average_rating.to_i == score }.compact
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
# Rates the object by a given score. A user object can be passed to the method.
|
||||
def rate_it( score, user_id )
|
||||
return unless score
|
||||
rate = Rate.find_or_create_by(score: score.to_i)
|
||||
rate.user_id = user_id
|
||||
rates << rate
|
||||
end
|
||||
|
||||
# Calculates the average rating. Calculation based on the already given scores.
|
||||
def average_rating
|
||||
return 0 if rates.empty?
|
||||
( rates.inject(0){|total, rate| total += rate.score }.to_f / rates.size )
|
||||
end
|
||||
|
||||
# Rounds the average rating value.
|
||||
def average_rating_round
|
||||
average_rating.round
|
||||
end
|
||||
|
||||
# Returns the average rating in percent. The maximal score must be provided or the default value (5) will be used.
|
||||
# TODO make maximum_rating automatically calculated.
|
||||
def average_rating_percent( maximum_rating = 5 )
|
||||
f = 100 / maximum_rating.to_f
|
||||
average_rating * f
|
||||
end
|
||||
|
||||
# Checks wheter a user rated the object or not.
|
||||
def rated_by?( user )
|
||||
ratings.detect {|r| r.user_id == user.id }
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,10 +1,10 @@
|
|||
class Rate < ActiveRecord::Base
|
||||
has_many :ratings
|
||||
|
||||
|
||||
validates_presence_of :score
|
||||
validates_uniqueness_of :score
|
||||
validates_numericality_of :score, :greater_than_or_equal_to => 1, :less_than_or_equal_to => 10
|
||||
|
||||
attr_accessor :user_id
|
||||
|
||||
end
|
||||
|
||||
attr_accessor :user_id
|
||||
|
||||
end
|
|
@ -1,6 +1,6 @@
|
|||
class Rating < ActiveRecord::Base
|
||||
belongs_to :rate
|
||||
belongs_to :rateable, :polymorphic => true
|
||||
|
||||
|
||||
validates_uniqueness_of :user_id, :scope => [:rateable_id, :rateable_type]
|
||||
end
|
3
lib/plugins/acts_as_readable/init.rb
Normal file
3
lib/plugins/acts_as_readable/init.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
require 'acts_as_readable'
|
||||
|
||||
ActiveRecord::Base.send :include, ActiveRecord::Acts::Readable
|
|
@ -1,14 +1,4 @@
|
|||
*GIT* (version numbers are overrated)
|
||||
|
||||
* 0.6 (19 Jul 2010) Rails 3 refactoring by gvarela!
|
||||
|
||||
* (16 Jun 2008) Backwards Compatibility is overrated (big updates for rails 2.1)
|
||||
|
||||
* Use ActiveRecord 2.1's dirty attribute checking instead [Asa Calow]
|
||||
* Remove last traces of #non_versioned_fields
|
||||
* Remove AR::Base.find_version and AR::Base.find_versions, rely on AR association proxies and named_scope
|
||||
* Remove #versions_count, rely on AR association counter caching.
|
||||
* Remove #versioned_attributes, basically the same as AR::Base.versioned_columns
|
||||
*SVN* (version numbers are overrated)
|
||||
|
||||
* (5 Oct 2006) Allow customization of #versions association options [Dan Peterson]
|
||||
|
|
@ -8,17 +8,21 @@ Install
|
|||
|
||||
* gem install acts_as_versioned
|
||||
|
||||
<3 GitHub
|
||||
Rubyforge project
|
||||
|
||||
* http://github.com/technoweenie/acts_as_versioned
|
||||
* http://rubyforge.org/projects/ar-versioned
|
||||
|
||||
Gemcutter FTW
|
||||
RDocs
|
||||
|
||||
* http://gemcutter.org/gems/acts_as_versioned
|
||||
* http://ar-versioned.rubyforge.org
|
||||
|
||||
Subversion
|
||||
|
||||
* http://svn.github.com/technoweenie/acts_as_versioned.git
|
||||
* http://techno-weenie.net/svn/projects/acts_as_versioned
|
||||
|
||||
Collaboa
|
||||
|
||||
* http://collaboa.techno-weenie.net/repository/browse/acts_as_versioned
|
||||
|
||||
Special thanks to Dreamer on ##rubyonrails for help in early testing. His ServerSideWiki (http://serversidewiki.com)
|
||||
was the first project to use acts_as_versioned <em>in the wild</em>.
|
182
lib/plugins/acts_as_versioned/Rakefile
Normal file
182
lib/plugins/acts_as_versioned/Rakefile
Normal file
|
@ -0,0 +1,182 @@
|
|||
require 'rubygems'
|
||||
|
||||
Gem::manage_gems
|
||||
|
||||
require 'rake/rdoctask'
|
||||
require 'rake/packagetask'
|
||||
require 'rake/gempackagetask'
|
||||
require 'rake/testtask'
|
||||
require 'rake/contrib/rubyforgepublisher'
|
||||
|
||||
PKG_NAME = 'acts_as_versioned'
|
||||
PKG_VERSION = '0.3.1'
|
||||
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
||||
PROD_HOST = "technoweenie@bidwell.textdrive.com"
|
||||
RUBY_FORGE_PROJECT = 'ar-versioned'
|
||||
RUBY_FORGE_USER = 'technoweenie'
|
||||
|
||||
desc 'Default: run unit tests.'
|
||||
task :default => :test
|
||||
|
||||
desc 'Test the calculations plugin.'
|
||||
Rake::TestTask.new(:test) do |t|
|
||||
t.libs << 'lib'
|
||||
t.pattern = 'test/**/*_test.rb'
|
||||
t.verbose = true
|
||||
end
|
||||
|
||||
desc 'Generate documentation for the calculations plugin.'
|
||||
Rake::RDocTask.new(:rdoc) do |rdoc|
|
||||
rdoc.rdoc_dir = 'rdoc'
|
||||
rdoc.title = "#{PKG_NAME} -- Simple versioning with active record models"
|
||||
rdoc.options << '--line-numbers --inline-source'
|
||||
rdoc.rdoc_files.include('README', 'CHANGELOG', 'RUNNING_UNIT_TESTS')
|
||||
rdoc.rdoc_files.include('lib/**/*.rb')
|
||||
end
|
||||
|
||||
spec = Gem::Specification.new do |s|
|
||||
s.name = PKG_NAME
|
||||
s.version = PKG_VERSION
|
||||
s.platform = Gem::Platform::RUBY
|
||||
s.summary = "Simple versioning with active record models"
|
||||
s.files = FileList["{lib,test}/**/*"].to_a + %w(README MIT-LICENSE CHANGELOG RUNNING_UNIT_TESTS)
|
||||
s.files.delete "acts_as_versioned_plugin.sqlite.db"
|
||||
s.files.delete "acts_as_versioned_plugin.sqlite3.db"
|
||||
s.files.delete "test/debug.log"
|
||||
s.require_path = 'lib'
|
||||
s.autorequire = 'acts_as_versioned'
|
||||
s.has_rdoc = true
|
||||
s.test_files = Dir['test/**/*_test.rb']
|
||||
s.add_dependency 'activerecord', '>= 1.10.1'
|
||||
s.add_dependency 'activesupport', '>= 1.1.1'
|
||||
s.author = "Rick Olson"
|
||||
s.email = "technoweenie@gmail.com"
|
||||
s.homepage = "http://techno-weenie.net"
|
||||
end
|
||||
|
||||
Rake::GemPackageTask.new(spec) do |pkg|
|
||||
pkg.need_tar = true
|
||||
end
|
||||
|
||||
desc "Publish the API documentation"
|
||||
task :pdoc => [:rdoc] do
|
||||
Rake::RubyForgePublisher.new(RUBY_FORGE_PROJECT, RUBY_FORGE_USER).upload
|
||||
end
|
||||
|
||||
desc 'Publish the gem and API docs'
|
||||
task :publish => [:pdoc, :rubyforge_upload]
|
||||
|
||||
desc "Publish the release files to RubyForge."
|
||||
task :rubyforge_upload => :package do
|
||||
files = %w(gem tgz).map { |ext| "pkg/#{PKG_FILE_NAME}.#{ext}" }
|
||||
|
||||
if RUBY_FORGE_PROJECT then
|
||||
require 'net/http'
|
||||
require 'open-uri'
|
||||
|
||||
project_uri = "http://rubyforge.org/projects/#{RUBY_FORGE_PROJECT}/"
|
||||
project_data = open(project_uri) { |data| data.read }
|
||||
group_id = project_data[/[?&]group_id=(\d+)/, 1]
|
||||
raise "Couldn't get group id" unless group_id
|
||||
|
||||
# This echos password to shell which is a bit sucky
|
||||
if ENV["RUBY_FORGE_PASSWORD"]
|
||||
password = ENV["RUBY_FORGE_PASSWORD"]
|
||||
else
|
||||
print "#{RUBY_FORGE_USER}@rubyforge.org's password: "
|
||||
password = STDIN.gets.chomp
|
||||
end
|
||||
|
||||
login_response = Net::HTTP.start("rubyforge.org", 80) do |http|
|
||||
data = [
|
||||
"login=1",
|
||||
"form_loginname=#{RUBY_FORGE_USER}",
|
||||
"form_pw=#{password}"
|
||||
].join("&")
|
||||
http.post("/account/login.php", data)
|
||||
end
|
||||
|
||||
cookie = login_response["set-cookie"]
|
||||
raise "Login failed" unless cookie
|
||||
headers = { "Cookie" => cookie }
|
||||
|
||||
release_uri = "http://rubyforge.org/frs/admin/?group_id=#{group_id}"
|
||||
release_data = open(release_uri, headers) { |data| data.read }
|
||||
package_id = release_data[/[?&]package_id=(\d+)/, 1]
|
||||
raise "Couldn't get package id" unless package_id
|
||||
|
||||
first_file = true
|
||||
release_id = ""
|
||||
|
||||
files.each do |filename|
|
||||
basename = File.basename(filename)
|
||||
file_ext = File.extname(filename)
|
||||
file_data = File.open(filename, "rb") { |file| file.read }
|
||||
|
||||
puts "Releasing #{basename}..."
|
||||
|
||||
release_response = Net::HTTP.start("rubyforge.org", 80) do |http|
|
||||
release_date = Time.now.strftime("%Y-%m-%d %H:%M")
|
||||
type_map = {
|
||||
".zip" => "3000",
|
||||
".tgz" => "3110",
|
||||
".gz" => "3110",
|
||||
".gem" => "1400"
|
||||
}; type_map.default = "9999"
|
||||
type = type_map[file_ext]
|
||||
boundary = "rubyqMY6QN9bp6e4kS21H4y0zxcvoor"
|
||||
|
||||
query_hash = if first_file then
|
||||
{
|
||||
"group_id" => group_id,
|
||||
"package_id" => package_id,
|
||||
"release_name" => PKG_FILE_NAME,
|
||||
"release_date" => release_date,
|
||||
"type_id" => type,
|
||||
"processor_id" => "8000", # Any
|
||||
"release_notes" => "",
|
||||
"release_changes" => "",
|
||||
"preformatted" => "1",
|
||||
"submit" => "1"
|
||||
}
|
||||
else
|
||||
{
|
||||
"group_id" => group_id,
|
||||
"release_id" => release_id,
|
||||
"package_id" => package_id,
|
||||
"step2" => "1",
|
||||
"type_id" => type,
|
||||
"processor_id" => "8000", # Any
|
||||
"submit" => "Add This File"
|
||||
}
|
||||
end
|
||||
|
||||
query = "?" + query_hash.map do |(name, value)|
|
||||
[name, URI.encode(value)].join("=")
|
||||
end.join("&")
|
||||
|
||||
data = [
|
||||
"--" + boundary,
|
||||
"Content-Disposition: form-data; name=\"userfile\"; filename=\"#{basename}\"",
|
||||
"Content-Type: application/octet-stream",
|
||||
"Content-Transfer-Encoding: binary",
|
||||
"", file_data, ""
|
||||
].join("\x0D\x0A")
|
||||
|
||||
release_headers = headers.merge(
|
||||
"Content-Type" => "multipart/form-data; boundary=#{boundary}"
|
||||
)
|
||||
|
||||
target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php"
|
||||
http.post(target + query, data, release_headers)
|
||||
end
|
||||
|
||||
if first_file then
|
||||
release_id = release_response.body[/release_id=(\d+)/, 1]
|
||||
raise("Couldn't get release id") unless release_id
|
||||
end
|
||||
|
||||
first_file = false
|
||||
end
|
||||
end
|
||||
end
|
1
lib/plugins/acts_as_versioned/init.rb
Normal file
1
lib/plugins/acts_as_versioned/init.rb
Normal file
|
@ -0,0 +1 @@
|
|||
require 'acts_as_versioned'
|
568
lib/plugins/acts_as_versioned/lib/acts_as_versioned.rb
Normal file
568
lib/plugins/acts_as_versioned/lib/acts_as_versioned.rb
Normal file
|
@ -0,0 +1,568 @@
|
|||
# Copyright (c) 2005 Rick Olson
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
module ActiveRecord #:nodoc:
|
||||
module Acts #:nodoc:
|
||||
# Specify this act if you want to save a copy of the row in a versioned table. This assumes there is a
|
||||
# versioned table ready and that your model has a version field. This works with optimistic locking if the lock_version
|
||||
# column is present as well.
|
||||
#
|
||||
# The class for the versioned model is derived the first time it is seen. Therefore, if you change your database schema you have to restart
|
||||
# your container for the changes to be reflected. In development mode this usually means restarting WEBrick.
|
||||
#
|
||||
# class Page < ActiveRecord::Base
|
||||
# # assumes pages_versions table
|
||||
# acts_as_versioned
|
||||
# end
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# page = Page.create(:title => 'hello world!')
|
||||
# page.version # => 1
|
||||
#
|
||||
# page.title = 'hello world'
|
||||
# page.save
|
||||
# page.version # => 2
|
||||
# page.versions.size # => 2
|
||||
#
|
||||
# page.revert_to(1) # using version number
|
||||
# page.title # => 'hello world!'
|
||||
#
|
||||
# page.revert_to(page.versions.last) # using versioned instance
|
||||
# page.title # => 'hello world'
|
||||
#
|
||||
# page.versions.earliest # efficient query to find the first version
|
||||
# page.versions.latest # efficient query to find the most recently created version
|
||||
#
|
||||
#
|
||||
# Simple Queries to page between versions
|
||||
#
|
||||
# page.versions.before(version)
|
||||
# page.versions.after(version)
|
||||
#
|
||||
# Access the previous/next versions from the versioned model itself
|
||||
#
|
||||
# version = page.versions.latest
|
||||
# version.previous # go back one version
|
||||
# version.next # go forward one version
|
||||
#
|
||||
# See ActiveRecord::Acts::Versioned::ClassMethods#acts_as_versioned for configuration options
|
||||
module Versioned
|
||||
CALLBACKS = [:set_new_version, :save_version_on_create, :save_version?, :clear_altered_attributes]
|
||||
def self.included(base) # :nodoc:
|
||||
base.extend ClassMethods
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
# == Configuration options
|
||||
#
|
||||
# * <tt>class_name</tt> - versioned model class name (default: PageVersion in the above example)
|
||||
# * <tt>table_name</tt> - versioned model table name (default: page_versions in the above example)
|
||||
# * <tt>foreign_key</tt> - foreign key used to relate the versioned model to the original model (default: page_id in the above example)
|
||||
# * <tt>inheritance_column</tt> - name of the column to save the model's inheritance_column value for STI. (default: versioned_type)
|
||||
# * <tt>version_column</tt> - name of the column in the model that keeps the version number (default: version)
|
||||
# * <tt>sequence_name</tt> - name of the custom sequence to be used by the versioned model.
|
||||
# * <tt>limit</tt> - number of revisions to keep, defaults to unlimited
|
||||
# * <tt>if</tt> - symbol of method to check before saving a new version. If this method returns false, a new version is not saved.
|
||||
# For finer control, pass either a Proc or modify Model#version_condition_met?
|
||||
#
|
||||
# acts_as_versioned :if => Proc.new { |auction| !auction.expired? }
|
||||
#
|
||||
# or...
|
||||
#
|
||||
# class Auction
|
||||
# def version_condition_met? # totally bypasses the <tt>:if</tt> option
|
||||
# !expired?
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# * <tt>if_changed</tt> - Simple way of specifying attributes that are required to be changed before saving a model. This takes
|
||||
# either a symbol or array of symbols. WARNING - This will attempt to overwrite any attribute setters you may have.
|
||||
# Use this instead if you want to write your own attribute setters (and ignore if_changed):
|
||||
#
|
||||
# def name=(new_name)
|
||||
# write_changed_attribute :name, new_name
|
||||
# end
|
||||
#
|
||||
# * <tt>extend</tt> - Lets you specify a module to be mixed in both the original and versioned models. You can also just pass a block
|
||||
# to create an anonymous mixin:
|
||||
#
|
||||
# class Auction
|
||||
# acts_as_versioned do
|
||||
# def started?
|
||||
# !started_at.nil?
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# or...
|
||||
#
|
||||
# module AuctionExtension
|
||||
# def started?
|
||||
# !started_at.nil?
|
||||
# end
|
||||
# end
|
||||
# class Auction
|
||||
# acts_as_versioned :extend => AuctionExtension
|
||||
# end
|
||||
#
|
||||
# Example code:
|
||||
#
|
||||
# @auction = Auction.find(1)
|
||||
# @auction.started?
|
||||
# @auction.versions.first.started?
|
||||
#
|
||||
# == Database Schema
|
||||
#
|
||||
# The model that you're versioning needs to have a 'version' attribute. The model is versioned
|
||||
# into a table called #{model}_versions where the model name is singlular. The _versions table should
|
||||
# contain all the fields you want versioned, the same version column, and a #{model}_id foreign key field.
|
||||
#
|
||||
# A lock_version field is also accepted if your model uses Optimistic Locking. If your table uses Single Table inheritance,
|
||||
# then that field is reflected in the versioned model as 'versioned_type' by default.
|
||||
#
|
||||
# Acts_as_versioned comes prepared with the ActiveRecord::Acts::Versioned::ActMethods::ClassMethods#create_versioned_table
|
||||
# method, perfect for a migration. It will also create the version column if the main model does not already have it.
|
||||
#
|
||||
# class AddVersions < ActiveRecord::Migration
|
||||
# def self.up
|
||||
# # create_versioned_table takes the same options hash
|
||||
# # that create_table does
|
||||
# Post.create_versioned_table
|
||||
# end
|
||||
#
|
||||
# def self.down
|
||||
# Post.drop_versioned_table
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# == Changing What Fields Are Versioned
|
||||
#
|
||||
# By default, acts_as_versioned will version all but these fields:
|
||||
#
|
||||
# [self.primary_key, inheritance_column, 'version', 'lock_version', versioned_inheritance_column]
|
||||
#
|
||||
# You can add or change those by modifying #non_versioned_columns. Note that this takes strings and not symbols.
|
||||
#
|
||||
# class Post < ActiveRecord::Base
|
||||
# acts_as_versioned
|
||||
# self.non_versioned_columns << 'comments_count'
|
||||
# end
|
||||
#
|
||||
def acts_as_versioned(options = {}, &extension)
|
||||
# don't allow multiple calls
|
||||
return if self.included_modules.include?(ActiveRecord::Acts::Versioned::ActMethods)
|
||||
|
||||
send :include, ActiveRecord::Acts::Versioned::ActMethods
|
||||
|
||||
cattr_accessor :versioned_class_name, :versioned_foreign_key, :versioned_table_name, :versioned_inheritance_column,
|
||||
:version_column, :max_version_limit, :track_altered_attributes, :version_condition, :version_sequence_name, :non_versioned_columns,
|
||||
:version_association_options
|
||||
|
||||
# legacy
|
||||
alias_method :non_versioned_fields, :non_versioned_columns
|
||||
alias_method :non_versioned_fields=, :non_versioned_columns=
|
||||
|
||||
class << self
|
||||
alias_method :non_versioned_fields, :non_versioned_columns
|
||||
alias_method :non_versioned_fields=, :non_versioned_columns=
|
||||
end
|
||||
|
||||
send :attr_accessor, :altered_attributes
|
||||
|
||||
self.versioned_class_name = options[:class_name] || "Version"
|
||||
self.versioned_foreign_key = options[:foreign_key] || self.to_s.foreign_key
|
||||
self.versioned_table_name = options[:table_name] || "#{table_name_prefix}#{base_class.name.demodulize.underscore}_versions#{table_name_suffix}"
|
||||
self.versioned_inheritance_column = options[:inheritance_column] || "versioned_#{inheritance_column}"
|
||||
self.version_column = options[:version_column] || 'version'
|
||||
self.version_sequence_name = options[:sequence_name]
|
||||
self.max_version_limit = options[:limit].to_i
|
||||
self.version_condition = options[:if] || true
|
||||
self.non_versioned_columns = [self.primary_key, inheritance_column, 'version', 'lock_version', versioned_inheritance_column]
|
||||
self.version_association_options = {
|
||||
:class_name => "#{self.to_s}::#{versioned_class_name}",
|
||||
:foreign_key => versioned_foreign_key,
|
||||
:dependent => :delete_all
|
||||
}.merge(options[:association_options] || {})
|
||||
|
||||
if block_given?
|
||||
extension_module_name = "#{versioned_class_name}Extension"
|
||||
silence_warnings do
|
||||
self.const_set(extension_module_name, Module.new(&extension))
|
||||
end
|
||||
|
||||
options[:extend] = self.const_get(extension_module_name)
|
||||
end
|
||||
|
||||
class_eval do
|
||||
has_many :versions, version_association_options do
|
||||
# finds earliest version of this record
|
||||
def earliest
|
||||
@earliest ||= order('version').first
|
||||
end
|
||||
|
||||
# find latest version of this record
|
||||
def latest
|
||||
@latest ||= order('version desc').first
|
||||
end
|
||||
end
|
||||
before_save :set_new_version
|
||||
after_create :save_version_on_create
|
||||
after_update :save_version
|
||||
after_save :clear_old_versions
|
||||
after_save :clear_altered_attributes
|
||||
|
||||
unless options[:if_changed].nil?
|
||||
self.track_altered_attributes = true
|
||||
options[:if_changed] = [options[:if_changed]] unless options[:if_changed].is_a?(Array)
|
||||
options[:if_changed].each do |attr_name|
|
||||
define_method("#{attr_name}=") do |value|
|
||||
write_changed_attribute attr_name, value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
include options[:extend] if options[:extend].is_a?(Module)
|
||||
end
|
||||
|
||||
# create the dynamic versioned model
|
||||
const_set(versioned_class_name, Class.new(ActiveRecord::Base)).class_eval do
|
||||
def self.reloadable? ; false ; end
|
||||
# find first version before the given version
|
||||
def self.before(version)
|
||||
order('version desc').
|
||||
where("#{original_class.versioned_foreign_key} = ? and version < ?", version.send(original_class.versioned_foreign_key), version.version).
|
||||
first
|
||||
end
|
||||
|
||||
# find first version after the given version.
|
||||
def self.after(version)
|
||||
order('version').
|
||||
where("#{original_class.versioned_foreign_key} = ? and version > ?", version.send(original_class.versioned_foreign_key), version.version).
|
||||
first
|
||||
end
|
||||
|
||||
def previous
|
||||
self.class.before(self)
|
||||
end
|
||||
|
||||
def next
|
||||
self.class.after(self)
|
||||
end
|
||||
|
||||
def versions_count
|
||||
page.version
|
||||
end
|
||||
end
|
||||
|
||||
versioned_class.cattr_accessor :original_class
|
||||
versioned_class.original_class = self
|
||||
versioned_class.table_name = versioned_table_name
|
||||
versioned_class.belongs_to self.to_s.demodulize.underscore.to_sym,
|
||||
:class_name => "::#{self.to_s}",
|
||||
:foreign_key => versioned_foreign_key
|
||||
versioned_class.send :include, options[:extend] if options[:extend].is_a?(Module)
|
||||
versioned_class.set_sequence_name version_sequence_name if version_sequence_name
|
||||
end
|
||||
end
|
||||
|
||||
module ActMethods
|
||||
def self.included(base) # :nodoc:
|
||||
base.extend ClassMethods
|
||||
end
|
||||
|
||||
# Finds a specific version of this record
|
||||
def find_version(version = nil)
|
||||
self.class.find_version(id, version)
|
||||
end
|
||||
|
||||
# Saves a version of the model if applicable
|
||||
def save_version
|
||||
save_version_on_create if save_version?
|
||||
end
|
||||
|
||||
# Saves a version of the model in the versioned table. This is called in the after_save callback by default
|
||||
def save_version_on_create
|
||||
rev = self.class.versioned_class.new
|
||||
self.clone_versioned_model(self, rev)
|
||||
rev.version = send(self.class.version_column)
|
||||
rev.send("#{self.class.versioned_foreign_key}=", self.id)
|
||||
rev.save
|
||||
end
|
||||
|
||||
# Clears old revisions if a limit is set with the :limit option in <tt>acts_as_versioned</tt>.
|
||||
# Override this method to set your own criteria for clearing old versions.
|
||||
def clear_old_versions
|
||||
return if self.class.max_version_limit == 0
|
||||
excess_baggage = send(self.class.version_column).to_i - self.class.max_version_limit
|
||||
if excess_baggage > 0
|
||||
sql = "DELETE FROM #{self.class.versioned_table_name} WHERE version <= #{excess_baggage} AND #{self.class.versioned_foreign_key} = #{self.id}"
|
||||
self.class.versioned_class.connection.execute sql
|
||||
end
|
||||
end
|
||||
|
||||
def versions_count
|
||||
version
|
||||
end
|
||||
|
||||
# Reverts a model to a given version. Takes either a version number or an instance of the versioned model
|
||||
def revert_to(version)
|
||||
if version.is_a?(self.class.versioned_class)
|
||||
return false unless version.send(self.class.versioned_foreign_key) == self.id and !version.new_record?
|
||||
else
|
||||
return false unless version = versions.find_by_version(version)
|
||||
end
|
||||
self.clone_versioned_model(version, self)
|
||||
self.send("#{self.class.version_column}=", version.version)
|
||||
true
|
||||
end
|
||||
|
||||
# Reverts a model to a given version and saves the model.
|
||||
# Takes either a version number or an instance of the versioned model
|
||||
def revert_to!(version)
|
||||
revert_to(version) ? save_without_revision : false
|
||||
end
|
||||
|
||||
# Temporarily turns off Optimistic Locking while saving. Used when reverting so that a new version is not created.
|
||||
def save_without_revision
|
||||
save_without_revision!
|
||||
true
|
||||
rescue
|
||||
false
|
||||
end
|
||||
|
||||
def save_without_revision!
|
||||
without_locking do
|
||||
without_revision do
|
||||
save!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Returns an array of attribute keys that are versioned. See non_versioned_columns
|
||||
def versioned_attributes
|
||||
self.attributes.keys.select { |k| !self.class.non_versioned_columns.include?(k) }
|
||||
end
|
||||
|
||||
# If called with no parameters, gets whether the current model has changed and needs to be versioned.
|
||||
# If called with a single parameter, gets whether the parameter has changed.
|
||||
def changed?(attr_name = nil)
|
||||
attr_name.nil? ?
|
||||
(!self.class.track_altered_attributes || (altered_attributes && altered_attributes.length > 0)) :
|
||||
(altered_attributes && altered_attributes.include?(attr_name.to_s))
|
||||
end
|
||||
|
||||
# keep old dirty? method
|
||||
alias_method :dirty?, :changed?
|
||||
|
||||
# Clones a model. Used when saving a new version or reverting a model's version.
|
||||
def clone_versioned_model(orig_model, new_model)
|
||||
self.versioned_attributes.each do |key|
|
||||
new_model.send("#{key}=", orig_model.send(key)) if orig_model.respond_to?(key)
|
||||
end
|
||||
|
||||
if self.class.columns_hash.include?(self.class.inheritance_column)
|
||||
if orig_model.is_a?(self.class.versioned_class)
|
||||
new_model[new_model.class.inheritance_column] = orig_model[self.class.versioned_inheritance_column]
|
||||
elsif new_model.is_a?(self.class.versioned_class)
|
||||
new_model[self.class.versioned_inheritance_column] = orig_model[orig_model.class.inheritance_column]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Checks whether a new version shall be saved or not. Calls <tt>version_condition_met?</tt> and <tt>changed?</tt>.
|
||||
def save_version?
|
||||
version_condition_met? && changed?
|
||||
end
|
||||
|
||||
# Checks condition set in the :if option to check whether a revision should be created or not. Override this for
|
||||
# custom version condition checking.
|
||||
def version_condition_met?
|
||||
case
|
||||
when version_condition.is_a?(Symbol)
|
||||
send(version_condition)
|
||||
when version_condition.respond_to?(:call) && (version_condition.arity == 1 || version_condition.arity == -1)
|
||||
version_condition.call(self)
|
||||
else
|
||||
version_condition
|
||||
end
|
||||
end
|
||||
|
||||
# Executes the block with the versioning callbacks disabled.
|
||||
#
|
||||
# @foo.without_revision do
|
||||
# @foo.save
|
||||
# end
|
||||
#
|
||||
def without_revision(&block)
|
||||
self.class.without_revision(&block)
|
||||
end
|
||||
|
||||
# Turns off optimistic locking for the duration of the block
|
||||
#
|
||||
# @foo.without_locking do
|
||||
# @foo.save
|
||||
# end
|
||||
#
|
||||
def without_locking(&block)
|
||||
self.class.without_locking(&block)
|
||||
end
|
||||
|
||||
def empty_callback() end #:nodoc:
|
||||
|
||||
protected
|
||||
# sets the new version before saving, unless you're using optimistic locking. In that case, let it take care of the version.
|
||||
def set_new_version
|
||||
self.send("#{self.class.version_column}=", self.next_version) if new_record? || (!locking_enabled? && save_version?)
|
||||
end
|
||||
|
||||
# Gets the next available version for the current record, or 1 for a new record
|
||||
def next_version
|
||||
return 1 if new_record?
|
||||
(versions.maximum('version') || 0) + 1
|
||||
end
|
||||
|
||||
# clears current changed attributes. Called after save.
|
||||
def clear_altered_attributes
|
||||
self.altered_attributes = []
|
||||
end
|
||||
|
||||
def write_changed_attribute(attr_name, attr_value)
|
||||
# Convert to db type for comparison. Avoids failing Float<=>String comparisons.
|
||||
attr_value_for_db = self.class.columns_hash[attr_name.to_s].type_cast_from_database(attr_value)
|
||||
(self.altered_attributes ||= []) << attr_name.to_s unless self.changed?(attr_name) || self.send(attr_name) == attr_value_for_db
|
||||
write_attribute(attr_name, attr_value_for_db)
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
# Finds a specific version of a specific row of this model
|
||||
def find_version(id, version = nil)
|
||||
return find(id) unless version
|
||||
|
||||
conditions = ["#{versioned_foreign_key} = ? AND version = ?", id, version]
|
||||
options = { :conditions => conditions, :limit => 1 }
|
||||
|
||||
if result = find_versions(id, options).first
|
||||
result
|
||||
else
|
||||
raise RecordNotFound, "Couldn't find #{name} with ID=#{id} and VERSION=#{version}"
|
||||
end
|
||||
end
|
||||
|
||||
# Finds versions of a specific model. Takes an options hash like <tt>find</tt>
|
||||
def find_versions(id, options = {})
|
||||
versioned_class.all({
|
||||
:conditions => ["#{versioned_foreign_key} = ?", id],
|
||||
:order => 'version' }.merge(options))
|
||||
end
|
||||
|
||||
# Returns an array of columns that are versioned. See non_versioned_columns
|
||||
def versioned_columns
|
||||
self.columns.select { |c| !non_versioned_columns.include?(c.name) }
|
||||
end
|
||||
|
||||
# Returns an instance of the dynamic versioned model
|
||||
def versioned_class
|
||||
const_get versioned_class_name
|
||||
end
|
||||
|
||||
# Rake migration task to create the versioned table using options passed to acts_as_versioned
|
||||
def create_versioned_table(create_table_options = {})
|
||||
# create version column in main table if it does not exist
|
||||
if !self.content_columns.find { |c| %w(version lock_version).include? c.name }
|
||||
self.connection.add_column table_name, :version, :integer
|
||||
end
|
||||
|
||||
self.connection.create_table(versioned_table_name, create_table_options) do |t|
|
||||
t.column versioned_foreign_key, :integer
|
||||
t.column :version, :integer
|
||||
end
|
||||
|
||||
updated_col = nil
|
||||
self.versioned_columns.each do |col|
|
||||
updated_col = col if !updated_col && %(updated_at updated_on).include?(col.name)
|
||||
self.connection.add_column versioned_table_name, col.name, col.type,
|
||||
:limit => col.limit,
|
||||
:default => col.default,
|
||||
:scale => col.scale,
|
||||
:precision => col.precision
|
||||
end
|
||||
|
||||
if type_col = self.columns_hash[inheritance_column]
|
||||
self.connection.add_column versioned_table_name, versioned_inheritance_column, type_col.type,
|
||||
:limit => type_col.limit,
|
||||
:default => type_col.default,
|
||||
:scale => type_col.scale,
|
||||
:precision => type_col.precision
|
||||
end
|
||||
|
||||
if updated_col.nil?
|
||||
self.connection.add_column versioned_table_name, :updated_at, :timestamp
|
||||
end
|
||||
end
|
||||
|
||||
# Rake migration task to drop the versioned table
|
||||
def drop_versioned_table
|
||||
self.connection.drop_table versioned_table_name
|
||||
end
|
||||
|
||||
# Executes the block with the versioning callbacks disabled.
|
||||
#
|
||||
# Foo.without_revision do
|
||||
# @foo.save
|
||||
# end
|
||||
#
|
||||
def without_revision(&block)
|
||||
class_eval do
|
||||
CALLBACKS.each do |attr_name|
|
||||
alias_method "orig_#{attr_name}".to_sym, attr_name
|
||||
alias_method attr_name, :empty_callback
|
||||
end
|
||||
end
|
||||
block.call
|
||||
ensure
|
||||
class_eval do
|
||||
CALLBACKS.each do |attr_name|
|
||||
alias_method attr_name, "orig_#{attr_name}".to_sym
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Turns off optimistic locking for the duration of the block
|
||||
#
|
||||
# Foo.without_locking do
|
||||
# @foo.save
|
||||
# end
|
||||
#
|
||||
def without_locking(&block)
|
||||
current = ActiveRecord::Base.lock_optimistically
|
||||
ActiveRecord::Base.lock_optimistically = false if current
|
||||
result = block.call
|
||||
ActiveRecord::Base.lock_optimistically = true if current
|
||||
result
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ActiveRecord::Base.send :include, ActiveRecord::Acts::Versioned
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue