Compare commits

..

17 Commits

Author SHA1 Message Date
pozorvlak
19f4ee51ed Merge pull request #891 from Growstuff/dev
Release 10
2016-05-22 16:34:18 +01:00
Cesy
7be346d92f Merge pull request #890 from maco/gem_udpate
upgrade gems and make API change for ruby-units
2016-05-22 08:54:07 +01:00
Mackenzie Morgan
51a0a33b2a upgrade gems and make API change for ruby-units 2016-05-21 16:33:42 -04:00
Mackenzie Morgan
0df52b3cd8 update paperclip 2016-05-20 11:28:55 +01:00
Daniel O'Connor
18cd8f5966 #507 #813 Add spec 2016-05-19 15:53:11 -04:00
Kevin Rio
5a31619b46 If i reply to a notification directly, it's not marked as read. #507 2016-05-19 15:53:11 -04:00
Daniel O'Connor
4b4e0cf69a $ rubocop --only HashSyntax --auto-correct
483 files inspected, 2018 offenses detected, 2018 offenses corrected
2016-05-19 15:53:11 -04:00
Mackenzie Morgan
8659ebca2d switch from less to sass
* dependency hell + bit rot on upstream libraries  prevents installation on OS X
2016-05-19 15:52:54 -04:00
Miles Gould
238e0be682 Merge branch 'upgrade_misc_dev_tools' into dev 2016-05-19 15:02:32 +01:00
Mackenzie
4324ceb8ca Merge pull request #884 from pozorvlak/bump_ruby_22x
Bump ruby to 2.2.x
2016-05-19 09:40:48 -04:00
Mackenzie
19d6c8f293 Merge pull request #882 from pozorvlak/install_all_gems_on_travis
Install *all* gems in TravisCI
2016-05-19 09:37:08 -04:00
Miles Gould
bcb74c7ed8 Merge branch 'dev' into bump_ruby_22x 2016-05-19 14:15:33 +01:00
Miles Gould
4a341bb7ab Install *all* gems in CI
Previously we were only installing the gems needed for testing. This
caused our CI to miss an incompatibility problem with a gem that was
only needed for another environment:
https://github.com/Growstuff/growstuff/pull/878#discussion_r63745751
2016-05-19 13:33:36 +01:00
Daniel O'Connor
02615dc522 $ bundle update selenium-webdriver guard guard-rspec rails factory_girl pg simplecov coveralls newrelic_rpm better_errors minitest 2016-05-17 13:33:12 +09:30
Daniel O'Connor
668f6d3a2b Fix 'app/views/harvests/_form.html.haml:39: warning: duplicated key at line 39 ignored: :class' 2016-03-29 00:43:14 +10:30
Daniel O'Connor
b0adec20e7 Fix CVE-2015-7551 (https://www.ruby-lang.org/en/news/2015/12/16/unsafe-tainted-string-usage-in-fiddle-and-dl-cve-2015-7551/) 2016-03-28 23:40:17 +10:30
Daniel O'Connor
6905cd410d Bump to current ruby 2.2.*, as there's an end of life for 2.1.* https://www.ruby-lang.org/en/news/2016/02/24/support-plan-of-ruby-2-0-0-and-2-1/ 2016-03-28 23:38:25 +10:30
291 changed files with 2325 additions and 2416 deletions

View File

@@ -1 +1 @@
2.1.8
2.2.4

View File

@@ -7,9 +7,8 @@ env:
- GROWSTUFF_SITE_NAME="Growstuff (travis)" RAILS_SECRET_TOKEN='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' GROWSTUFF_ELASTICSEARCH='false'
global:
secure: "Z5TpM2jEX4UCvNePnk/LwltQX48U2u9BRc+Iypr1x9QW2o228QJhPIOH39a8RMUrepGnkQIq9q3ZRUn98RfrJz1yThtlNFL3NmzdQ57gKgjGwfpa0e4Dwj/ZJqV2D84tDGjvdVYLP7zzaYZxQcwk/cgNpzKf/jq97HLNP7CYuf4="
bundler_args: "--without development production staging"
rvm:
- 2.1.8
- 2.2.4
before_script:
- psql -c 'create database growstuff_test;' -U postgres
script:

20
Gemfile
View File

@@ -1,20 +1,18 @@
source 'https://rubygems.org'
ruby '2.1.8'
ruby '2.2.4'
gem 'rails', '~> 4.1.11'
gem 'bundler', '>=1.1.5'
gem 'sass-rails', '~> 4.0.4'
gem 'sass-rails', '~> 5.0.4'
gem 'coffee-rails', '~> 4.1.0'
gem 'haml'
# Another CSS preprocessor, used for Bootstrap overrides
gem 'less', '~>2.5.0'
gem 'less-rails', '~> 2.5.0'
# CSS framework
gem 'less-rails-bootstrap', '~> 3.2.0'
gem 'bootstrap-sass', '~> 3.3.6'
gem 'font-awesome-sass'
gem 'uglifier', '~> 2.7.2' # JavaScript compressor
@@ -29,7 +27,7 @@ gem 'unicorn' # http server
gem 'pg'
gem 'figaro' # for handling config via ENV variables
gem 'cancancan', '~> 1.9' # for checking member privileges
gem 'gibbon' # for Mailchimp newsletter subscriptions
gem 'gibbon', '~>1.2.0' # for Mailchimp newsletter subscriptions
gem 'csv_shaper' # CSV export
gem 'ruby-units' # for unit conversion
@@ -46,14 +44,6 @@ gem 'activemerchant', '1.33.0',
gem 'active_utils', '1.0.5',
:path => 'vendor/gems/active_utils-1.0.5'
# less-rails depends on a JavaScript engine; we use therubyracer.
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# long term, we'll probably want node.js for performance, but this will do
# for now as it's easier for new people to install
gem 'therubyracer', '~> 0.12', :platforms => :ruby
# libv8 is needed by therubyracer and is a bit finicky
gem 'libv8', '3.16.14.7'
# Markdown formatting for updates etc
gem 'bluecloth'

View File

@@ -33,7 +33,7 @@ GEM
activesupport (= 4.1.15)
builder (~> 3.1)
erubis (~> 2.7.0)
active_link_to (1.0.2)
active_link_to (1.0.3)
actionpack
activemodel (4.1.15)
activesupport (= 4.1.15)
@@ -48,13 +48,13 @@ GEM
minitest (~> 5.1)
thread_safe (~> 0.1)
tzinfo (~> 1.1)
addressable (2.3.6)
addressable (2.4.0)
arel (5.0.1.20140414130214)
autoprefixer-rails (5.1.1)
ast (2.2.0)
autoprefixer-rails (6.3.6.1)
execjs
json
bcrypt (3.1.11)
better_errors (2.0.0)
better_errors (2.1.1)
coderay (>= 1.0.0)
erubis (>= 2.6.6)
rack (>= 0.9.0)
@@ -62,49 +62,46 @@ GEM
debug_inspector (>= 0.0.1)
bluecloth (2.2.0)
bonsai-elasticsearch-rails (0.0.4)
bootstrap-datepicker-rails (1.3.0.2)
bootstrap-datepicker-rails (1.6.1.1)
railties (>= 3.0)
bootstrap-kaminari-views (0.0.5)
kaminari (>= 0.13)
rails (>= 3.1)
bootstrap-sass (3.3.3)
autoprefixer-rails (>= 5.0.0.1)
sass (>= 3.2.19)
bootstrap_form (2.2.0)
bootstrap-sass (3.3.6)
autoprefixer-rails (>= 5.2.1)
sass (>= 3.3.4)
bootstrap_form (2.3.0)
builder (3.2.2)
byebug (3.5.1)
columnize (~> 0.8)
debugger-linecache (~> 1.2)
slop (~> 3.6)
cancancan (1.9.2)
capybara (2.4.4)
byebug (9.0.4)
cancancan (1.14.0)
capybara (2.7.1)
addressable
mime-types (>= 1.16)
nokogiri (>= 1.3.3)
rack (>= 1.0.0)
rack-test (>= 0.5.4)
xpath (~> 2.0)
capybara-email (2.4.0)
capybara-email (2.5.0)
capybara (~> 2.4)
mail
childprocess (0.5.6)
childprocess (0.5.9)
ffi (~> 1.0, >= 1.0.11)
climate_control (0.0.3)
activesupport (>= 3.0)
cliver (0.3.2)
cocaine (0.5.7)
cocaine (0.5.8)
climate_control (>= 0.0.3, < 1.0)
codemirror-rails (4.8)
codemirror-rails (5.11)
railties (>= 3.0, < 5)
coderay (1.1.0)
coffee-rails (4.1.0)
coderay (1.1.1)
coffee-rails (4.1.1)
coffee-script (>= 2.2.0)
railties (>= 4.0.0, < 5.0)
coffee-script (2.3.0)
railties (>= 4.0.0, < 5.1.x)
coffee-script (2.4.1)
coffee-script-source
execjs
coffee-script-source (1.8.0)
columnize (0.9.0)
comfortable_mexican_sofa (1.12.7)
coffee-script-source (1.10.0)
comfortable_mexican_sofa (1.12.9)
active_link_to (>= 1.0.0)
bootstrap-sass (>= 3.2.0)
bootstrap_form (>= 2.2.0)
@@ -119,20 +116,19 @@ GEM
rails (>= 4.0.0, < 5)
rails-i18n (>= 4.0.0)
sass-rails (>= 4.0.3)
commonjs (0.2.7)
coveralls (0.7.1)
multi_json (~> 1.3)
rest-client
simplecov (>= 0.7)
term-ansicolor
thor
csv_shaper (1.1.1)
concurrent-ruby (1.0.2)
coveralls (0.8.13)
json (~> 1.8)
simplecov (~> 0.11.0)
term-ansicolor (~> 1.3)
thor (~> 0.19.1)
tins (~> 1.6.0)
csv_shaper (1.2.0)
activesupport (>= 3.0.0)
dalli (2.7.2)
database_cleaner (1.5.0)
dalli (2.7.6)
database_cleaner (1.5.3)
debug_inspector (0.0.2)
debugger-linecache (1.2.0)
devise (3.5.6)
devise (3.5.10)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 3.2.6, < 5)
@@ -141,51 +137,51 @@ GEM
warden (~> 1.2.3)
diff-lcs (1.2.5)
docile (1.1.5)
domain_name (0.5.24)
unf (>= 0.0.5, < 1.0.0)
easy_translate (0.5.0)
json
thread
thread_safe
elasticsearch (1.0.6)
elasticsearch-api (= 1.0.6)
elasticsearch-transport (= 1.0.6)
elasticsearch-api (1.0.6)
elasticsearch (1.0.17)
elasticsearch-api (= 1.0.17)
elasticsearch-transport (= 1.0.17)
elasticsearch-api (1.0.17)
multi_json
elasticsearch-model (0.1.6)
elasticsearch-model (0.1.9)
activesupport (> 3)
elasticsearch (> 0.4)
hashie
elasticsearch-rails (0.1.6)
elasticsearch-transport (1.0.6)
elasticsearch-rails (0.1.9)
elasticsearch-transport (1.0.17)
faraday
multi_json
erubis (2.7.0)
excon (0.43.0)
execjs (2.6.0)
excon (0.49.0)
execjs (2.7.0)
factory_girl (4.5.0)
activesupport (>= 3.0.0)
factory_girl_rails (4.5.0)
factory_girl (~> 4.5.0)
railties (>= 3.0.0)
faraday (0.9.1)
faraday (0.9.2)
multipart-post (>= 1.2, < 3)
ffi (1.9.10)
figaro (1.0.0)
figaro (1.1.1)
thor (~> 0.14)
flickraw (0.9.8)
font-awesome-sass (4.6.2)
sass (>= 3.2)
formatador (0.2.5)
friendly_id (5.0.4)
friendly_id (5.0.5)
activerecord (>= 4.0.0)
gibbon (1.1.4)
gibbon (1.2.0)
httparty
multi_json (>= 1.3.4)
multi_json (>= 1.9.0)
gravatar-ultimate (2.0.0)
activesupport (>= 2.3.14)
rack
guard (2.12.8)
guard (2.14.0)
formatador (>= 0.2.4)
listen (>= 2.7, <= 4.0)
listen (>= 2.7, < 4.0)
lumberjack (~> 1.0)
nenv (~> 0.1)
notiffany (~> 0.0)
@@ -193,125 +189,119 @@ GEM
shellany (~> 0.0)
thor (>= 0.18.1)
guard-compat (1.2.1)
guard-rspec (4.6.2)
guard-rspec (4.6.5)
guard (~> 2.1)
guard-compat (~> 1.1)
rspec (>= 2.99.0, < 4.0)
haml (4.1.0.beta.1)
haml (4.0.7)
tilt
haml-rails (0.6.0)
haml-rails (0.9.0)
actionpack (>= 4.0.1)
activesupport (>= 4.0.1)
haml (>= 3.1, < 5.0)
haml (>= 4.0.6, < 5.0)
html2haml (>= 1.0.1)
railties (>= 4.0.1)
hashie (3.3.2)
heroku-api (0.3.22)
excon (~> 0.38)
hashie (3.4.4)
heroku-api (0.4.2)
excon (~> 0.45)
multi_json (~> 1.8)
highline (1.6.21)
hike (1.2.3)
hpricot (0.8.6)
html2haml (1.0.1)
highline (1.7.8)
html2haml (2.0.0)
erubis (~> 2.7.0)
haml (>= 4.0.0.rc.1)
hpricot (~> 0.8.6)
ruby_parser (~> 3.1.1)
http-cookie (1.0.2)
domain_name (~> 0.5)
haml (~> 4.0.0)
nokogiri (~> 1.6.0)
ruby_parser (~> 3.5)
httparty (0.13.3)
json (~> 1.8)
multi_xml (>= 0.5.2)
i18n (0.7.0)
i18n-tasks (0.7.8)
activesupport
i18n-tasks (0.9.5)
activesupport (>= 4.0.2)
ast (>= 2.1.0)
easy_translate (>= 0.5.0)
erubis
highline
highline (>= 1.7.3)
i18n
slop (>= 3.5.0)
term-ansicolor
terminal-table
jquery-rails (3.1.3)
parser (>= 2.2.3.0)
term-ansicolor (>= 1.3.2)
terminal-table (>= 1.5.1)
jquery-rails (3.1.4)
railties (>= 3.0, < 5.0)
thor (>= 0.14, < 2.0)
jquery-ui-rails (5.0.3)
jquery-ui-rails (5.0.5)
railties (>= 3.2.16)
js-routes (0.9.9)
js-routes (1.2.5)
railties (>= 3.2)
sprockets-rails
json (1.8.3)
kaminari (0.16.3)
actionpack (>= 3.0.0)
activesupport (>= 3.0.0)
kgio (2.9.2)
kramdown (1.5.0)
kgio (2.10.0)
kramdown (1.11.1)
launchy (2.4.3)
addressable (~> 2.3)
leaflet-markercluster-rails (0.7.0)
railties (>= 3.1)
leaflet-rails (0.7.4)
less (2.5.1)
commonjs (~> 0.2.7)
less-rails (2.5.0)
actionpack (>= 3.1)
less (~> 2.5.0)
less-rails-bootstrap (3.2.0)
less-rails (~> 2.5.0)
letter_opener (1.3.0)
leaflet-rails (0.7.7)
letter_opener (1.4.1)
launchy (~> 2.2)
libv8 (3.16.14.7)
listen (3.0.2)
rb-fsevent (>= 0.9.3)
rb-inotify (>= 0.9)
lumberjack (1.0.9)
listen (3.1.5)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
ruby_dep (~> 1.2)
lumberjack (1.0.10)
mail (2.6.4)
mime-types (>= 1.16, < 4)
memcachier (0.0.2)
method_source (0.8.2)
mime-types (2.99.1)
mime-types (3.0)
mime-types-data (~> 3.2015)
mime-types-data (3.2016.0221)
mimemagic (0.3.0)
mini_portile2 (2.0.0)
minitest (5.8.4)
multi_json (1.11.2)
minitest (5.9.0)
multi_json (1.11.3)
multi_xml (0.5.5)
multipart-post (2.0.0)
nenv (0.2.0)
netrc (0.10.3)
newrelic_rpm (3.9.8.273)
nenv (0.3.0)
newrelic_rpm (3.15.2.317)
nokogiri (1.6.7.2)
mini_portile2 (~> 2.0.0.rc2)
notiffany (0.0.6)
notiffany (0.1.0)
nenv (~> 0.1)
shellany (~> 0.0)
oauth (0.4.7)
omniauth (1.2.2)
oauth (0.5.1)
omniauth (1.3.1)
hashie (>= 1.2, < 4)
rack (~> 1.0)
omniauth-flickr (0.0.15)
rack (>= 1.0, < 3)
omniauth-flickr (0.0.19)
multi_json (~> 1.11.0)
omniauth-oauth (~> 1.0)
omniauth-oauth (1.0.1)
omniauth-oauth (1.1.0)
oauth
omniauth (~> 1.0)
omniauth-twitter (1.1.0)
multi_json (~> 1.3)
omniauth-oauth (~> 1.0)
omniauth-twitter (1.2.1)
json (~> 1.3)
omniauth-oauth (~> 1.1)
orm_adapter (0.5.0)
paperclip (4.3.0)
paperclip (4.3.6)
activemodel (>= 3.2.0)
activesupport (>= 3.2.0)
cocaine (~> 0.5.5)
mime-types
mimemagic (= 0.3.0)
pg (0.17.1)
parser (2.3.1.0)
ast (~> 2.2)
pg (0.18.4)
plupload-rails (1.2.1)
rails (>= 3.1)
poltergeist (1.6.0)
poltergeist (1.9.0)
capybara (~> 2.1)
cliver (~> 0.3.1)
multi_json (~> 1.0)
websocket-driver (>= 0.2.0)
pry (0.10.1)
pry (0.10.3)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
@@ -330,36 +320,31 @@ GEM
bundler (>= 1.3.0, < 2.0)
railties (= 4.1.15)
sprockets-rails (~> 2.0)
rails-i18n (4.0.3)
i18n (~> 0.6)
rails-i18n (4.0.8)
i18n (~> 0.7)
railties (~> 4.0)
rails_12factor (0.0.3)
rails_serve_static_assets
rails_stdout_logging
rails_serve_static_assets (0.0.2)
rails_stdout_logging (0.0.3)
rails_serve_static_assets (0.0.5)
rails_stdout_logging (0.0.5)
railties (4.1.15)
actionpack (= 4.1.15)
activesupport (= 4.1.15)
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
raindrops (0.13.0)
raindrops (0.16.0)
rake (11.1.2)
rb-fsevent (0.9.5)
rb-inotify (0.9.5)
rb-fsevent (0.9.7)
rb-inotify (0.9.7)
ffi (>= 0.5.0)
ref (1.0.5)
responders (1.1.2)
railties (>= 3.2, < 4.2)
rest-client (1.8.0)
http-cookie (>= 1.0.2, < 2.0)
mime-types (>= 1.16, < 3.0)
netrc (~> 0.7)
rspec (3.4.0)
rspec-core (~> 3.4.0)
rspec-expectations (~> 3.4.0)
rspec-mocks (~> 3.4.0)
rspec-activemodel-mocks (1.0.1)
rspec-activemodel-mocks (1.0.3)
activemodel (>= 3.0)
activesupport (>= 3.0)
rspec-mocks (>= 2.99, < 4.0)
@@ -380,60 +365,52 @@ GEM
rspec-mocks (~> 3.4.0)
rspec-support (~> 3.4.0)
rspec-support (3.4.1)
ruby-units (1.4.5)
ruby_parser (3.1.3)
ruby-units (2.0.0)
ruby_dep (1.3.1)
ruby_parser (3.8.2)
sexp_processor (~> 4.1)
rubyzip (1.1.7)
sass (3.2.19)
sass-rails (4.0.5)
rubyzip (1.2.0)
sass (3.4.22)
sass-rails (5.0.4)
railties (>= 4.0.0, < 5.0)
sass (~> 3.2.2)
sprockets (~> 2.8, < 3.0)
sprockets-rails (~> 2.0)
selenium-webdriver (2.47.1)
sass (~> 3.1)
sprockets (>= 2.8, < 4.0)
sprockets-rails (>= 2.0, < 4.0)
tilt (>= 1.1, < 3)
selenium-webdriver (2.53.0)
childprocess (~> 0.5)
multi_json (~> 1.0)
rubyzip (~> 1.0)
websocket (~> 1.0)
sexp_processor (4.4.4)
sexp_processor (4.7.0)
shellany (0.0.1)
simplecov (0.9.1)
simplecov (0.11.2)
docile (~> 1.1.0)
multi_json (~> 1.0)
simplecov-html (~> 0.8.0)
simplecov-html (0.8.0)
json (~> 1.8)
simplecov-html (~> 0.10.0)
simplecov-html (0.10.0)
slop (3.6.0)
sprockets (2.12.4)
hike (~> 1.2)
multi_json (~> 1.0)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
sprockets (3.6.0)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-rails (2.3.3)
actionpack (>= 3.0)
activesupport (>= 3.0)
sprockets (>= 2.8, < 4.0)
term-ansicolor (1.3.0)
term-ansicolor (1.3.2)
tins (~> 1.0)
terminal-table (1.4.5)
therubyracer (0.12.1)
libv8 (~> 3.16.14.0)
ref
terminal-table (1.5.2)
thor (0.19.1)
thread (0.1.4)
thread (0.2.2)
thread_safe (0.3.5)
tilt (1.4.1)
tins (1.3.3)
tilt (2.0.4)
tins (1.6.0)
tzinfo (1.2.2)
thread_safe (~> 0.1)
uglifier (2.7.2)
execjs (>= 0.3.0)
json (>= 1.8.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.1)
unicorn (4.8.3)
unicorn (5.1.0)
kgio (~> 2.6)
rack
raindrops (~> 0.7)
warden (1.2.6)
rack (>= 1.0)
@@ -441,11 +418,11 @@ GEM
nokogiri (>= 1.2.0)
rack (>= 1.0)
rack-test (>= 0.5.3)
websocket (1.2.2)
websocket-driver (0.5.4)
websocket (1.2.3)
websocket-driver (0.6.4)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.2)
will_paginate (3.0.7)
will_paginate (3.1.0)
xpath (2.0.0)
nokogiri (~> 1.3)
@@ -461,6 +438,7 @@ DEPENDENCIES
bonsai-elasticsearch-rails
bootstrap-datepicker-rails
bootstrap-kaminari-views
bootstrap-sass (~> 3.3.6)
bundler (>= 1.1.5)
byebug
cancancan (~> 1.9)
@@ -478,9 +456,10 @@ DEPENDENCIES
factory_girl_rails (~> 4.5.0)
figaro
flickraw
font-awesome-sass
friendly_id (~> 5.0.4)
geocoder!
gibbon
gibbon (~> 1.2.0)
gravatar-ultimate
guard
guard-rspec
@@ -494,11 +473,7 @@ DEPENDENCIES
kaminari
leaflet-markercluster-rails
leaflet-rails
less (~> 2.5.0)
less-rails (~> 2.5.0)
less-rails-bootstrap (~> 3.2.0)
letter_opener
libv8 (= 3.16.14.7)
memcachier
newrelic_rpm
omniauth
@@ -514,13 +489,15 @@ DEPENDENCIES
rspec-activemodel-mocks
rspec-rails (~> 3.4.0)
ruby-units
sass-rails (~> 4.0.4)
sass-rails (~> 5.0.4)
selenium-webdriver
therubyracer (~> 0.12)
uglifier (~> 2.7.2)
unicorn
webrat
will_paginate (~> 3.0)
RUBY VERSION
ruby 2.1.8p440
BUNDLED WITH
1.11.2
1.12.4

View File

@@ -32,6 +32,14 @@ frontend features. We welcome contributions -- see
* Drop in to one of our [discussion forums](http://wiki.growstuff.org/index.php/Discussion_forums) to chat to other developers, get help, etc.
* You may also be interested in our [API](http://wiki.growstuff.org/index.php/API).
The wiki is down right now, so here's what you need to do on Mac OS X to get set up.
```
gem install bundle
gem install pg -v '0.18.4' -- --with-pg-config=/Applications/Postgres.app/Contents/Versions/latest/bin/pg_config
bundle install
```
## For designers, writers, researchers, data wranglers, and other contributors
There are heaps of ways to get involved and contribute no matter what

View File

@@ -16,7 +16,6 @@
//= require jquery
//= require jquery_ujs
//= require jquery-ui/autocomplete
//= require twitter/bootstrap
//= require_tree .
//= require bootstrap-sprockets
//= require bootstrap-datepicker
//= require_tree .

View File

@@ -1,14 +0,0 @@
/*
* This is a manifest file that'll automatically include all the stylesheets available in this directory
* and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
* the top of the compiled file, but it's generally better to create a new file per style scope.
*= require_self
*= require jquery-ui/autocomplete
*= require bootstrap-datepicker
*= require leaflet
*= require leaflet.markercluster
*= require leaflet.markercluster.default
*= require custom_bootstrap/custom_bootstrap
*= require overrides.css
*= require_tree .
*/

View File

@@ -0,0 +1,7 @@
@import 'jquery-ui/autocomplete'
@import 'bootstrap-datepicker'
@import 'leaflet'
@import 'leaflet.markercluster'
@import 'leaflet.markercluster.default'
@import 'custom_bootstrap/custom_bootstrap'
@import 'overrides'

View File

@@ -1,56 +0,0 @@
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// !!! AUTOMATICALLY GENERATED FILE. DO NOT MODIFY !!!
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Core variables and mixins
@import "twitter/bootstrap/variables.less";
@import "custom_bootstrap/variables.less"; // Modify this for custom colors, font-sizes, etc
@import "twitter/bootstrap/mixins.less";
@import "custom_bootstrap/mixins.less"; // Modify this for custom mixins
// Reset and dependencies
@import "twitter/bootstrap/normalize.less";
@import "twitter/bootstrap/print.less";
@import "twitter/bootstrap/glyphicons.less";
// Core CSS
@import "twitter/bootstrap/scaffolding.less";
@import "twitter/bootstrap/type.less";
@import "twitter/bootstrap/code.less";
@import "twitter/bootstrap/grid.less";
@import "twitter/bootstrap/tables.less";
@import "twitter/bootstrap/forms.less";
@import "twitter/bootstrap/buttons.less";
// Components
@import "twitter/bootstrap/component-animations.less";
@import "twitter/bootstrap/dropdowns.less";
@import "twitter/bootstrap/button-groups.less";
@import "twitter/bootstrap/input-groups.less";
@import "twitter/bootstrap/navs.less";
@import "twitter/bootstrap/navbar.less";
@import "twitter/bootstrap/breadcrumbs.less";
@import "twitter/bootstrap/pagination.less";
@import "twitter/bootstrap/pager.less";
@import "twitter/bootstrap/labels.less";
@import "twitter/bootstrap/badges.less";
@import "twitter/bootstrap/jumbotron.less";
@import "twitter/bootstrap/thumbnails.less";
@import "twitter/bootstrap/alerts.less";
@import "twitter/bootstrap/progress-bars.less";
@import "twitter/bootstrap/media.less";
@import "twitter/bootstrap/list-group.less";
@import "twitter/bootstrap/panels.less";
@import "twitter/bootstrap/responsive-embed.less";
@import "twitter/bootstrap/wells.less";
@import "twitter/bootstrap/close.less";
// Components w/ JavaScript
@import "twitter/bootstrap/modals.less";
@import "twitter/bootstrap/tooltip.less";
@import "twitter/bootstrap/popovers.less";
@import "twitter/bootstrap/carousel.less";
// Utility classes
@import "twitter/bootstrap/utilities.less";
@import "twitter/bootstrap/responsive-utilities.less";

View File

@@ -0,0 +1,59 @@
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// !!! AUTOMATICALLY GENERATED FILE. DO NOT MODIFY !!!
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Core variables and mixins
@import "bootstrap-sprockets"
@import "bootstrap/variables"
// Modify this for custom colors, font-sizes, etc
@import "custom_bootstrap/variables"
@import "bootstrap/mixins"
// Modify this for custom mixins
@import "custom_bootstrap/mixins"
// Reset and dependencies
@import "bootstrap/normalize"
@import "bootstrap/print"
@import "bootstrap/glyphicons"
// Core CSS
@import "bootstrap/scaffolding"
@import "bootstrap/type"
@import "bootstrap/code"
@import "bootstrap/grid"
@import "bootstrap/tables"
@import "bootstrap/forms"
@import "bootstrap/buttons"
// Components
@import "bootstrap/component-animations"
@import "bootstrap/dropdowns"
@import "bootstrap/button-groups"
@import "bootstrap/input-groups"
@import "bootstrap/navs"
@import "bootstrap/navbar"
@import "bootstrap/breadcrumbs"
@import "bootstrap/pagination"
@import "bootstrap/pager"
@import "bootstrap/labels"
@import "bootstrap/badges"
@import "bootstrap/jumbotron"
@import "bootstrap/thumbnails"
@import "bootstrap/alerts"
@import "bootstrap/progress-bars"
@import "bootstrap/media"
@import "bootstrap/list-group"
@import "bootstrap/panels"
@import "bootstrap/responsive-embed"
@import "bootstrap/wells"
@import "bootstrap/close"
// Components w/ JavaScript
@import "bootstrap/modals"
@import "bootstrap/tooltip"
@import "bootstrap/popovers"
@import "bootstrap/carousel"
// Utility classes
@import "bootstrap/utilities"
@import "bootstrap/responsive-utilities"

View File

@@ -1,54 +0,0 @@
// Use this file to override Twitter Bootstrap variables or define own variables.
// Import original variables so they can be used in overrides
@import "twitter/bootstrap/variables.less";
// Base colours
@beige: #f3f1ee;
@brown: #413f3b;
@green: #5f8e43;
@blue: #2f4365;
@red: #8e4d43;
@orange: #b2685c;
@yellow: #b2935c;
@body-bg: @beige;
@text-color: @brown;
@link-color: @green;
@brand-primary: @green;
@font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif;
@font-family-serif: Georgia, "Times New Roman", Times, serif;
@font-family-mono: Monaco, Menlo, Consolas, "Courier New", monospace;
@font-size-base: 14px;
@font-family-base: @font-family-sans-serif;
@line-height-base: 1.5;
@alt-font-family: @font-family-serif;
@headings-font-family: @font-family-sans-serif;
@headings-font-weight: bold; // instead of browser default, bold
@headings-color: inherit; // empty to use BS default, @textColor
// Hero unit
@jumbotron-bg: darken(@body-bg, 10%);
// Nav bar
@navbar-default-bg: @brown;
@navbar-default-bg-highlight: @brown;
@navbar-default-color: @beige;
@navbar-default-link-color: darken(@beige, 20%);
@navbar-default-link-hover-color: @beige;
@navbar-default-link-active-color: @beige;
@navbar-default-brand-color: lighten(@green, 20%);
// Top nav collapse threshold
@grid-float-breakpoint: @screen-md-min;
@dropdown-bg: lighten(@beige, 10%);
@dropdown-link-color: @brown;
@dropdown-link-hover-color: @brown;
@dropdown-link-hover-bg: lighten(@green, 50%);

View File

@@ -0,0 +1,54 @@
// Use this file to override Twitter Bootstrap variables or define own variables.
// Import original variables so they can be used in overrides
//@import 'bootstrap/variables.scss'
// Base colours
$beige: #f3f1ee
$brown: #413f3b
$green: #5f8e43
$blue: #2f4365
$red: #8e4d43
$orange: #b2685c
$yellow: #b2935c
$body-bg: $beige
$text-color: $brown
$link-color: $green
$brand-primary: $green
$font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif
$font-family-serif: Georgia, "Times New Roman", Times, serif
$font-family-mono: Monaco, Menlo, Consolas, "Courier New", monospace
$font-size-base: 14px
$font-family-base: $font-family-sans-serif
$line-height-base: 1.5
$alt-font-family: $font-family-serif
$headings-font-family: $font-family-sans-serif
$headings-font-weight: bold // instead of browser default, bold
$headings-color: inherit // empty to use BS default, $textColor
// Hero unit
$jumbotron-bg: darken($body-bg, 10%)
// Nav bar
$navbar-default-bg: $brown
$navbar-default-bg-highlight: $brown
$navbar-default-color: $beige
$navbar-default-link-color: darken($beige, 20%)
$navbar-default-link-hover-color: $beige
$navbar-default-link-active-color: $beige
$navbar-default-brand-color: lighten($green, 20%)
// Top nav collapse threshold
$grid-float-breakpoint: $screen-md-min
$dropdown-bg: lighten($beige, 10%)
$dropdown-link-color: $brown
$dropdown-link-hover-color: $brown
$dropdown-link-hover-bg: lighten($green, 50%)

View File

@@ -1,10 +0,0 @@
.leaflet-popup-content-wrapper, .leaflet-popup-tip {
border: none;
}
.thumbnail{
background: #fff !important;
border: solid 1px whitesmoke;
}
.thumbnail .crop-thumbnail .cropinfo{
padding-top: 14px;
}

View File

@@ -0,0 +1,10 @@
.leaflet-popup-content-wrapper,
.leaflet-popup-tip
border: none
.thumbnail
background: #fff !important
border: solid 1px whitesmoke
.thumbnail .crop-thumbnail .cropinfo
padding-top: 14px

View File

@@ -1,360 +0,0 @@
@import "twitter/bootstrap/bootstrap";
@import "custom_bootstrap/variables";
// this padding needs to be done before the responsive stuff is imported
body {
// modifying this for our promotional banner. can be replaced after if
// needed.
// padding-top: @navbar-height + 15px;
padding-top: @navbar-height;
}
//@import "twitter/bootstrap/responsive";
// Set the correct sprite paths
@iconSpritePath: asset-path("twitter/bootstrap/glyphicons-halflings");
@iconWhiteSpritePath: asset-path("twitter/bootstrap/glyphicons-halflings-white");
// Set the Font Awesome (Font Awesome is default. You can disable by commenting below lines)
@fontAwesomeEotPath: asset-url("fontawesome-webfont.eot");
@fontAwesomeEotPath_iefix: asset-url("fontawesome-webfont.eot#iefix");
@fontAwesomeWoffPath: asset-url("fontawesome-webfont.woff");
@fontAwesomeTtfPath: asset-url("fontawesome-webfont.ttf");
@fontAwesomeSvgPath: asset-url("fontawesome-webfont.svg#fontawesomeregular");
// Font Awesome
//@import "fontawesome/font-awesome";
// Glyphicons
//@import "twitter/bootstrap/sprites.less";
.list-inline > li.first {
padding-left: 0px;
}
h2 {
font-size: 150%;
}
/*
#subtitle {
color: lighten(@brown, 30%);
margin-top: 0px;
padding-top: 0px;
padding-left: 1em;
font-style: italic;
font-weight: normal;
}
*/
h3 {
font-size: 120%;
}
.main {
padding-right: 1em;
}
.sidebar {
margin-left: -1px;
border-left: 1px solid darken(@beige, 10%);
padding-left: 1em;
}
// this is used for eg. crops and members index pages
.six-across:nth-child(6n+1) {
margin-left: 0px
}
.three-across:nth-child(3n+1) {
margin-left: 0px;
clear: both;
}
// let's condense the hero unit a little
.jumbotron {
padding-top: 30px;
padding-bottom: 30px;
}
// info under the main heading on homepage
.jumbotron .info {
padding-top: 15px;
}
// signup widget on homepage
.jumbotron .signup {
background-color: lighten(@green, 40%);
border: 1px solid lighten(@green, 20%);
border-radius: 6px;
padding: 15px;
text-align: center;
line-height: 200%;
}
// stats shown on homepage. eg. "999 members..."
p.stats {
font-weight: bold;
}
.member-cards {
display: flex;
flex: none;
flex-wrap: wrap;
justify-content: space-between;
}
.member-thumbnail {
padding: .25em;
div {
width: 5em;
display: inline-block;
vertical-align: top;
}
div ~ div {
width: 15em;
padding-left: 1em;
}
}
#placesmap, #cropmap {
height: 500px;
}
#membermap {
height: 250px;
}
.member-location {
font-size: small;
font-style: italic;
}
.member-location a {
color: @brown;
}
.photo-thumbnail {
position:relative;
padding:0;
img {
width:100%;
}
.text {
display:none;
color:#000;
position:absolute;
bottom:0;
background:rgba(0, 0, 0, 0.8);
width:100%;
margin:0;
}
p {
padding:5px;
margin:0;
color:#fff;
}
&:hover {
.text {
display:block;
}
}
}
.thumbnail {
border: none;
text-align: center;
margin-bottom: 1.5em;
.member-thumbnail {
text-align: left;
img {
height: 85px;
width: 85px;
max-width: 85px
}
}
.crop-thumbnail {
height: 220px;
.cropinfo {
display: inline-block;
max-width: 100%;
white-space: nowrap;
line-height: 1em;
padding-bottom: 2px;
.cropname {
overflow: hidden;
text-overflow: ellipsis;
}
.scientificname {
font-size: small;
font-style: italic;
overflow: hidden;
text-overflow: ellipsis;
}
.plantingcount {
font-size: small;
}
}
.crop-name a {
padding-top: 2px;
}
.scientific-name small {
margin-bottom: -2px;
}
}
}
li.crop-hierarchy {
list-style-type: disc;
}
.navbar-brand {
margin: 0px;
padding: 0px;
}
.navbar-bottom {
margin: 40px 0px 0px 0px !important;
}
// footer
footer {
#footer1, #footer2, #footer3 {
text-align: left;
padding-top: 1em;
padding-bottom: 2em;
ul {
list-style-type: none;
list-style-position: outside;
padding-left: 0px;
margin-left: 0px;
}
a {
color: @navbar-default-link-color;
text-decoration: none;
}
a:hover {
color: @navbar-default-link-hover-color;
}
a:active {
color: @navbar-default-link-active-color;
}
}
.navbar-bottom.navbar {
border-radius: 0;
}
}
// ensure footer is pushed to bottom of browser window
#maincontainer {
min-height: 80%;
}
html, body {
height: 100%;
}
//
.crop-image, .member-image {
width: 100%;
height: 100%;
}
// Autosuggest
.ui-autocomplete {
z-index: @zindex-tooltip;
}
// Crowdfunding campaign, Sep-Oct 2014
.crowdfunding-banner {
text-align: center;
font-weight: bold;
background-color: lighten(@green, 30%);
margin-top: 0px;
margin-bottom: 5px;
padding: 15px;
}
.crowdfunding-banner a {
color: @brown;
text-decoration: underline;
}
.alert {
a {
font-weight: 800;
}
}
// Overrides applying only to mobile view. This must be at the end of the overrides file.
@media only screen and (max-width: 767px) {
.sidebar {
margin-left: 0;
border-left: none;
padding-left: 0;
}
#map {
height: 300px;
}
.navbar .nav > li {
display: block;
}
}
/* override "info" alert boxes to be green, not blue, on Growstuff */
@state-info-text: darken(@green, 10%);
@state-info-bg: lighten(@green, 50%);
/* and set "success" to be the same, as it was just very slightly
* different because the default bootstrap green is slightly different
* from ours */
@state-success-text: darken(@green, 10%);
@state-success-bg: lighten(@green, 50%);
.hide {
display: none;
}
#add-sci_name-row, #remove-sci_name-row, #add-alt_name-row, #remove-alt_name-row{
display: none;
}
.panel-footer{
height: 6em;
}
#gardens_panel_body{
height: 20em;
}
.form-group.required .control-label:before {
content: "* ";
color: red;
}
.margin-bottom {
margin-bottom: 1em;
}
.red {
color: red;
}

View File

@@ -0,0 +1,290 @@
@import "bootstrap-sprockets"
@import "bootstrap"
@import "custom_bootstrap/variables"
// this padding needs to be done before the responsive stuff is imported
body
// modifying this for our promotional banner. can be replaced after if
// needed.
// padding-top: $navbar-height + 15px
padding-top: $navbar-height
//@import "bootstrap/responsive"
// Font Awesome
@import "font-awesome-sprockets"
@import "font-awesome"
// Glyphicons
//@import "bootstrap/glyphicons"
.list-inline > li.first
padding-left: 0px
h2
font-size: 150%
//#subtitle
// color: lighten($brown, 30%)
// font-style: italic
// font-weight: normal
// margin-top: 0px
// padding-left: 1em
// padding-top: 0px
h3
font-size: 120%
.main
padding-right: 1em
.sidebar
border-left: 1px solid darken($beige, 10%)
margin-left: -1px
padding-left: 1em
// this is used for eg. crops and members index pages
.six-across:nth-child(6n+1)
margin-left: 0px
.three-across:nth-child(3n+1)
margin-left: 0px
clear: both
// let's condense the hero unit a little
.jumbotron
padding-top: 30px
padding-bottom: 30px
// info under the main heading on homepage
.jumbotron .info
padding-top: 15px
// signup widget on homepage
.jumbotron .signup
background-color: lighten($green, 40%)
border: 1px solid lighten($green, 20%)
border-radius: 6px
line-height: 200%
padding: 15px
text-align: center
// stats shown on homepage. eg. "999 members..."
p.stats
font-weight: bold
.member-cards
display: flex
flex: none
flex-wrap: wrap
justify-content: space-between
.member-thumbnail
padding: .25em
div
width: 5em
display: inline-block
vertical-align: top
.member-thumbnail div~div
padding-left: 1em
width: 15em
#placesmap, #cropmap
height: 500px
#membermap
height: 250px
.member-location
font-size: small
font-style: italic
.member-location a
color: $brown
.photo-thumbnail
padding: 0
position: relative
img
width: 100%
.text
display: none
color: #000
position: absolute
bottom: 0
background: rgba(0, 0, 0, 0.8)
width: 100%
margin: 0
p
padding: 5px
margin: 0
color: #fff
&:hover
.text
display: block
.thumbnail
border: none
text-align: center
margin-bottom: 1.5em
.member-thumbnail
text-align: left
img
height: 85px
width: 85px
max-width: 85px
.crop-thumbnail
height: 220px
.cropinfo
display: inline-block
max-width: 100%
white-space: nowrap
line-height: 1em
padding-bottom: 2px
.cropname
overflow: hidden
text-overflow: ellipsis
.scientificname
font-size: small
font-style: italic
overflow: hidden
text-overflow: ellipsis
.plantingcount
font-size: small
.crop-name a
padding-top: 2px
.scientific-name small
margin-bottom: -2px
li.crop-hierarchy
list-style-type: disc
.navbar-brand
margin: 0px
padding: 0px
.navbar-bottom
margin: 40px 0px 0px 0px !important
// footer
footer
#footer1, #footer2, #footer3
text-align: left
padding-top: 1em
padding-bottom: 2em
ul
list-style-type: none
list-style-position: outside
padding-left: 0px
margin-left: 0px
a
color: $navbar-default-link-color
text-decoration: none
a:hover
color: $navbar-default-link-hover-color
a:active
color: $navbar-default-link-active-color
.navbar-bottom.navbar
border-radius: 0
// ensure footer is pushed to bottom of browser window
#maincontainer
min-height: 80%
html, body
height: 100%
.crop-image, .member-image
width: 100%
height: 100%
// Autosuggest
.ui-autocomplete
z-index: $zindex-tooltip
// Crowdfunding campaign, Sep-Oct 2014
.crowdfunding-banner
text-align: center
font-weight: bold
background-color: lighten($green, 30%)
margin-top: 0px
margin-bottom: 5px
padding: 15px
.crowdfunding-banner a
color: $brown
text-decoration: underline
.alert
a
font-weight: 800
// Overrides applying only to mobile view. This must be at the end of the overrides file.
@media only screen and (max-width: 767px)
.sidebar
margin-left: 0
border-left: none
padding-left: 0
#map
height: 300px
.navbar .nav > li
display: block
/* override "info" alert boxes to be green, not blue, on Growstuff */
$state-info-text: darken($green, 10%)
$state-info-bg: lighten($green, 50%)
/* and set "success" to be the same, as it was just very slightly
* different because the default bootstrap green is slightly different
* from ours */
$state-success-text: darken($green, 10%)
$state-success-bg: lighten($green, 50%)
.hide
display: none
#add-sci_name-row, #remove-sci_name-row, #add-alt_name-row, #remove-alt_name-row
display: none
.panel-footer
height: 6em
#gardens_panel_body
height: 20em
.form-group.required .control-label:before
content: "* "
color: red
.margin-bottom
margin-bottom: 1em
.red
color: red

View File

@@ -8,7 +8,7 @@ class Admin::OrdersController < ApplicationController
def search
authorize! :manage, :all
@orders = Order.search({:by => params[:search_by], :for => params[:search_text]})
@orders = Order.search({by: params[:search_by], for: params[:search_text]})
if @orders.empty?
flash[:alert] = "Couldn't find order with #{params[:search_by]} = #{params[:search_text]}"

View File

@@ -1,5 +1,5 @@
class AlternateNamesController < ApplicationController
before_filter :authenticate_member!, :except => [:index, :show]
before_filter :authenticate_member!, except: [:index, :show]
load_and_authorize_resource
# GET /alternate_names

View File

@@ -35,7 +35,7 @@ class ApplicationController < ActionController::Base
# CanCan error handling
rescue_from CanCan::AccessDenied do |exception|
redirect_to request.referer || root_url, :alert => exception.message
redirect_to request.referer || root_url, alert: exception.message
end
def set_locale

View File

@@ -20,14 +20,14 @@ class AuthenticationsController < ApplicationController
@authentication = current_member.authentications
.create_with(
:name => name,
:token => auth['credentials']['token'],
:secret => auth['credentials']['secret']
name: name,
token: auth['credentials']['token'],
secret: auth['credentials']['secret']
)
.find_or_create_by(
:provider => auth['provider'],
:uid => auth['uid'],
:name => name)
provider: auth['provider'],
uid: auth['uid'],
name: name)
flash[:notice] = "Authentication successful."
else

View File

@@ -1,16 +1,16 @@
class CommentsController < ApplicationController
before_filter :authenticate_member!, :except => [:index, :show]
before_filter :authenticate_member!, except: [:index, :show]
load_and_authorize_resource
# GET /comments
# GET /comments.json
def index
@comments = Comment.paginate(:page => params[:page])
@comments = Comment.paginate(page: params[:page])
respond_to do |format|
format.html # index.html.erb
format.json { render json: @comments }
format.rss { render :layout => false }
format.rss { render layout: false }
end
end
@@ -39,7 +39,7 @@ class CommentsController < ApplicationController
end
else
redirect_to request.referer || root_url,
:alert => "Can't post a comment on a non-existent post"
alert: "Can't post a comment on a non-existent post"
end
end

View File

@@ -1,9 +1,9 @@
require 'will_paginate/array'
class CropsController < ApplicationController
before_filter :authenticate_member!, :except => [:index, :hierarchy, :search, :show]
before_filter :authenticate_member!, except: [:index, :hierarchy, :search, :show]
load_and_authorize_resource
skip_authorize_resource :only => [:hierarchy, :search]
skip_authorize_resource only: [:hierarchy, :search]
# GET /crops
# GET /crops.json
@@ -11,25 +11,25 @@ class CropsController < ApplicationController
@sort = params[:sort]
if @sort == 'alpha'
# alphabetical order
@crops = Crop.includes(:scientific_names, {:plantings => :photos})
@paginated_crops = @crops.approved.paginate(:page => params[:page])
@crops = Crop.includes(:scientific_names, {plantings: :photos})
@paginated_crops = @crops.approved.paginate(page: params[:page])
else
# default to sorting by popularity
@crops = Crop.popular.includes(:scientific_names, {:plantings => :photos})
@paginated_crops = @crops.approved.paginate(:page => params[:page])
@crops = Crop.popular.includes(:scientific_names, {plantings: :photos})
@paginated_crops = @crops.approved.paginate(page: params[:page])
end
respond_to do |format|
format.html
format.json { render :json => @crops }
format.json { render json: @crops }
format.rss do
@crops = Crop.recent.includes(:scientific_names, :creator)
render :rss => @crops
render rss: @crops
end
format.csv do
@filename = "Growstuff-Crops-#{Time.zone.now.to_s(:number)}.csv"
@crops = Crop.includes(:scientific_names, :plantings, :seeds, :creator)
render :csv => @crops
render csv: @crops
end
end
end
@@ -46,7 +46,7 @@ class CropsController < ApplicationController
@crops = Crop.recent
end
@crops = @crops.paginate(:page => params[:page])
@crops = @crops.paginate(page: params[:page])
@crop_wranglers = Role.crop_wranglers
respond_to do |format|
@@ -66,25 +66,25 @@ class CropsController < ApplicationController
def search
@term = params[:term]
@matches = Crop.search(@term)
@paginated_matches = @matches.paginate(:page => params[:page])
@paginated_matches = @matches.paginate(page: params[:page])
respond_to do |format|
format.html
format.json { render :json => @matches }
format.json { render json: @matches }
end
end
# GET /crops/1
# GET /crops/1.json
def show
@crop = Crop.includes(:scientific_names, {:plantings => :photos}).find(params[:id])
@posts = @crop.posts.paginate(:page => params[:page])
@crop = Crop.includes(:scientific_names, {plantings: :photos}).find(params[:id])
@posts = @crop.posts.paginate(page: params[:page])
respond_to do |format|
format.html # show.html.haml
format.json do
render :json => @crop.to_json(:include => {
:plantings => { :include => { :owner => { :only => [:id, :login_name, :location, :latitude, :longitude] }}}
render json: @crop.to_json(include: {
plantings: { include: { owner: { only: [:id, :login_name, :location, :latitude, :longitude] }}}
})
end
end
@@ -207,6 +207,6 @@ class CropsController < ApplicationController
private
def crop_params
params.require(:crop).permit(:en_wikipedia_url, :name, :parent_id, :creator_id, :approval_status, :request_notes, :reason_for_rejection, :rejection_notes, :scientific_names_attributes => [:scientific_name, :_destroy, :id])
params.require(:crop).permit(:en_wikipedia_url, :name, :parent_id, :creator_id, :approval_status, :request_notes, :reason_for_rejection, :rejection_notes, scientific_names_attributes: [:scientific_name, :_destroy, :id])
end
end

View File

@@ -1,12 +1,12 @@
class FollowsController < ApplicationController
before_filter :authenticate_member!
load_and_authorize_resource
skip_load_resource :only => :create
skip_load_resource only: :create
# POST /follows
def create
@follow = current_member.follows.build(:followed_id => follow_params[:followed_id])
@follow = current_member.follows.build(followed_id: follow_params[:followed_id])
if @follow.save
flash[:notice] = "Followed #{ @follow.followed.login_name }"

View File

@@ -1,15 +1,15 @@
class GardensController < ApplicationController
before_filter :authenticate_member!, :except => [:index, :show]
before_filter :authenticate_member!, except: [:index, :show]
load_and_authorize_resource
# GET /gardens
# GET /gardens.json
def index
@gardens = Garden.paginate(:page => params[:page])
@gardens = Garden.paginate(page: params[:page])
@owner = Member.find_by_slug(params[:owner])
if @owner
@gardens = @owner.gardens.paginate(:page => params[:page])
@gardens = @owner.gardens.paginate(page: params[:page])
end
respond_to do |format|
@@ -87,7 +87,7 @@ class GardensController < ApplicationController
expire_fragment("homepage_stats")
respond_to do |format|
format.html { redirect_to gardens_by_owner_path(:owner => @garden.owner), notice: 'Garden was successfully deleted.' }
format.html { redirect_to gardens_by_owner_path(owner: @garden.owner), notice: 'Garden was successfully deleted.' }
format.json { head :no_content }
end
end

View File

@@ -1,5 +1,5 @@
class HarvestsController < ApplicationController
before_filter :authenticate_member!, :except => [:index, :show]
before_filter :authenticate_member!, except: [:index, :show]
load_and_authorize_resource
@@ -17,12 +17,12 @@ class HarvestsController < ApplicationController
end
respond_to do |format|
format.html { @harvests = @harvests.paginate(:page => params[:page]) }
format.html { @harvests = @harvests.paginate(page: params[:page]) }
format.json { render json: @harvests }
format.csv do
specifics = (@owner ? "#{@owner.login_name}-" : @crop ? "#{@crop.name}-" : nil)
@filename = "Growstuff-#{specifics}Harvests-#{Time.zone.now.to_s(:number)}.csv"
render :csv => @harvests
render csv: @harvests
end
end
end

View File

@@ -1,21 +1,21 @@
class MembersController < ApplicationController
load_and_authorize_resource
skip_authorize_resource :only => [:nearby, :unsubscribe]
skip_authorize_resource only: [:nearby, :unsubscribe]
after_action :expire_cache_fragments, :only => :create
after_action :expire_cache_fragments, only: :create
def index
@sort = params[:sort]
if @sort == 'recently_joined'
@members = Member.confirmed.recently_joined.paginate(:page => params[:page])
@members = Member.confirmed.recently_joined.paginate(page: params[:page])
else
@members = Member.confirmed.paginate(:page => params[:page])
@members = Member.confirmed.paginate(page: params[:page])
end
respond_to do |format|
format.html # index.html.haml
format.json { render :json => @members.to_json(:only => [:id, :login_name, :slug, :bio, :created_at, :location, :latitude, :longitude]) }
format.json { render json: @members.to_json(only: [:id, :login_name, :slug, :bio, :created_at, :location, :latitude, :longitude]) }
end
end
@@ -31,22 +31,22 @@ class MembersController < ApplicationController
respond_to do |format|
format.html # show.html.haml
format.json { render :json => @member.to_json(:only => [:id, :login_name, :bio, :created_at, :slug, :location, :latitude, :longitude]) }
format.json { render json: @member.to_json(only: [:id, :login_name, :bio, :created_at, :slug, :location, :latitude, :longitude]) }
format.rss { render(
:layout => false,
:locals => { :member => @member }
layout: false,
locals: { member: @member }
)}
end
end
def view_follows
@member = Member.confirmed.find(params[:login_name])
@follows = @member.followed.paginate(:page => params[:page])
@follows = @member.followed.paginate(page: params[:page])
end
def view_followers
@member = Member.confirmed.find(params[:login_name])
@followers = @member.followers.paginate(:page => params[:page])
@followers = @member.followers.paginate(page: params[:page])
end
EMAIL_TYPE_STRING = {

View File

@@ -40,6 +40,8 @@ class NotificationsController < ApplicationController
def reply
@notification = Notification.new
@sender_notification = Notification.find(params[:id])
@sender_notification.read = true
@sender_notification.save
@recipient = @sender_notification.sender
@subject = @sender_notification.subject =~ /^Re: / ?
@sender_notification.subject :

View File

@@ -8,7 +8,7 @@ class OrderItemsController < ApplicationController
params[:order_item][:price] = params[:order_item][:price].to_f * 100 # convert to cents
end
@order_item = OrderItem.new(order_item_params)
@order_item.order = current_member.current_order || Order.create(:member_id => current_member.id)
@order_item.order = current_member.current_order || Order.create(member_id: current_member.id)
respond_to do |format|
if @order_item.save

View File

@@ -34,15 +34,15 @@ class OrdersController < ApplicationController
@order = Order.find(params[:id])
respond_to do |format|
if @order.update_attributes(:referral_code => params[:referral_code])
if @order.update_attributes(referral_code: params[:referral_code])
response = EXPRESS_GATEWAY.setup_purchase(
@order.total,
:items => @order.activemerchant_items,
:currency => Growstuff::Application.config.currency,
:no_shipping => true,
:ip => request.remote_ip,
:return_url => complete_order_url,
:cancel_return_url => shop_url
items: @order.activemerchant_items,
currency: Growstuff::Application.config.currency,
no_shipping: true,
ip: request.remote_ip,
return_url: complete_order_url,
cancel_return_url: shop_url
)
format.html { redirect_to EXPRESS_GATEWAY.redirect_url_for(response.token) }
else
@@ -58,10 +58,10 @@ class OrdersController < ApplicationController
if (params[:token] && params['PayerID'])
purchase = EXPRESS_GATEWAY.purchase(
@order.total,
:currency => Growstuff::Application.config.currency,
:ip => request.remote_ip,
:payer_id => params['PayerID'],
:token => params[:token]
currency: Growstuff::Application.config.currency,
ip: request.remote_ip,
payer_id: params['PayerID'],
token: params[:token]
)
if purchase.success?
@order.completed_at = Time.zone.now

View File

@@ -1,11 +1,11 @@
class PhotosController < ApplicationController
before_filter :authenticate_member!, :except => [:index, :show]
before_filter :authenticate_member!, except: [:index, :show]
load_and_authorize_resource
# GET /photos
# GET /photos.json
def index
@photos = Photo.paginate(:page => params[:page])
@photos = Photo.paginate(page: params[:page])
respond_to do |format|
format.html # index.html.erb

View File

@@ -5,7 +5,7 @@ class PlacesController < ApplicationController
respond_to do |format|
format.html
# json response is whatever we want to map here
format.json { render :json => Member.located.to_json(:only => [:id, :login_name, :slug, :location, :latitude, :longitude]) }
format.json { render json: Member.located.to_json(only: [:id, :login_name, :slug, :location, :latitude, :longitude]) }
end
end
@@ -16,7 +16,7 @@ class PlacesController < ApplicationController
@nearby_members = Member.nearest_to(params[:place])
respond_to do |format|
format.html # show.html.haml
format.json { render :json => @nearby_members.to_json(:only => [:id, :login_name, :slug, :location, :latitude, :longitude]) }
format.json { render json: @nearby_members.to_json(only: [:id, :login_name, :slug, :location, :latitude, :longitude]) }
end
end

View File

@@ -1,5 +1,5 @@
class PlantingsController < ApplicationController
before_filter :authenticate_member!, :except => [:index, :show]
before_filter :authenticate_member!, except: [:index, :show]
load_and_authorize_resource
# GET /plantings
@@ -8,21 +8,21 @@ class PlantingsController < ApplicationController
@owner = Member.find_by_slug(params[:owner])
@crop = Crop.find_by_slug(params[:crop])
if @owner
@plantings = @owner.plantings.includes(:owner, :crop, :garden).paginate(:page => params[:page])
@plantings = @owner.plantings.includes(:owner, :crop, :garden).paginate(page: params[:page])
elsif @crop
@plantings = @crop.plantings.includes(:owner, :crop, :garden).paginate(:page => params[:page])
@plantings = @crop.plantings.includes(:owner, :crop, :garden).paginate(page: params[:page])
else
@plantings = Planting.includes(:owner, :crop, :garden).paginate(:page => params[:page])
@plantings = Planting.includes(:owner, :crop, :garden).paginate(page: params[:page])
end
respond_to do |format|
format.html { @plantings = @plantings.paginate(:page => params[:page]) }
format.html { @plantings = @plantings.paginate(page: params[:page]) }
format.json { render json: @plantings }
format.rss { render :layout => false } #index.rss.builder
format.rss { render layout: false } #index.rss.builder
format.csv do
specifics = (@owner ? "#{@owner.login_name}-" : @crop ? "#{@crop.name}-" : nil)
@filename = "Growstuff-#{specifics}Plantings-#{Time.zone.now.to_s(:number)}.csv"
render :csv => @plantings
render csv: @plantings
end
end
end

View File

@@ -1,5 +1,5 @@
class PostsController < ApplicationController
before_filter :authenticate_member!, :except => [:index, :show]
before_filter :authenticate_member!, except: [:index, :show]
load_and_authorize_resource
# GET /posts
@@ -8,29 +8,29 @@ class PostsController < ApplicationController
def index
@author = Member.find_by_slug(params[:author])
if @author
@posts = @author.posts.includes(:author, { :comments => :author }).paginate(:page => params[:page])
@posts = @author.posts.includes(:author, { comments: :author }).paginate(page: params[:page])
else
@posts = Post.includes(:author, { :comments => :author }).paginate(:page => params[:page])
@posts = Post.includes(:author, { comments: :author }).paginate(page: params[:page])
end
respond_to do |format|
format.html # index.html.haml
format.json { render json: @posts }
format.rss { render :layout => false } #index.rss.builder
format.rss { render layout: false } #index.rss.builder
end
end
# GET /posts/1
# GET /posts/1.json
def show
@post = Post.includes(:author, { :comments => :author }).find(params[:id])
@post = Post.includes(:author, { comments: :author }).find(params[:id])
respond_to do |format|
format.html # show.html.haml
format.json { render json: @post }
format.rss { render(
:layout => false,
:locals => { :post => @post }
layout: false,
locals: { post: @post }
)}
end
end

View File

@@ -28,7 +28,7 @@ class RegistrationsController < Devise::RegistrationsController
if successfully_updated
set_flash_message :notice, :updated
# Sign in the member bypassing validation in case their password changed
sign_in @member, :bypass => true
sign_in @member, bypass: true
redirect_to edit_member_registration_path
else
render "edit"

View File

@@ -1,5 +1,5 @@
class ScientificNamesController < ApplicationController
before_filter :authenticate_member!, :except => [:index, :show]
before_filter :authenticate_member!, except: [:index, :show]
load_and_authorize_resource
# GET /scientific_names

View File

@@ -1,5 +1,5 @@
class SeedsController < ApplicationController
before_filter :authenticate_member!, :except => [:index, :show]
before_filter :authenticate_member!, except: [:index, :show]
load_and_authorize_resource
# GET /seeds
@@ -8,17 +8,17 @@ class SeedsController < ApplicationController
@owner = Member.find_by_slug(params[:owner])
@crop = Crop.find_by_slug(params[:crop])
if @owner
@seeds = @owner.seeds.includes(:owner, :crop).paginate(:page => params[:page])
@seeds = @owner.seeds.includes(:owner, :crop).paginate(page: params[:page])
elsif @crop
@seeds = @crop.seeds.includes(:owner, :crop).paginate(:page => params[:page])
@seeds = @crop.seeds.includes(:owner, :crop).paginate(page: params[:page])
else
@seeds = Seed.includes(:owner, :crop).paginate(:page => params[:page])
@seeds = Seed.includes(:owner, :crop).paginate(page: params[:page])
end
respond_to do |format|
format.html # index.html.erb
format.json { render json: @seeds }
format.rss { render :layout => false } #index.rss.builder
format.rss { render layout: false } #index.rss.builder
format.csv do
if @owner
@filename = "Growstuff-#{@owner}-Seeds-#{Time.zone.now.to_s(:number)}.csv"
@@ -27,7 +27,7 @@ class SeedsController < ApplicationController
@filename = "Growstuff-Seeds-#{Time.zone.now.to_s(:number)}.csv"
@seeds = Seed.includes(:owner, :crop)
end
render :csv => @seeds
render csv: @seeds
end
end
end

View File

@@ -21,7 +21,7 @@ module ApplicationHelper
link = "http://www.wolframalpha.com/input/?i=#{pid}+#{currency}"
return link_to "(convert)",
link,
:target => "_blank"
target: "_blank"
end
# Produces a cache key for uniquely identifying cached fragments.
@@ -46,8 +46,8 @@ module ApplicationHelper
return member.preferred_avatar_uri if member.preferred_avatar_uri.present?
Gravatar.new(member.email).image_url({
:size => size,
:default => :identicon
size: size,
default: :identicon
})
end
end

View File

@@ -18,11 +18,11 @@ module HarvestsHelper
def display_human_quantity(harvest)
if ! harvest.quantity.blank? && harvest.quantity > 0
if harvest.unit == 'individual' # just the number
number_to_human(harvest.quantity, :strip_insignificant_zeros => true)
number_to_human(harvest.quantity, strip_insignificant_zeros: true)
elsif ! harvest.unit.blank? # pluralize anything else
return pluralize(number_to_human(harvest.quantity, :strip_insignificant_zeros => true), harvest.unit)
return pluralize(number_to_human(harvest.quantity, strip_insignificant_zeros: true), harvest.unit)
else
return "#{number_to_human(harvest.quantity, :strip_insignificant_zeros => true)} #{harvest.unit}"
return "#{number_to_human(harvest.quantity, strip_insignificant_zeros: true)} #{harvest.unit}"
end
else
return nil
@@ -31,7 +31,7 @@ module HarvestsHelper
def display_weight(harvest)
if ! harvest.weight_quantity.blank? && harvest.weight_quantity > 0
return "#{number_to_human(harvest.weight_quantity, :strip_insignificant_zeros => true)} #{harvest.weight_unit}"
return "#{number_to_human(harvest.weight_quantity, strip_insignificant_zeros: true)} #{harvest.weight_unit}"
else
return nil
end

View File

@@ -2,7 +2,7 @@ module NotificationsHelper
def reply_link(notification)
if notification.post
# comment on the post in question
new_comment_url(:post_id => notification.post.id)
new_comment_url(post_id: notification.post.id)
else
# by default, reply link sends a PM in return
reply_notification_url(notification)

View File

@@ -17,8 +17,8 @@ class Notifier < ActionMailer::Base
# Encrypting
@signed_message = verifier.generate ({ member_id: @notification.recipient.id, type: :send_notification_email })
mail(:to => @notification.recipient.email,
:subject => @notification.subject)
mail(to: @notification.recipient.email,
subject: @notification.subject)
end
def planting_reminder(member)
@@ -31,24 +31,24 @@ class Notifier < ActionMailer::Base
@signed_message = verifier.generate ({ member_id: @member.id, type: :send_planting_reminder })
if @member.send_planting_reminder
mail(:to => @member.email,
:subject => "What have you planted lately?")
mail(to: @member.email,
subject: "What have you planted lately?")
end
end
def new_crop_request(member, request)
@member, @request = member, request
mail(:to => @member.email, :subject => "#{@request.requester.login_name} has requested #{@request.name} as a new crop")
mail(to: @member.email, subject: "#{@request.requester.login_name} has requested #{@request.name} as a new crop")
end
def crop_request_approved(member, crop)
@member, @crop = member, crop
mail(:to => @member.email, :subject => "#{crop.name.capitalize} has been approved")
mail(to: @member.email, subject: "#{crop.name.capitalize} has been approved")
end
def crop_request_rejected(member, crop)
@member, @crop = member, crop
mail(:to => @member.email, :subject => "#{crop.name.capitalize} has been rejected")
mail(to: @member.email, subject: "#{crop.name.capitalize} has been rejected")
end
end

View File

@@ -24,7 +24,7 @@ class Ability
# nobody should be able to view unapproved crops unless they
# are wranglers or admins
cannot :read, Crop
can :read, Crop, :approval_status => "approved"
can :read, Crop, approval_status: "approved"
# scientific names should only be viewable if associated crop is approved
cannot :read, ScientificName
can :read, ScientificName do |sn|
@@ -38,15 +38,15 @@ class Ability
if member
# members can see even rejected or pending crops if they requested it
can :read, Crop, :requester_id => member.id
can :read, Crop, requester_id: member.id
# managing your own user settings
can :update, Member, :id => member.id
can :update, Member, id: member.id
# can read/delete notifications that were sent to them
can :read, Notification, :recipient_id => member.id
can :destroy, Notification, :recipient_id => member.id
can :reply, Notification, :recipient_id => member.id
can :read, Notification, recipient_id: member.id
can :destroy, Notification, recipient_id: member.id
can :reply, Notification, recipient_id: member.id
# can send a private message to anyone but themselves
# note: sadly, we can't test for this from the view, but it works
# for the model/controller
@@ -68,58 +68,58 @@ class Ability
# can create & destroy their own authentications against other sites.
can :create, Authentication
can :destroy, Authentication, :member_id => member.id
can :destroy, Authentication, member_id: member.id
# anyone can create a post, or comment on a post,
# but only the author can edit/destroy it.
can :create, Post
can :update, Post, :author_id => member.id
can :destroy, Post, :author_id => member.id
can :update, Post, author_id: member.id
can :destroy, Post, author_id: member.id
can :create, Comment
can :update, Comment, :author_id => member.id
can :destroy, Comment, :author_id => member.id
can :update, Comment, author_id: member.id
can :destroy, Comment, author_id: member.id
# same deal for gardens and plantings
can :create, Garden
can :update, Garden, :owner_id => member.id
can :destroy, Garden, :owner_id => member.id
can :update, Garden, owner_id: member.id
can :destroy, Garden, owner_id: member.id
can :create, Planting
can :update, Planting, :garden => { :owner_id => member.id }
can :destroy, Planting, :garden => { :owner_id => member.id }
can :update, Planting, garden: { owner_id: member.id }
can :destroy, Planting, garden: { owner_id: member.id }
can :create, Harvest
can :update, Harvest, :owner_id => member.id
can :destroy, Harvest, :owner_id => member.id
can :update, Harvest, owner_id: member.id
can :destroy, Harvest, owner_id: member.id
can :create, Photo
can :update, Photo, :owner_id => member.id
can :destroy, Photo, :owner_id => member.id
can :update, Photo, owner_id: member.id
can :destroy, Photo, owner_id: member.id
can :create, Seed
can :update, Seed, :owner_id => member.id
can :destroy, Seed, :owner_id => member.id
can :update, Seed, owner_id: member.id
can :destroy, Seed, owner_id: member.id
# orders/shop/etc
can :create, Order
can :read, Order, :member_id => member.id
can :complete, Order, :member_id => member.id, :completed_at => nil
can :checkout, Order, :member_id => member.id, :completed_at => nil
can :cancel, Order, :member_id => member.id, :completed_at => nil
can :destroy, Order, :member_id => member.id, :completed_at => nil
can :read, Order, member_id: member.id
can :complete, Order, member_id: member.id, completed_at: nil
can :checkout, Order, member_id: member.id, completed_at: nil
can :cancel, Order, member_id: member.id, completed_at: nil
can :destroy, Order, member_id: member.id, completed_at: nil
can :create, OrderItem
# for now, let's not let people mess with individual order items
cannot :read, OrderItem, :order => { :member_id => member.id }
cannot :update, OrderItem, :order => { :member_id => member.id, :completed_at => nil }
cannot :destroy, OrderItem, :order => { :member_id => member.id, :completed_at => nil }
cannot :read, OrderItem, order: { member_id: member.id }
cannot :update, OrderItem, order: { member_id: member.id, completed_at: nil }
cannot :destroy, OrderItem, order: { member_id: member.id, completed_at: nil }
# following/unfollowing permissions
can :create, Follow
cannot :create, Follow, :followed_id => member.id # can't follow yourself
cannot :create, Follow, followed_id: member.id # can't follow yourself
can :destroy, Follow
cannot :destroy, Follow, :followed_id => member.id # can't unfollow yourself
cannot :destroy, Follow, followed_id: member.id # can't unfollow yourself
if member.has_role? :admin

View File

@@ -2,8 +2,8 @@ class Account < ActiveRecord::Base
belongs_to :member
belongs_to :account_type
validates :member_id, :uniqueness => {
:message => 'already has account details associated with it'
validates :member_id, uniqueness: {
message: 'already has account details associated with it'
}
before_create do |account|

View File

@@ -1,5 +1,5 @@
class AlternateName < ActiveRecord::Base
after_commit { |an| an.crop.__elasticsearch__.index_document if an.crop && ENV['GROWSTUFF_ELASTICSEARCH'] == "true" }
belongs_to :crop
belongs_to :creator, :class_name => 'Member'
belongs_to :creator, class_name: 'Member'
end

View File

@@ -1,5 +1,5 @@
class Comment < ActiveRecord::Base
belongs_to :author, :class_name => 'Member'
belongs_to :author, class_name: 'Member'
belongs_to :post
default_scope { order("created_at DESC") }
@@ -11,11 +11,11 @@ class Comment < ActiveRecord::Base
# don't send notifications to yourself
if recipient != sender
Notification.create(
:recipient_id => recipient,
:sender_id => sender,
:subject => "#{self.author} commented on #{self.post.subject}",
:body => self.body,
:post_id => self.post.id
recipient_id: recipient,
sender_id: sender,
subject: "#{self.author} commented on #{self.post.subject}",
body: self.body,
post_id: self.post.id
)
end
end

View File

@@ -4,42 +4,42 @@ class Crop < ActiveRecord::Base
has_many :scientific_names, after_add: :update_index, after_remove: :update_index
accepts_nested_attributes_for :scientific_names,
:allow_destroy => true,
:reject_if => :all_blank
allow_destroy: true,
reject_if: :all_blank
has_many :alternate_names, after_add: :update_index, after_remove: :update_index, dependent: :destroy
has_many :plantings
has_many :photos, :through => :plantings
has_many :photos, through: :plantings
has_many :seeds
has_many :harvests
has_many :plant_parts, -> { uniq }, :through => :harvests
belongs_to :creator, :class_name => 'Member'
belongs_to :requester, :class_name => 'Member'
has_many :plant_parts, -> { uniq }, through: :harvests
belongs_to :creator, class_name: 'Member'
belongs_to :requester, class_name: 'Member'
belongs_to :parent, :class_name => 'Crop'
has_many :varieties, :class_name => 'Crop', :foreign_key => 'parent_id'
belongs_to :parent, class_name: 'Crop'
has_many :varieties, class_name: 'Crop', foreign_key: 'parent_id'
has_and_belongs_to_many :posts
before_destroy {|crop| crop.posts.clear}
default_scope { order("lower(name) asc") }
scope :recent, -> { where(:approval_status => "approved").reorder("created_at desc") }
scope :toplevel, -> { where(:approval_status => "approved", :parent_id => nil) }
scope :popular, -> { where(:approval_status => "approved").reorder("plantings_count desc, lower(name) asc") }
scope :randomized, -> { where(:approval_status => "approved").reorder('random()') } # ok on sqlite and psql, but not on mysql
scope :pending_approval, -> { where(:approval_status => "pending") }
scope :approved, -> { where(:approval_status => "approved") }
scope :rejected, -> { where(:approval_status => "rejected") }
scope :recent, -> { where(approval_status: "approved").reorder("created_at desc") }
scope :toplevel, -> { where(approval_status: "approved", parent_id: nil) }
scope :popular, -> { where(approval_status: "approved").reorder("plantings_count desc, lower(name) asc") }
scope :randomized, -> { where(approval_status: "approved").reorder('random()') } # ok on sqlite and psql, but not on mysql
scope :pending_approval, -> { where(approval_status: "pending") }
scope :approved, -> { where(approval_status: "approved") }
scope :rejected, -> { where(approval_status: "rejected") }
## Wikipedia urls are only necessary when approving a crop
validates :en_wikipedia_url,
:format => {
:with => /\Ahttps?:\/\/en\.wikipedia\.org\/wiki/,
:message => 'is not a valid English Wikipedia URL'
format: {
with: /\Ahttps?:\/\/en\.wikipedia\.org\/wiki/,
message: 'is not a valid English Wikipedia URL'
},
:if => :approved?
if: :approved?
## Reasons are only necessary when rejecting
validates :reason_for_rejection, :presence => true, :if => :rejected?
validates :reason_for_rejection, presence: true, if: :rejected?
## This validation addresses a race condition
validate :approval_status_cannot_be_changed_again
@@ -231,14 +231,14 @@ class Crop < ActiveRecord::Base
crop = Crop.find_or_create_by(name: name)
crop.update_attributes(
:en_wikipedia_url => en_wikipedia_url,
:creator_id => cropbot.id
en_wikipedia_url: en_wikipedia_url,
creator_id: cropbot.id
)
if parent
parent = Crop.find_by_name(parent)
if parent
crop.update_attributes(:parent_id => parent.id)
crop.update_attributes(parent_id: parent.id)
else
logger.warn("Warning: parent crop #{parent} not found")
end
@@ -264,13 +264,13 @@ class Crop < ActiveRecord::Base
raise "cropbot account not found: run rake db:seed" unless cropbot
names_to_add.each do |n|
if self.scientific_names.exists?(:scientific_name => n)
if self.scientific_names.exists?(scientific_name: n)
logger.warn("Warning: skipping duplicate scientific name #{n} for #{self}")
else
self.scientific_names.create(
:scientific_name => n,
:creator_id => cropbot.id
scientific_name: n,
creator_id: cropbot.id
)
end
end
@@ -286,12 +286,12 @@ class Crop < ActiveRecord::Base
names_to_add = alternate_names.split(%r{,\s*})
names_to_add.each do |n|
if self.alternate_names.exists?(:name => n)
if self.alternate_names.exists?(name: n)
logger.warn("Warning: skipping duplicate alternate name #{n} for #{self}")
else
self.alternate_names.create(
:name => n,
:creator_id => cropbot.id
name: n,
creator_id: cropbot.id
)
end
end

View File

@@ -1,14 +1,14 @@
class Follow < ActiveRecord::Base
belongs_to :follower, class_name: "Member"
belongs_to :followed, class_name: "Member"
validates :follower_id, uniqueness: { :scope => :followed_id }
validates :follower_id, uniqueness: { scope: :followed_id }
after_create do
Notification.create(
:recipient_id => self.followed_id,
:sender_id => self.follower_id,
:subject => "#{self.follower.login_name} is now following you",
:body => "#{self.follower.login_name} just followed you on #{ENV["GROWSTUFF_SITE_NAME"]}. "
recipient_id: self.followed_id,
sender_id: self.follower_id,
subject: "#{self.follower.login_name} is now following you",
body: "#{self.follower.login_name} just followed you on #{ENV["GROWSTUFF_SITE_NAME"]}. "
)
end

View File

@@ -3,7 +3,7 @@ class Forum < ActiveRecord::Base
friendly_id :name, use: [:slugged, :finders]
has_many :posts
belongs_to :owner, :class_name => "Member"
belongs_to :owner, class_name: "Member"
def to_s
return name

View File

@@ -3,9 +3,9 @@ class Garden < ActiveRecord::Base
extend FriendlyId
friendly_id :garden_slug, use: [:slugged, :finders]
belongs_to :owner, :class_name => 'Member', :foreign_key => 'owner_id'
has_many :plantings, -> { order(created_at: :desc) }, :dependent => :destroy
has_many :crops, :through => :plantings
belongs_to :owner, class_name: 'Member', foreign_key: 'owner_id'
has_many :plantings, -> { order(created_at: :desc) }, dependent: :destroy
has_many :crops, through: :plantings
has_and_belongs_to_many :photos
@@ -25,23 +25,23 @@ class Garden < ActiveRecord::Base
after_save :mark_inactive_garden_plantings_as_finished
default_scope { order("lower(name) asc") }
scope :active, -> { where(:active => true) }
scope :inactive, -> { where(:active => false) }
scope :active, -> { where(active: true) }
scope :inactive, -> { where(active: false) }
validates :location,
:length => { :maximum => 255 }
length: { maximum: 255 }
validates :name,
:format => {
:with => /\S/
format: {
with: /\S/
},
:length => { :maximum => 255 }
length: { maximum: 255 }
validates :area,
:numericality => {
:only_integer => false,
:greater_than_or_equal_to => 0 },
:allow_nil => true
numericality: {
only_integer: false,
greater_than_or_equal_to: 0 },
allow_nil: true
AREA_UNITS_VALUES = {
"square metres" => "square metre",
@@ -49,10 +49,10 @@ class Garden < ActiveRecord::Base
"hectares" => "hectare",
"acres" => "acre"
}
validates :area_unit, :inclusion => { :in => AREA_UNITS_VALUES.values,
:message => "%{value} is not a valid area unit" },
:allow_nil => true,
:allow_blank => true
validates :area_unit, inclusion: { in: AREA_UNITS_VALUES.values,
message: "%{value} is not a valid area unit" },
allow_nil: true,
allow_blank: true
after_validation :cleanup_area

View File

@@ -4,7 +4,7 @@ class Harvest < ActiveRecord::Base
friendly_id :harvest_slug, use: [:slugged, :finders]
belongs_to :crop
belongs_to :owner, :class_name => 'Member'
belongs_to :owner, class_name: 'Member'
belongs_to :plant_part
has_and_belongs_to_many :photos
@@ -20,17 +20,17 @@ class Harvest < ActiveRecord::Base
default_scope { order('created_at DESC') }
validates :crop, :approved => true
validates :crop, approved: true
validates :crop, :presence => {:message => "must be present and exist in our database"}
validates :crop, presence: {message: "must be present and exist in our database"}
validates :plant_part, :presence => {:message => "must be present and exist in our database"}
validates :plant_part, presence: {message: "must be present and exist in our database"}
validates :quantity,
:numericality => {
:only_integer => false,
:greater_than_or_equal_to => 0 },
:allow_nil => true
numericality: {
only_integer: false,
greater_than_or_equal_to: 0 },
allow_nil: true
UNITS_VALUES = {
"individual" => "individual",
@@ -44,24 +44,24 @@ class Harvest < ActiveRecord::Base
"baskets" => "basket",
"bushels" => "bushel"
}
validates :unit, :inclusion => { :in => UNITS_VALUES.values,
:message => "%{value} is not a valid unit" },
:allow_nil => true,
:allow_blank => true
validates :unit, inclusion: { in: UNITS_VALUES.values,
message: "%{value} is not a valid unit" },
allow_nil: true,
allow_blank: true
validates :weight_quantity,
:numericality => { :only_integer => false },
:allow_nil => true
numericality: { only_integer: false },
allow_nil: true
WEIGHT_UNITS_VALUES = {
"kg" => "kg",
"lb" => "lb",
"oz" => "oz"
}
validates :weight_unit, :inclusion => { :in => WEIGHT_UNITS_VALUES.values,
:message => "%{value} is not a valid unit" },
:allow_nil => true,
:allow_blank => true
validates :weight_unit, inclusion: { in: WEIGHT_UNITS_VALUES.values,
message: "%{value} is not a valid unit" },
allow_nil: true,
allow_blank: true
after_validation :cleanup_quantities
@@ -72,7 +72,7 @@ class Harvest < ActiveRecord::Base
def set_si_weight
if self.weight_unit != nil
weight_string = "#{self.weight_quantity} #{self.weight_unit}"
self.si_weight = Unit(weight_string).convert_to("kg").to_s("%0.3f").delete(" kg").to_f
self.si_weight = Unit.new(weight_string).convert_to("kg").to_s("%0.3f").delete(" kg").to_f
end
end
@@ -104,7 +104,7 @@ class Harvest < ActiveRecord::Base
# 2 buckets of apricots, weighing 10kg
string = ''
if self.quantity
string += "#{number_to_human(self.quantity.to_s, :strip_insignificant_zeros => true)} "
string += "#{number_to_human(self.quantity.to_s, strip_insignificant_zeros: true)} "
if self.unit == 'individual'
string += 'individual '
else
@@ -125,7 +125,7 @@ class Harvest < ActiveRecord::Base
end
if self.weight_quantity
string += " weighing #{number_to_human(self.weight_quantity, :strip_insignificant_zeros => true)} #{self.weight_unit}"
string += " weighing #{number_to_human(self.weight_quantity, strip_insignificant_zeros: true)} #{self.weight_unit}"
end
return string

View File

@@ -4,26 +4,26 @@ class Member < ActiveRecord::Base
friendly_id :login_name, use: [:slugged, :finders]
has_many :posts, :foreign_key => 'author_id'
has_many :comments, :foreign_key => 'author_id'
has_many :forums, :foreign_key => 'owner_id'
has_many :posts, foreign_key: 'author_id'
has_many :comments, foreign_key: 'author_id'
has_many :forums, foreign_key: 'owner_id'
has_many :gardens, :foreign_key => 'owner_id'
has_many :plantings, :foreign_key => 'owner_id'
has_many :gardens, foreign_key: 'owner_id'
has_many :plantings, foreign_key: 'owner_id'
has_many :seeds, :foreign_key => 'owner_id'
has_many :harvests, :foreign_key => 'owner_id'
has_many :seeds, foreign_key: 'owner_id'
has_many :harvests, foreign_key: 'owner_id'
has_and_belongs_to_many :roles
has_many :notifications, :foreign_key => 'recipient_id'
has_many :sent_notifications, :foreign_key => 'sender_id'
has_many :notifications, foreign_key: 'recipient_id'
has_many :sent_notifications, foreign_key: 'sender_id'
has_many :authentications
has_many :orders
has_one :account
has_one :account_type, :through => :account
has_one :account_type, through: :account
has_many :photos
@@ -33,13 +33,13 @@ class Member < ActiveRecord::Base
scope :located, -> { where("location <> '' and latitude IS NOT NULL and longitude IS NOT NULL") }
scope :recently_signed_in, -> { reorder('updated_at DESC') }
scope :recently_joined, -> { reorder("confirmed_at desc") }
scope :wants_newsletter, -> { where(:newsletter => true) }
scope :wants_newsletter, -> { where(newsletter: true) }
has_many :follows, :class_name => "Follow", :foreign_key => "follower_id"
has_many :followed, :through => :follows
has_many :follows, class_name: "Follow", foreign_key: "follower_id"
has_many :followed, through: :follows
has_many :inverse_follows, :class_name => "Follow", :foreign_key => "followed_id"
has_many :followers, :through => :inverse_follows, :source => :follower
has_many :inverse_follows, class_name: "Follow", foreign_key: "followed_id"
has_many :followers, through: :inverse_follows, source: :follower
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
@@ -58,34 +58,34 @@ class Member < ActiveRecord::Base
attr_accessor :login
# Requires acceptance of the Terms of Service
validates_acceptance_of :tos_agreement, :allow_nil => false,
:accept => true
validates_acceptance_of :tos_agreement, allow_nil: false,
accept: true
validates :login_name,
:length => {
:minimum => 2,
:maximum => 25,
:message => "should be between 2 and 25 characters long"
length: {
minimum: 2,
maximum: 25,
message: "should be between 2 and 25 characters long"
},
:exclusion => {
:in => %w(growstuff admin moderator staff nearby),
:message => "name is reserved"
exclusion: {
in: %w(growstuff admin moderator staff nearby),
message: "name is reserved"
},
:format => {
:with => /\A\w+\z/,
:message => "may only include letters, numbers, or underscores"
format: {
with: /\A\w+\z/,
message: "may only include letters, numbers, or underscores"
},
:uniqueness => {
:case_sensitive => false
uniqueness: {
case_sensitive: false
}
# Give each new member a default garden
after_create {|member| Garden.create(:name => "Garden", :owner_id => member.id) }
after_create {|member| Garden.create(name: "Garden", owner_id: member.id) }
# and an account record (for paid accounts etc)
# we use find_or_create to avoid accidentally creating a second one,
# which can happen sometimes especially with FactoryGirl associations
after_create {|member| Account.find_or_create_by(:member_id => member.id) }
after_create {|member| Account.find_or_create_by(member_id: member.id) }
after_save :update_newsletter_subscription
@@ -93,7 +93,7 @@ class Member < ActiveRecord::Base
def self.find_first_by_auth_conditions(warden_conditions)
conditions = warden_conditions.dup
if login = conditions.delete(:login)
where(conditions).where(["lower(login_name) = :value OR lower(email) = :value", { :value => login.downcase }]).first
where(conditions).where(["lower(login_name) = :value OR lower(email) = :value", { value: login.downcase }]).first
else
where(conditions).first
end
@@ -108,7 +108,7 @@ class Member < ActiveRecord::Base
end
def current_order
orders.where(:completed_at => nil).first
orders.where(completed_at: nil).first
end
# when purchasing a product that gives you a paid account, this method
@@ -163,15 +163,15 @@ class Member < ActiveRecord::Base
result = false
if set
result = flickr.photosets.getPhotos(
:photoset_id => set,
:page => page_num,
:per_page => 30
photoset_id: set,
page: page_num,
per_page: 30
)
else
result = flickr.people.getPhotos(
:user_id => 'me',
:page => page_num,
:per_page => 30
user_id: 'me',
page: page_num,
per_page: 30
)
end
if result
@@ -239,10 +239,10 @@ class Member < ActiveRecord::Base
return true if (Rails.env.test? && !testing)
gb = Gibbon::API.new
res = gb.lists.subscribe({
:id => Gibbon::API.api_key,
:email => { :email => email },
:merge_vars => { :login_name => login_name },
:double_optin => false # they already confirmed their email with us
id: Gibbon::API.api_key,
email: { email: email },
merge_vars: { login_name: login_name },
double_optin: false # they already confirmed their email with us
})
end
@@ -250,17 +250,17 @@ class Member < ActiveRecord::Base
return true if (Rails.env.test? && !testing)
gb = Gibbon::API.new
res = gb.lists.unsubscribe({
:id => ENV['GROWSTUFF_MAILCHIMP_NEWSLETTER_ID'],
:email => { :email => email }
id: ENV['GROWSTUFF_MAILCHIMP_NEWSLETTER_ID'],
email: { email: email }
})
end
def already_following?(member)
self.follows.exists?(:followed_id => member.id)
self.follows.exists?(followed_id: member.id)
end
def get_follow(member)
self.follows.where(:followed_id => member.id).first if already_following?(member)
self.follows.where(followed_id: member.id).first if already_following?(member)
end
end

View File

@@ -1,12 +1,12 @@
class Notification < ActiveRecord::Base
belongs_to :sender, :class_name => 'Member'
belongs_to :recipient, :class_name => 'Member'
belongs_to :sender, class_name: 'Member'
belongs_to :recipient, class_name: 'Member'
belongs_to :post
validates :subject, :length => { :maximum => 255 }
validates :subject, length: { maximum: 255 }
default_scope { order('created_at DESC') }
scope :unread, -> { where(:read => false) }
scope :unread, -> { where(read: false) }
before_create :replace_blank_subject
after_create :send_email

View File

@@ -1,13 +1,13 @@
class Order < ActiveRecord::Base
belongs_to :member
has_many :order_items, :dependent => :destroy
has_many :order_items, dependent: :destroy
default_scope { order('created_at DESC') }
validates :referral_code, :format => {
:with => /\A[a-zA-Z0-9 ]*\z/,
:message => "may only include letters and numbers"
validates :referral_code, format: {
with: /\A[a-zA-Z0-9 ]*\z/,
message: "may only include letters and numbers"
}
before_save :standardize_referral_code
@@ -27,9 +27,9 @@ class Order < ActiveRecord::Base
items = []
order_items.each do |i|
items.push({
:name => i.product.name,
:quantity => i.quantity,
:amount => i.price
name: i.product.name,
quantity: i.quantity,
amount: i.price
})
end
return items
@@ -87,7 +87,7 @@ class Order < ActiveRecord::Base
end
when "referral_code"
# coerce to uppercase
return Order.where(:referral_code => args[:for].upcase)
return Order.where(referral_code: args[:for].upcase)
end
end
return []

View File

@@ -4,7 +4,7 @@ class OrderItem < ActiveRecord::Base
validate :price_must_be_greater_than_minimum
validates_uniqueness_of :order_id, :message => "may only have one item."
validates_uniqueness_of :order_id, message: "may only have one item."
def price_must_be_greater_than_minimum
@product = Product.find(product_id)

View File

@@ -1,5 +1,5 @@
class Photo < ActiveRecord::Base
belongs_to :owner, :class_name => 'Member'
belongs_to :owner, class_name: 'Member'
has_and_belongs_to_many :plantings
has_and_belongs_to_many :harvests
@@ -23,16 +23,16 @@ class Photo < ActiveRecord::Base
# for easier stubbing and testing.
def flickr_metadata
flickr = owner.flickr
info = flickr.photos.getInfo(:photo_id => flickr_photo_id)
info = flickr.photos.getInfo(photo_id: flickr_photo_id)
licenses = flickr.photos.licenses.getInfo()
license = licenses.find { |l| l.id == info.license }
return {
:title => info.title || "Untitled",
:license_name => license.name,
:license_url => license.url,
:thumbnail_url => FlickRaw.url_q(info),
:fullsize_url => FlickRaw.url_z(info),
:link_url => FlickRaw.url_photopage(info)
title: info.title || "Untitled",
license_name: license.name,
license_url: license.url,
thumbnail_url: FlickRaw.url_q(info),
fullsize_url: FlickRaw.url_z(info),
link_url: FlickRaw.url_photopage(info)
}
end

View File

@@ -1,9 +1,9 @@
class PlantPart < ActiveRecord::Base
extend FriendlyId
friendly_id :name, :use => [:slugged, :finders]
friendly_id :name, use: [:slugged, :finders]
has_many :harvests
has_many :crops, -> { uniq }, :through => :harvests
has_many :crops, -> { uniq }, through: :harvests
def to_s
return name

View File

@@ -3,8 +3,8 @@ class Planting < ActiveRecord::Base
friendly_id :planting_slug, use: [:slugged, :finders]
belongs_to :garden
belongs_to :owner, :class_name => 'Member', :counter_cache => true
belongs_to :crop, :counter_cache => true
belongs_to :owner, class_name: 'Member', counter_cache: true
belongs_to :crop, counter_cache: true
has_and_belongs_to_many :photos
@@ -18,33 +18,33 @@ class Planting < ActiveRecord::Base
end
default_scope { order("created_at desc") }
scope :finished, -> { where(:finished => true) }
scope :current, -> { where(:finished => false) }
scope :finished, -> { where(finished: true) }
scope :current, -> { where(finished: false) }
delegate :name,
:en_wikipedia_url,
:default_scientific_name,
:plantings_count,
:to => :crop,
:prefix => true
to: :crop,
prefix: true
default_scope { order("created_at desc") }
validates :crop, :approved => true
validates :crop, approved: true
validates :crop, :presence => {:message => "must be present and exist in our database"}
validates :crop, presence: {message: "must be present and exist in our database"}
validates :quantity,
:numericality => {
:only_integer => true,
:greater_than_or_equal_to => 0 },
:allow_nil => true
numericality: {
only_integer: true,
greater_than_or_equal_to: 0 },
allow_nil: true
SUNNINESS_VALUES = %w(sun semi-shade shade)
validates :sunniness, :inclusion => { :in => SUNNINESS_VALUES,
:message => "%{value} is not a valid sunniness value" },
:allow_nil => true,
:allow_blank => true
validates :sunniness, inclusion: { in: SUNNINESS_VALUES,
message: "%{value} is not a valid sunniness value" },
allow_nil: true,
allow_blank: true
PLANTED_FROM_VALUES = [
'seed',
@@ -59,10 +59,10 @@ class Planting < ActiveRecord::Base
'graft',
'layering'
]
validates :planted_from, :inclusion => { :in => PLANTED_FROM_VALUES,
:message => "%{value} is not a valid planting method" },
:allow_nil => true,
:allow_blank => true
validates :planted_from, inclusion: { in: PLANTED_FROM_VALUES,
message: "%{value} is not a valid planting method" },
allow_nil: true,
allow_blank: true
validate :finished_must_be_after_planted
@@ -95,7 +95,7 @@ class Planting < ActiveRecord::Base
end
def calculate_days_before_maturity(planting, crop)
p_crop = Planting.where(:crop_id => crop).where.not(:id => planting)
p_crop = Planting.where(crop_id: crop).where.not(id: planting)
differences = p_crop.collect do |p|
if p.finished and !p.finished_at.nil?
(p.finished_at - p.planted_at).to_i
@@ -109,11 +109,11 @@ class Planting < ActiveRecord::Base
end
end
def planted?(current_date = Date.today)
def planted?(current_date = Date.current)
planted_at.present? && current_date.to_date >= planted_at
end
def percentage_grown(current_date = Date.today)
def percentage_grown(current_date = Date.current)
return nil unless days_before_maturity && planted?(current_date)
days = (current_date.to_date - planted_at.to_date).to_i

View File

@@ -1,9 +1,9 @@
class Post < ActiveRecord::Base
extend FriendlyId
friendly_id :author_date_subject, use: [:slugged, :finders]
belongs_to :author, :class_name => 'Member'
belongs_to :author, class_name: 'Member'
belongs_to :forum
has_many :comments, :dependent => :destroy
has_many :comments, dependent: :destroy
has_and_belongs_to_many :crops
before_destroy {|post| post.crops.clear}
after_save :update_crops_posts_association
@@ -27,10 +27,10 @@ class Post < ActiveRecord::Base
recipients.map{ |r| r.id }.each do |recipient|
if recipient != sender
Notification.create(
:recipient_id => recipient,
:sender_id => sender,
:subject => "#{self.author} mentioned you in their post #{self.subject}",
:body => self.body,
recipient_id: recipient,
sender_id: sender,
subject: "#{self.author} mentioned you in their post #{self.subject}",
body: self.body,
)
end
end
@@ -39,10 +39,10 @@ class Post < ActiveRecord::Base
default_scope { order("created_at desc") }
validates :subject,
:format => {
:with => /\S/
format: {
with: /\S/
},
:length => { :maximum => 255 }
length: { maximum: 255 }
def author_date_subject

View File

@@ -3,10 +3,10 @@ class Product < ActiveRecord::Base
belongs_to :account_type
validates :paid_months,
:numericality => {
:only_integer => true,
:greater_than_or_equal_to => 0 },
:allow_nil => true
numericality: {
only_integer: true,
greater_than_or_equal_to: 0 },
allow_nil: true
def to_s
name

View File

@@ -1,5 +1,5 @@
class ScientificName < ActiveRecord::Base
after_commit { |sn| sn.crop.__elasticsearch__.index_document if sn.crop && ENV['GROWSTUFF_ELASTICSEARCH'] == "true" }
belongs_to :crop
belongs_to :creator, :class_name => 'Member'
belongs_to :creator, class_name: 'Member'
end

View File

@@ -3,62 +3,62 @@ class Seed < ActiveRecord::Base
friendly_id :seed_slug, use: [:slugged, :finders]
belongs_to :crop
belongs_to :owner, :class_name => 'Member', :foreign_key => 'owner_id'
belongs_to :owner, class_name: 'Member', foreign_key: 'owner_id'
default_scope { order("created_at desc") }
validates :crop, :approved => true
validates :crop, approved: true
validates :crop, :presence => {:message => "must be present and exist in our database"}
validates :crop, presence: {message: "must be present and exist in our database"}
validates :quantity,
:numericality => {
:only_integer => true,
:greater_than_or_equal_to => 0 },
:allow_nil => true
numericality: {
only_integer: true,
greater_than_or_equal_to: 0 },
allow_nil: true
validates :days_until_maturity_min,
:numericality => {
:only_integer => true,
:greater_than_or_equal_to => 0 },
:allow_nil => true
numericality: {
only_integer: true,
greater_than_or_equal_to: 0 },
allow_nil: true
validates :days_until_maturity_max,
:numericality => {
:only_integer => true,
:greater_than_or_equal_to => 0 },
:allow_nil => true
numericality: {
only_integer: true,
greater_than_or_equal_to: 0 },
allow_nil: true
scope :tradable, -> { where("tradable_to != 'nowhere'") }
TRADABLE_TO_VALUES = %w(nowhere locally nationally internationally)
validates :tradable_to, :inclusion => { :in => TRADABLE_TO_VALUES,
:message => "You may only trade seed nowhere, locally, nationally, or internationally" },
:allow_nil => false,
:allow_blank => false
validates :tradable_to, inclusion: { in: TRADABLE_TO_VALUES,
message: "You may only trade seed nowhere, locally, nationally, or internationally" },
allow_nil: false,
allow_blank: false
ORGANIC_VALUES = [
'certified organic',
'non-certified organic',
'conventional/non-organic',
'unknown']
validates :organic, :inclusion => { :in => ORGANIC_VALUES,
:message => "You must say whether the seeds are organic or not, or that you don't know" },
:allow_nil => false,
:allow_blank => false
validates :organic, inclusion: { in: ORGANIC_VALUES,
message: "You must say whether the seeds are organic or not, or that you don't know" },
allow_nil: false,
allow_blank: false
GMO_VALUES = [
'certified GMO-free',
'non-certified GMO-free',
'GMO',
'unknown']
validates :gmo, :inclusion => { :in => GMO_VALUES,
:message => "You must say whether the seeds are genetically modified or not, or that you don't know" },
:allow_nil => false,
:allow_blank => false
validates :gmo, inclusion: { in: GMO_VALUES,
message: "You must say whether the seeds are genetically modified or not, or that you don't know" },
allow_nil: false,
allow_blank: false
HEIRLOOM_VALUES = %w(heirloom hybrid unknown)
validates :heirloom, :inclusion => { :in => HEIRLOOM_VALUES,
:message => "You must say whether the seeds are heirloom, hybrid, or unknown" },
:allow_nil => false,
:allow_blank => false
validates :heirloom, inclusion: { in: HEIRLOOM_VALUES,
message: "You must say whether the seeds are heirloom, hybrid, or unknown" },
allow_nil: false,
allow_blank: false
def tradable?
if self.tradable_to == 'nowhere'

View File

@@ -36,7 +36,7 @@
.form-group
= f.label :weight_quantity, 'Weighing (in total):', :class => 'control-label col-md-2'
.col-md-2
= f.number_field :weight_quantity, :class => 'input-small', :step => 'any', :class => 'form-control', :placeholder => 'optional'
= f.number_field :weight_quantity, :class => 'input-small form-control', :step => 'any', :placeholder => 'optional'
.col-md-2
= f.select(:weight_unit, Harvest::WEIGHT_UNITS_VALUES, {:include_blank => false}, :class => 'form-control')
.form-group

View File

@@ -19,7 +19,7 @@ images_dir = "app/assets/images"
# If you prefer the indented syntax, you might want to regenerate this
# project again passing --syntax sass, or you can uncomment this:
# preferred_syntax = :sass
preferred_syntax = :sass
# and then run:
# sass-convert -R --from scss --to sass sass scss && rm -rf sass && mv scss sass

View File

@@ -5,7 +5,7 @@ require 'openssl'
if defined?(Bundler)
# If you precompile assets before deploying to production, use this line
Bundler.require(*Rails.groups(:assets => %w(development test)))
Bundler.require(*Rails.groups(assets: %w(development test)))
# If you want your assets lazily compiled in production, use this line
# Bundler.require(:default, :assets, Rails.env)
end
@@ -84,9 +84,9 @@ module Growstuff
config.action_mailer.delivery_method = :sendmail
config.action_mailer.sendmail_settings = {
:location => '/usr/sbin/sendmail',
:arguments => '-i -t',
:openssl_verify_mode => 'none'
location: '/usr/sbin/sendmail',
arguments: '-i -t',
openssl_verify_mode: 'none'
}
# Growstuff-specific configuration variables

View File

@@ -3,13 +3,14 @@ development:
database: growstuff_dev
host: localhost
user: postgres
password: password
password: postgres
test:
adapter: postgresql
database: growstuff_test
host: localhost
user: postgres
password: postgres
production:
adapter: postgresql

View File

@@ -44,15 +44,15 @@ Growstuff::Application.configure do
# config.action_view.raise_on_missing_translations = true
# Growstuff config
config.action_mailer.default_url_options = { :host => 'localhost:8080' }
config.action_mailer.default_url_options = { host: 'localhost:8080' }
config.action_mailer.delivery_method = :letter_opener
config.action_mailer.smtp_settings = {
:port => '587',
:address => 'smtp.mandrillapp.com',
:user_name => ENV['GROWSTUFF_MANDRILL_USERNAME'],
:password => ENV['GROWSTUFF_MANDRILL_APIKEY'],
:authentication => :login
port: '587',
address: 'smtp.mandrillapp.com',
user_name: ENV['GROWSTUFF_MANDRILL_USERNAME'],
password: ENV['GROWSTUFF_MANDRILL_APIKEY'],
authentication: :login
}
config.host = 'localhost:8080'
@@ -65,9 +65,9 @@ Growstuff::Application.configure do
config.after_initialize do
ActiveMerchant::Billing::Base.mode = :test
paypal_options = {
:login => ENV['GROWSTUFF_PAYPAL_USERNAME'] || 'dummy',
:password => ENV['GROWSTUFF_PAYPAL_PASSWORD'] || 'dummy',
:signature => ENV['GROWSTUFF_PAYPAL_SIGNATURE'] || 'dummy'
login: ENV['GROWSTUFF_PAYPAL_USERNAME'] || 'dummy',
password: ENV['GROWSTUFF_PAYPAL_PASSWORD'] || 'dummy',
signature: ENV['GROWSTUFF_PAYPAL_SIGNATURE'] || 'dummy'
}
::STANDARD_GATEWAY = ActiveMerchant::Billing::PaypalGateway.new(paypal_options)
::EXPRESS_GATEWAY = ActiveMerchant::Billing::PaypalExpressGateway.new(paypal_options)

View File

@@ -67,15 +67,15 @@ Growstuff::Application.configure do
config.active_record.dump_schema_after_migration = false
# Growstuff configuration
config.action_mailer.default_url_options = { :host => 'growstuff.org' }
config.action_mailer.default_url_options = { host: 'growstuff.org' }
config.action_mailer.smtp_settings = {
:port => '587',
:address => 'smtp.mandrillapp.com',
:user_name => ENV['GROWSTUFF_MANDRILL_USERNAME'],
:password => ENV['GROWSTUFF_MANDRILL_APIKEY'],
:domain => 'heroku.com',
:authentication => :plain
port: '587',
address: 'smtp.mandrillapp.com',
user_name: ENV['GROWSTUFF_MANDRILL_USERNAME'],
password: ENV['GROWSTUFF_MANDRILL_APIKEY'],
domain: 'heroku.com',
authentication: :plain
}
config.action_mailer.delivery_method = :smtp
@@ -93,9 +93,9 @@ Growstuff::Application.configure do
config.after_initialize do
ActiveMerchant::Billing::Base.mode = :production
paypal_options = {
:login => ENV['GROWSTUFF_PAYPAL_USERNAME'],
:password => ENV['GROWSTUFF_PAYPAL_PASSWORD'],
:signature => ENV['GROWSTUFF_PAYPAL_SIGNATURE']
login: ENV['GROWSTUFF_PAYPAL_USERNAME'],
password: ENV['GROWSTUFF_PAYPAL_PASSWORD'],
signature: ENV['GROWSTUFF_PAYPAL_SIGNATURE']
}
::STANDARD_GATEWAY = ActiveMerchant::Billing::PaypalGateway.new(paypal_options)
::EXPRESS_GATEWAY = ActiveMerchant::Billing::PaypalExpressGateway.new(paypal_options)

View File

@@ -69,15 +69,15 @@ Growstuff::Application.configure do
config.active_record.dump_schema_after_migration = false
# Growstuff configuration
config.action_mailer.default_url_options = { :host => 'staging.growstuff.org' }
config.action_mailer.default_url_options = { host: 'staging.growstuff.org' }
config.action_mailer.smtp_settings = {
:port => '587',
:address => 'smtp.mandrillapp.com',
:user_name => ENV['GROWSTUFF_MANDRILL_USERNAME'],
:password => ENV['GROWSTUFF_MANDRILL_APIKEY'],
:domain => 'heroku.com',
:authentication => :plain
port: '587',
address: 'smtp.mandrillapp.com',
user_name: ENV['GROWSTUFF_MANDRILL_USERNAME'],
password: ENV['GROWSTUFF_MANDRILL_APIKEY'],
domain: 'heroku.com',
authentication: :plain
}
config.action_mailer.delivery_method = :smtp
@@ -91,9 +91,9 @@ Growstuff::Application.configure do
config.after_initialize do
ActiveMerchant::Billing::Base.mode = :test
paypal_options = {
:login => ENV['GROWSTUFF_PAYPAL_USERNAME'],
:password => ENV['GROWSTUFF_PAYPAL_PASSWORD'],
:signature => ENV['GROWSTUFF_PAYPAL_SIGNATURE']
login: ENV['GROWSTUFF_PAYPAL_USERNAME'],
password: ENV['GROWSTUFF_PAYPAL_PASSWORD'],
signature: ENV['GROWSTUFF_PAYPAL_SIGNATURE']
}
::STANDARD_GATEWAY = ActiveMerchant::Billing::PaypalGateway.new(paypal_options)
::EXPRESS_GATEWAY = ActiveMerchant::Billing::PaypalExpressGateway.new(paypal_options)

View File

@@ -40,7 +40,7 @@ Growstuff::Application.configure do
# config.action_view.raise_on_missing_translations = true
# Growstuff config
config.action_mailer.default_url_options = { :host => 'localhost:8080' }
config.action_mailer.default_url_options = { host: 'localhost:8080' }
Growstuff::Application.configure do
config.host = 'test.example.com'
@@ -56,7 +56,7 @@ Growstuff::Application.configure do
end
Geocoder.configure(:lookup => :test)
Geocoder.configure(lookup: :test)
Geocoder::Lookup::Test.add_stub(
"Amundsen-Scott Base, Antarctica", [

View File

@@ -97,7 +97,7 @@ end
module CmsDeviseAuth
def authenticate
unless current_member && current_member.has_role?(:admin)
redirect_to root_path, :alert => 'Permission denied. Please sign in as an admin user to use the CMS admin area.'
redirect_to root_path, alert: 'Permission denied. Please sign in as an admin user to use the CMS admin area.'
end
end
end

View File

@@ -1,9 +1,9 @@
require 'geocodable'
Geocoder.configure(
:units => :km,
:timeout => 10,
:http_headers => {
units: :km,
timeout: 10,
http_headers: {
"User-Agent" =>
"#{Growstuff::Application.config.user_agent} #{Growstuff::Application.config.user_agent_email}",
"From" => Growstuff::Application.config.user_agent_email
@@ -12,5 +12,5 @@ Geocoder.configure(
# This configuration takes precedence over environment/test.rb
# Reported as https://github.com/alexreisner/geocoder/issues/509
if Geocoder.config.lookup != :test
Geocoder.configure(:lookup => :nominatim)
Geocoder.configure(lookup: :nominatim)
end

View File

@@ -4,7 +4,7 @@ Growstuff::Application.routes.draw do
resources :plant_parts
devise_for :members, :controllers => { :registrations => "registrations", :passwords => "passwords" }
devise_for :members, controllers: { registrations: "registrations", passwords: "passwords" }
devise_scope :member do
get '/members/unsubscribe/:message' => 'members#unsubscribe', :as => 'unsubscribe_member'
end
@@ -13,7 +13,7 @@ Growstuff::Application.routes.draw do
resources :photos
resources :authentications, :only => [:create, :destroy]
resources :authentications, only: [:create, :destroy]
resources :plantings
get '/plantings/owner/:owner' => 'plantings#index', :as => 'plantings_by_owner'
@@ -48,7 +48,7 @@ Growstuff::Application.routes.draw do
get 'reply', on: :member
end
resources :follows, :only => [:create, :destroy]
resources :follows, only: [:create, :destroy]
get '/members/:login_name/follows' => 'members#view_follows', :as => 'member_follows'
get '/members/:login_name/followers' => 'members#view_followers', :as => 'member_followers'
@@ -69,7 +69,7 @@ Growstuff::Application.routes.draw do
resources :products
get "home/index"
root :to => 'home#index'
root to: 'home#index'
get 'auth/:provider/callback' => 'authentications#create'
@@ -85,7 +85,7 @@ Growstuff::Application.routes.draw do
get '/shop' => 'shop#index'
get '/shop/:action' => 'shop#:action'
comfy_route :cms_admin, :path => '/admin/cms'
comfy_route :cms_admin, path: '/admin/cms'
get '/admin/orders' => 'admin/orders#index'
get '/admin/orders/:action' => 'admin/orders#:action'
get '/admin' => 'admin#index'
@@ -93,6 +93,6 @@ Growstuff::Application.routes.draw do
get '/admin/:action' => 'admin#:action'
# CMS stuff -- must remain LAST
comfy_route :cms, :path => '/', :sitemap => false
comfy_route :cms, path: '/', sitemap: false
end

View File

@@ -2,8 +2,8 @@ class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table(:users) do |t|
## Database authenticatable
t.string :email, :null => false, :default => ""
t.string :encrypted_password, :null => false, :default => ""
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
## Recoverable
t.string :reset_password_token
@@ -13,7 +13,7 @@ class DeviseCreateUsers < ActiveRecord::Migration
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, :default => 0
t.integer :sign_in_count, default: 0
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
@@ -26,7 +26,7 @@ class DeviseCreateUsers < ActiveRecord::Migration
t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
t.integer :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts
t.integer :failed_attempts, default: 0 # Only if lock strategy is :failed_attempts
t.string :unlock_token # Only if unlock strategy is :email or :both
t.datetime :locked_at
@@ -37,10 +37,10 @@ class DeviseCreateUsers < ActiveRecord::Migration
t.timestamps
end
add_index :users, :email, :unique => true
add_index :users, :reset_password_token, :unique => true
add_index :users, :confirmation_token, :unique => true
add_index :users, :unlock_token, :unique => true
add_index :users, :email, unique: true
add_index :users, :reset_password_token, unique: true
add_index :users, :confirmation_token, unique: true
add_index :users, :unlock_token, unique: true
# add_index :users, :authentication_token, :unique => true
end
end

View File

@@ -2,13 +2,13 @@ class RequireSystemNameForCrops < ActiveRecord::Migration
def up
change_table :crops do |t|
t.index :system_name
t.change :system_name, :string, :null => false
t.change :system_name, :string, null: false
end
end
def down
change_table :crops do |t|
t.change :system_name, :string, :null => true
t.change :system_name, :string, null: true
t.remove_index :system_name
end
end

View File

@@ -1,9 +1,9 @@
class CreateGardens < ActiveRecord::Migration
def change
create_table :gardens do |t|
t.string :name, :null => false
t.string :name, null: false
t.integer :user_id
t.string :slug, :null => false
t.string :slug, null: false
t.timestamps
end

View File

@@ -1,8 +1,8 @@
class CreateScientificNames < ActiveRecord::Migration
def change
create_table :scientific_names do |t|
t.string :scientific_name, :null => false
t.integer :crop_id, :null => false
t.string :scientific_name, null: false
t.integer :crop_id, null: false
t.timestamps
end

View File

@@ -1,9 +1,9 @@
class CreateUpdates < ActiveRecord::Migration
def change
create_table :updates do |t|
t.integer :user_id, :null => false
t.string :subject, :null => false
t.text :body, :null => false
t.integer :user_id, null: false
t.string :subject, null: false
t.text :body, null: false
t.timestamps
end

View File

@@ -1,8 +1,8 @@
class CreatePlantings < ActiveRecord::Migration
def change
create_table :plantings do |t|
t.integer :garden_id, :null => false
t.integer :crop_id, :null => false
t.integer :garden_id, null: false
t.integer :crop_id, null: false
t.datetime :planted_at
t.integer :quantity
t.text :description

View File

@@ -1,17 +1,17 @@
class RequireFieldsForComments < ActiveRecord::Migration
def up
change_table :comments do |t|
t.change :post_id, :integer, :null => false
t.change :author_id, :integer, :null => false
t.change :body, :text, :null => false
t.change :post_id, :integer, null: false
t.change :author_id, :integer, null: false
t.change :body, :text, null: false
end
end
def down
change_table :comments do |t|
t.change :post_id, :integer, :null => true
t.change :author_id, :integer, :null => true
t.change :body, :text, :null => true
t.change :post_id, :integer, null: true
t.change :author_id, :integer, null: true
t.change :body, :text, null: true
end
end
end

View File

@@ -2,7 +2,7 @@ class CreateNotifications < ActiveRecord::Migration
def change
create_table :notifications do |t|
t.integer :from_id
t.integer :to_id, :null => false
t.integer :to_id, null: false
t.string :subject
t.text :body
t.boolean :read

View File

@@ -1,9 +1,9 @@
class CreateForums < ActiveRecord::Migration
def change
create_table :forums do |t|
t.string :name, :null => false
t.text :description, :null => false
t.integer :owner_id, :null => false
t.string :name, null: false
t.text :description, null: false
t.integer :owner_id, null: false
t.timestamps
end

View File

@@ -1,7 +1,7 @@
class CreateRoles < ActiveRecord::Migration
def change
create_table :roles do |t|
t.string :name, :null => false
t.string :name, null: false
t.text :description
t.timestamps

View File

@@ -1,6 +1,6 @@
class AddMembersRolesTable < ActiveRecord::Migration
def change
create_table :members_roles, :id => false do |t|
create_table :members_roles, id: false do |t|
t.integer :member_id
t.integer :role_id
end

View File

@@ -1,13 +1,13 @@
class DefaultReadToFalse < ActiveRecord::Migration
def up
change_table :notifications do |t|
t.change :read, :boolean, :default => false
t.change :read, :boolean, default: false
end
end
def down
change_table :notifications do |t|
t.change :read, :boolean, :default => nil
t.change :read, :boolean, default: nil
end
end
end

View File

@@ -1,5 +1,5 @@
class AddSendEmailToMember < ActiveRecord::Migration
def change
add_column :members, :send_notification_email, :boolean, :default => true
add_column :members, :send_notification_email, :boolean, default: true
end
end

View File

@@ -1,8 +1,8 @@
class CreateAuthentications < ActiveRecord::Migration
def change
create_table :authentications do |t|
t.integer :member_id, :null => false
t.string :provider, :null => false
t.integer :member_id, null: false
t.string :provider, null: false
t.string :uid
t.string :token
t.string :secret

View File

@@ -1,3 +1,3 @@
class MakePostSubjectNonNull < ActiveRecord::Migration
change_column :posts, :subject, :string, :null => false
change_column :posts, :subject, :string, null: false
end

View File

@@ -1,9 +1,9 @@
class CreateProducts < ActiveRecord::Migration
def change
create_table :products do |t|
t.string :name, :null => false
t.string :description, :null => false
t.decimal :min_price, :null => false
t.string :name, null: false
t.string :description, null: false
t.decimal :min_price, null: false
t.timestamps
end

View File

@@ -1,7 +1,7 @@
class CreateOrders < ActiveRecord::Migration
def change
create_table :orders do |t|
t.string :member_id, :null => false
t.string :member_id, null: false
t.timestamps
end

View File

@@ -1,6 +1,6 @@
class AddOrdersProductsTable < ActiveRecord::Migration
def change
create_table :orders_products, :id => false do |t|
create_table :orders_products, id: false do |t|
t.integer :order_id
t.integer :product_id
end

View File

@@ -1,10 +1,10 @@
class CreatePhotos < ActiveRecord::Migration
def change
create_table :photos do |t|
t.integer :owner_id, :null => false
t.integer :flickr_photo_id, :null => false
t.string :thumbnail_url, :null => false
t.string :fullsize_url, :null => false
t.integer :owner_id, null: false
t.integer :flickr_photo_id, null: false
t.string :thumbnail_url, null: false
t.string :fullsize_url, null: false
t.timestamps
end

View File

@@ -5,9 +5,9 @@ class AddMetadataToPhotos < ActiveRecord::Migration
t.string :license_name
t.string :license_url
t.string :link_url
t.change :title, :string, :null => false
t.change :license_name, :string, :null => false
t.change :link_url, :string, :null => false
t.change :title, :string, null: false
t.change :license_name, :string, null: false
t.change :link_url, :string, null: false
end
end

View File

@@ -1,7 +1,7 @@
class CreateAccountDetails < ActiveRecord::Migration
def change
create_table :account_details do |t|
t.integer :member_id, :null => false
t.integer :member_id, null: false
t.integer :account_type_id
t.datetime :paid_until

View File

@@ -1,9 +1,9 @@
class RequireAccountTypeName < ActiveRecord::Migration
def up
change_column :account_types, :name, :string, :null => false
change_column :account_types, :name, :string, null: false
end
def down
change_column :account_types, :name, :string, :null => true
change_column :account_types, :name, :string, null: true
end
end

View File

@@ -1,6 +1,6 @@
class AddPhotosPlantingsTable < ActiveRecord::Migration
def change
create_table :photos_plantings, :id => false do |t|
create_table :photos_plantings, id: false do |t|
t.integer :photo_id
t.integer :planting_id
end

View File

@@ -1,8 +1,8 @@
class CreateSeeds < ActiveRecord::Migration
def change
create_table :seeds do |t|
t.integer :owner_id, :null => false
t.integer :crop_id, :null => false
t.integer :owner_id, null: false
t.integer :crop_id, null: false
t.text :description
t.integer :quantity
t.date :use_by

View File

@@ -1,8 +1,8 @@
class CreateHarvests < ActiveRecord::Migration
def change
create_table :harvests do |t|
t.integer :crop_id, :null => false
t.integer :owner_id, :null => false
t.integer :crop_id, null: false
t.integer :owner_id, null: false
t.date :harvested_at
t.decimal :quantity
t.string :units

View File

@@ -1,6 +1,6 @@
class AddFieldsToGardens < ActiveRecord::Migration
def change
add_column :gardens, :active, :boolean, :default => true
add_column :gardens, :active, :boolean, default: true
add_column :gardens, :location, :string
add_column :gardens, :latitude, :float
add_column :gardens, :longitude, :float

View File

@@ -1,9 +1,9 @@
class DefaultPlantingsCountToZero < ActiveRecord::Migration
def up
change_column :crops, :plantings_count, :integer, :default => 0
change_column :crops, :plantings_count, :integer, default: 0
end
def down
change_column :crops, :plantings_count, :integer, :default => nil
change_column :crops, :plantings_count, :integer, default: nil
end
end

View File

@@ -1,6 +1,6 @@
class AddFinishedToPlanting < ActiveRecord::Migration
def change
add_column :plantings, :finished, :boolean, :default => false
add_column :plantings, :finished, :boolean, default: false
add_column :plantings, :finished_at, :date
end
end

Some files were not shown because too many files have changed in this diff Show More