mirror of
https://github.com/Growstuff/growstuff.git
synced 2026-05-18 13:38:24 -04:00
merge from upstream
This commit is contained in:
@@ -1 +1 @@
|
||||
2.1.2
|
||||
2.1.5
|
||||
|
||||
38
.travis.yml
38
.travis.yml
@@ -1,12 +1,34 @@
|
||||
---
|
||||
sudo: false
|
||||
language: ruby
|
||||
|
||||
env: GROWSTUFF_SITE_NAME="Growstuff (travis)" RAILS_SECRET_TOKEN='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
|
||||
bundler_args: --without development production staging
|
||||
cache: bundler
|
||||
env:
|
||||
matrix:
|
||||
- GROWSTUFF_SITE_NAME="Growstuff (travis)" RAILS_SECRET_TOKEN='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
|
||||
global:
|
||||
secure: "Z5TpM2jEX4UCvNePnk/LwltQX48U2u9BRc+Iypr1x9QW2o228QJhPIOH39a8RMUrepGnkQIq9q3ZRUn98RfrJz1yThtlNFL3NmzdQ57gKgjGwfpa0e4Dwj/ZJqV2D84tDGjvdVYLP7zzaYZxQcwk/cgNpzKf/jq97HLNP7CYuf4="
|
||||
bundler_args: "--without development production staging"
|
||||
rvm:
|
||||
- 2.1.2
|
||||
- 2.1.5
|
||||
before_script:
|
||||
- psql -c 'create database growstuff_test;' -U postgres
|
||||
- psql -c 'create database growstuff_test;' -U postgres
|
||||
script:
|
||||
- bundle exec rake db:migrate --trace
|
||||
- bundle exec rspec spec/
|
||||
- bundle exec rake db:migrate --trace
|
||||
- bundle exec rspec spec/
|
||||
before_deploy:
|
||||
- bundle exec script/heroku_maintenance.rb on
|
||||
deploy:
|
||||
provider: heroku
|
||||
api_key:
|
||||
secure: WrQxf0fEKkCdXrjcejurobOnNNz3he4dDwjBbToXbQTQNDObPp7NetJrLsfM8FiUFEeOuvhIHHiDQtMvY720zGGAGxDptvgFS+0QHCUqoTRZA/yFfUmHlG2jROXTzk5uVK0AE4k6Ion5kX8+mM0EnMT/7u+MTFiukrJctSiEXfg=
|
||||
on:
|
||||
repo: Growstuff/growstuff
|
||||
app:
|
||||
dev: growstuff-staging
|
||||
travis_deploy: tranquil-basin-3130
|
||||
travis_containers: tranquil-basin-3130
|
||||
run:
|
||||
- "rake db:migrate"
|
||||
- "script/deploy-tasks.sh"
|
||||
- restart
|
||||
after_deploy:
|
||||
- bundle exec script/heroku_maintenance.rb off
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
Thanks for contributing to Growstuff!
|
||||
|
||||
Please include the following information in your pull request:
|
||||
When you create a pull request, please include the following:
|
||||
|
||||
* A link to the [Pivotal Tracker](http://tracker.growstuff.org/) task to which it relates.
|
||||
* Mention the issue it solves (eg. #123)
|
||||
* Your code should follow our [Coding style guide](http://wiki.growstuff.org/index.php/Coding_style_guide)
|
||||
* Make sure you have automated tests for your work, where possible.
|
||||
* Add your name (and that of your pair partner, if any) to [CONTRIBUTORS.md](CONTRIBUTORS.md).
|
||||
|
||||
@@ -11,10 +11,11 @@ submit the change with your pull request.
|
||||
- Alex Bayley / [Skud](https://github.com/Skud)
|
||||
- Cesy / [cesy](https://github.com/cesy)
|
||||
- Miles Gould / [pozorvlak](https://github.com/pozorvlak)
|
||||
- Joseph Caudle / [jcaudle](https://github.com/jcaudle)
|
||||
- Taylor Griffin / [tygriffin](https://github.com/tygriffin)
|
||||
|
||||
## Contributors
|
||||
|
||||
- Joseph Caudle / [jcaudle](https://github.com/jcaudle)
|
||||
- Ricky Amianym / [amianym](https://github.com/amianym)
|
||||
- Juliet Kemp / [julietk](https://github.com/julietk)
|
||||
- Federico Mena Quintero / [federicomenaquintero](https://github.com/federicomenaquintero)
|
||||
@@ -38,10 +39,8 @@ submit the change with your pull request.
|
||||
- Yaw Boakye / [yawboakye](https://github.com/yawboakye)
|
||||
- Ryan Clark / [IAMRYO](https://github.com/IAMRYO)
|
||||
- Marty Hines / [martyhines](https://github.com/martyhines)
|
||||
- Mackenzie "Maco" King / [maco](https://github.com/maco)
|
||||
- Amelia Greenhall / [ameliagreenhall](https://github.com/ameliagreenhall)
|
||||
- Barb Natali / [barbnatali](https://github.com/barbnatali)
|
||||
- Taylor Griffin / [tygriffin](https://github.com/tygriffin)
|
||||
- Marlena Compton / [Marlena](https://github.com/marlena)
|
||||
- Elizabeth A. Kari / [catfriend](https://github.com/catfriend)
|
||||
- Cheri Allen / [cherimarie](https://github.com/cherimarie)
|
||||
@@ -50,4 +49,7 @@ submit the change with your pull request.
|
||||
- Emma Winston / [emmawinston](https://github.com/emmawinston)
|
||||
- Kevin Rio / [krio](https://github.com/krio)
|
||||
- Yoong Kang Lim / [yoongkang](https://github.com/yoongkang)
|
||||
- Kevin Yang / [kevieyang](https://github.com/kevieyang)
|
||||
- Justin Hamman / [juzham](https://github.com/juzham)
|
||||
- Rocky Jaiswal / [rocky-jaiswal](https://github.com/rocky-jaiswal)
|
||||
|
||||
|
||||
157
Gemfile
157
Gemfile
@@ -1,92 +1,52 @@
|
||||
source 'https://rubygems.org'
|
||||
|
||||
ruby "2.1.2"
|
||||
ruby '2.1.5'
|
||||
|
||||
gem 'rails', '4.1.9'
|
||||
|
||||
gem 'bundler', '>=1.1.5'
|
||||
|
||||
gem 'rails', '3.2.13'
|
||||
gem 'rack', '~>1.4.5'
|
||||
gem 'json', '~>1.7.7'
|
||||
gem 'sass-rails', '~> 4.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 'uglifier', '~> 2.5.3' # JavaScript compressor
|
||||
|
||||
gem 'jquery-rails'
|
||||
gem 'jquery-ui-rails', '~> 5.0.2'
|
||||
gem 'js-routes' # provides access to Rails routes in Javascript
|
||||
gem 'flickraw'
|
||||
|
||||
gem 'leaflet-rails'
|
||||
gem 'leaflet-markercluster-rails'
|
||||
gem 'unicorn' # http server
|
||||
|
||||
gem 'unicorn' # http server
|
||||
gem 'pg'
|
||||
|
||||
gem 'figaro' # for handling config via ENV variables
|
||||
|
||||
gem 'cancan' # for checking member privileges
|
||||
|
||||
gem 'gibbon' # for Mailchimp newsletter subscriptions
|
||||
|
||||
gem 'csv_shaper' # CSV export
|
||||
gem 'figaro' # for handling config via ENV variables
|
||||
gem 'cancancan', '~> 1.9' # for checking member privileges
|
||||
gem 'gibbon' # for Mailchimp newsletter subscriptions
|
||||
gem 'csv_shaper' # CSV export
|
||||
|
||||
# vendored activemerchant for testing- needed for bogus paypal
|
||||
# gateway monkeypatch
|
||||
gem 'activemerchant', '1.33.0',
|
||||
:path => 'vendor/gems/activemerchant-1.33.0',
|
||||
:path => 'vendor/gems/activemerchant-1.33.0',
|
||||
:require => 'active_merchant'
|
||||
gem 'active_utils', '1.0.5',
|
||||
:path => 'vendor/gems/active_utils-1.0.5'
|
||||
:path => 'vendor/gems/active_utils-1.0.5'
|
||||
|
||||
group :production, :staging do
|
||||
gem 'newrelic_rpm'
|
||||
gem 'dalli'
|
||||
gem 'memcachier'
|
||||
gem 'rails_12factor' # supresses heroku plugin injection
|
||||
end
|
||||
|
||||
# Gems used only for assets and not required
|
||||
# in production environments by default.
|
||||
group :assets do
|
||||
# CSS preprocessor, used for app/assets/stylesheets/application.css
|
||||
gem 'sass-rails', '~> 3.2.3'
|
||||
# CoffeeScript is a Python-like language that compiles to JavaScript
|
||||
gem 'coffee-rails', '~> 3.2.1'
|
||||
|
||||
# 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.3'
|
||||
|
||||
# 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 'uglifier', '>= 1.0.3' # JavaScript compressor
|
||||
|
||||
gem 'compass-rails', '~> 1.0.3' # Yet Another CSS framework
|
||||
end
|
||||
|
||||
gem 'jquery-rails'
|
||||
gem 'jquery-ui-rails'
|
||||
gem 'js-routes' # provides access to Rails routes in Javascript
|
||||
gem 'flickraw'
|
||||
|
||||
# To use ActiveModel has_secure_password
|
||||
# gem 'bcrypt-ruby', '~> 3.0.0'
|
||||
|
||||
# To use Jbuilder templates for JSON
|
||||
# gem 'jbuilder'
|
||||
|
||||
# Use unicorn as the app server
|
||||
# gem 'unicorn'
|
||||
|
||||
group :development do
|
||||
# A debugger and irb alternative. Pry doesn't play nice
|
||||
# with unicorn, so start a Webrick server when debugging
|
||||
# with Pry
|
||||
gem 'pry'
|
||||
gem 'better_errors'
|
||||
gem 'binding_of_caller'
|
||||
gem 'letter_opener'
|
||||
end
|
||||
# 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'
|
||||
@@ -95,10 +55,10 @@ gem 'bluecloth'
|
||||
gem 'will_paginate', '~> 3.0'
|
||||
|
||||
# user signup/login/etc
|
||||
gem 'devise', '~> 3.2.0'
|
||||
gem 'devise', '~> 3.4.1'
|
||||
|
||||
# nicely formatted URLs
|
||||
gem 'friendly_id', '~> 4.0.10'
|
||||
gem 'friendly_id', '~> 5.0.4'
|
||||
|
||||
# gravatars
|
||||
gem 'gravatar-ultimate'
|
||||
@@ -118,16 +78,39 @@ gem 'omniauth-flickr', '>= 0.0.15'
|
||||
|
||||
gem 'rake', '>= 10.0.0'
|
||||
|
||||
group :development, :test do
|
||||
gem 'byebug' # debugging
|
||||
gem 'haml-rails' # HTML templating language
|
||||
gem 'rspec-rails', '~> 2.12.1' # unit testing framework
|
||||
gem 'database_cleaner', '~> 1.3.0'
|
||||
gem 'webrat' # provides HTML matchers for view tests
|
||||
gem 'factory_girl_rails', '~> 4.0' # for creating test data
|
||||
gem 'coveralls', require: false # coverage analysis
|
||||
gem 'capybara' # integration tests
|
||||
gem 'capybara-email' # integration tests for email
|
||||
gem 'poltergeist', '~> 1.5.1' # for headless JS testing
|
||||
gem 'i18n-tasks' # adds tests for finding missing and unused translations
|
||||
group :production, :staging do
|
||||
gem 'newrelic_rpm'
|
||||
gem 'dalli'
|
||||
gem 'memcachier'
|
||||
gem 'rails_12factor' # supresses heroku plugin injection
|
||||
end
|
||||
|
||||
group :development do
|
||||
# A debugger and irb alternative. Pry doesn't play nice
|
||||
# with unicorn, so start a Webrick server when debugging
|
||||
# with Pry
|
||||
gem 'pry'
|
||||
gem 'better_errors'
|
||||
gem 'binding_of_caller'
|
||||
gem 'letter_opener'
|
||||
gem 'quiet_assets'
|
||||
end
|
||||
|
||||
group :development, :test do
|
||||
gem 'haml-rails' # HTML templating language
|
||||
gem 'rspec-rails', '~> 3.1.0' # unit testing framework
|
||||
gem 'rspec-activemodel-mocks'
|
||||
gem 'byebug' # debugging
|
||||
gem 'database_cleaner', '~> 1.3.0'
|
||||
gem 'webrat' # provides HTML matchers for view tests
|
||||
gem 'factory_girl_rails', '~> 4.5.0' # for creating test data
|
||||
gem 'coveralls', require: false # coverage analysis
|
||||
gem 'capybara' # integration tests
|
||||
gem 'capybara-email' # integration tests for email
|
||||
gem 'poltergeist', '~> 1.5.1' # for headless JS testing
|
||||
gem 'i18n-tasks' # adds tests for finding missing and unused translations
|
||||
end
|
||||
|
||||
group :travis do
|
||||
gem 'heroku-api'
|
||||
end
|
||||
|
||||
268
Gemfile.lock
268
Gemfile.lock
@@ -20,35 +20,34 @@ PATH
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
actionmailer (3.2.13)
|
||||
actionpack (= 3.2.13)
|
||||
mail (~> 2.5.3)
|
||||
actionpack (3.2.13)
|
||||
activemodel (= 3.2.13)
|
||||
activesupport (= 3.2.13)
|
||||
builder (~> 3.0.0)
|
||||
actionmailer (4.1.9)
|
||||
actionpack (= 4.1.9)
|
||||
actionview (= 4.1.9)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
actionpack (4.1.9)
|
||||
actionview (= 4.1.9)
|
||||
activesupport (= 4.1.9)
|
||||
rack (~> 1.5.2)
|
||||
rack-test (~> 0.6.2)
|
||||
actionview (4.1.9)
|
||||
activesupport (= 4.1.9)
|
||||
builder (~> 3.1)
|
||||
erubis (~> 2.7.0)
|
||||
journey (~> 1.0.4)
|
||||
rack (~> 1.4.5)
|
||||
rack-cache (~> 1.2)
|
||||
rack-test (~> 0.6.1)
|
||||
sprockets (~> 2.2.1)
|
||||
activemodel (3.2.13)
|
||||
activesupport (= 3.2.13)
|
||||
builder (~> 3.0.0)
|
||||
activerecord (3.2.13)
|
||||
activemodel (= 3.2.13)
|
||||
activesupport (= 3.2.13)
|
||||
arel (~> 3.0.2)
|
||||
tzinfo (~> 0.3.29)
|
||||
activeresource (3.2.13)
|
||||
activemodel (= 3.2.13)
|
||||
activesupport (= 3.2.13)
|
||||
activesupport (3.2.13)
|
||||
i18n (= 0.6.1)
|
||||
multi_json (~> 1.0)
|
||||
activemodel (4.1.9)
|
||||
activesupport (= 4.1.9)
|
||||
builder (~> 3.1)
|
||||
activerecord (4.1.9)
|
||||
activemodel (= 4.1.9)
|
||||
activesupport (= 4.1.9)
|
||||
arel (~> 5.0.0)
|
||||
activesupport (4.1.9)
|
||||
i18n (~> 0.6, >= 0.6.9)
|
||||
json (~> 1.7, >= 1.7.7)
|
||||
minitest (~> 5.1)
|
||||
thread_safe (~> 0.1)
|
||||
tzinfo (~> 1.1)
|
||||
addressable (2.3.6)
|
||||
arel (3.0.3)
|
||||
arel (5.0.1.20140414130214)
|
||||
bcrypt (3.1.9)
|
||||
better_errors (2.0.0)
|
||||
coderay (>= 1.0.0)
|
||||
@@ -59,12 +58,12 @@ GEM
|
||||
bluecloth (2.2.0)
|
||||
bootstrap-datepicker-rails (1.3.0.2)
|
||||
railties (>= 3.0)
|
||||
builder (3.0.4)
|
||||
builder (3.2.2)
|
||||
byebug (3.5.1)
|
||||
columnize (~> 0.8)
|
||||
debugger-linecache (~> 1.2)
|
||||
slop (~> 3.6)
|
||||
cancan (1.6.10)
|
||||
cancancan (1.9.2)
|
||||
capybara (2.4.4)
|
||||
mime-types (>= 1.16)
|
||||
nokogiri (>= 1.3.3)
|
||||
@@ -74,24 +73,17 @@ GEM
|
||||
capybara-email (2.4.0)
|
||||
capybara (~> 2.4)
|
||||
mail
|
||||
chunky_png (1.3.3)
|
||||
cliver (0.3.2)
|
||||
coderay (1.1.0)
|
||||
coffee-rails (3.2.2)
|
||||
coffee-rails (4.1.0)
|
||||
coffee-script (>= 2.2.0)
|
||||
railties (~> 3.2.0)
|
||||
railties (>= 4.0.0, < 5.0)
|
||||
coffee-script (2.3.0)
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.8.0)
|
||||
columnize (0.8.9)
|
||||
columnize (0.9.0)
|
||||
commonjs (0.2.7)
|
||||
compass (0.12.7)
|
||||
chunky_png (~> 1.2)
|
||||
fssm (>= 0.2.7)
|
||||
sass (~> 3.2.19)
|
||||
compass-rails (1.0.3)
|
||||
compass (>= 0.12.2, < 0.14)
|
||||
coveralls (0.7.1)
|
||||
multi_json (~> 1.3)
|
||||
rest-client
|
||||
@@ -104,19 +96,21 @@ GEM
|
||||
database_cleaner (1.3.0)
|
||||
debug_inspector (0.0.2)
|
||||
debugger-linecache (1.2.0)
|
||||
devise (3.2.4)
|
||||
devise (3.4.1)
|
||||
bcrypt (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (>= 3.2.6, < 5)
|
||||
responders
|
||||
thread_safe (~> 0.1)
|
||||
warden (~> 1.2.3)
|
||||
diff-lcs (1.1.3)
|
||||
diff-lcs (1.2.5)
|
||||
docile (1.1.5)
|
||||
easy_translate (0.5.0)
|
||||
json
|
||||
thread
|
||||
thread_safe
|
||||
erubis (2.7.0)
|
||||
excon (0.43.0)
|
||||
execjs (2.2.2)
|
||||
factory_girl (4.5.0)
|
||||
activesupport (>= 3.0.0)
|
||||
@@ -126,29 +120,38 @@ GEM
|
||||
figaro (1.0.0)
|
||||
thor (~> 0.14)
|
||||
flickraw (0.9.8)
|
||||
friendly_id (4.0.10.1)
|
||||
activerecord (>= 3.0, < 4.0)
|
||||
fssm (0.2.10)
|
||||
friendly_id (5.0.4)
|
||||
activerecord (>= 4.0.0)
|
||||
gibbon (1.1.4)
|
||||
httparty
|
||||
multi_json (>= 1.3.4)
|
||||
gravatar-ultimate (2.0.0)
|
||||
activesupport (>= 2.3.14)
|
||||
rack
|
||||
haml (4.0.5)
|
||||
haml (4.1.0.beta.1)
|
||||
tilt
|
||||
haml-rails (0.4)
|
||||
actionpack (>= 3.1, < 4.1)
|
||||
activesupport (>= 3.1, < 4.1)
|
||||
haml (>= 3.1, < 4.1)
|
||||
railties (>= 3.1, < 4.1)
|
||||
hashie (3.3.1)
|
||||
haml-rails (0.6.0)
|
||||
actionpack (>= 4.0.1)
|
||||
activesupport (>= 4.0.1)
|
||||
haml (>= 3.1, < 5.0)
|
||||
html2haml (>= 1.0.1)
|
||||
railties (>= 4.0.1)
|
||||
hashie (3.3.2)
|
||||
heroku-api (0.3.22)
|
||||
excon (~> 0.38)
|
||||
multi_json (~> 1.8)
|
||||
highline (1.6.21)
|
||||
hike (1.2.3)
|
||||
httparty (0.11.0)
|
||||
multi_json (~> 1.0)
|
||||
hpricot (0.8.6)
|
||||
html2haml (1.0.1)
|
||||
erubis (~> 2.7.0)
|
||||
haml (>= 4.0.0.rc.1)
|
||||
hpricot (~> 0.8.6)
|
||||
ruby_parser (~> 3.1.1)
|
||||
httparty (0.13.3)
|
||||
json (~> 1.8)
|
||||
multi_xml (>= 0.5.2)
|
||||
i18n (0.6.1)
|
||||
i18n (0.7.0)
|
||||
i18n-tasks (0.7.8)
|
||||
activesupport
|
||||
easy_translate (>= 0.5.0)
|
||||
@@ -158,16 +161,15 @@ GEM
|
||||
slop (>= 3.5.0)
|
||||
term-ansicolor
|
||||
terminal-table
|
||||
journey (1.0.4)
|
||||
jquery-rails (3.1.2)
|
||||
railties (>= 3.0, < 5.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
jquery-ui-rails (4.1.2)
|
||||
railties (>= 3.1.0)
|
||||
jquery-ui-rails (5.0.3)
|
||||
railties (>= 3.2.16)
|
||||
js-routes (0.9.9)
|
||||
railties (>= 3.2)
|
||||
sprockets-rails
|
||||
json (1.7.7)
|
||||
json (1.8.2)
|
||||
kgio (2.9.2)
|
||||
launchy (2.4.3)
|
||||
addressable (~> 2.3)
|
||||
@@ -181,21 +183,21 @@ GEM
|
||||
less (~> 2.5.0)
|
||||
less-rails-bootstrap (3.2.0)
|
||||
less-rails (~> 2.5.0)
|
||||
letter_opener (1.2.0)
|
||||
letter_opener (1.3.0)
|
||||
launchy (~> 2.2)
|
||||
libv8 (3.16.14.3)
|
||||
mail (2.5.4)
|
||||
mime-types (~> 1.16)
|
||||
treetop (~> 1.4.8)
|
||||
libv8 (3.16.14.7)
|
||||
mail (2.6.3)
|
||||
mime-types (>= 1.16, < 3)
|
||||
memcachier (0.0.2)
|
||||
method_source (0.8.2)
|
||||
mime-types (1.25.1)
|
||||
mime-types (2.4.3)
|
||||
mini_portile (0.6.1)
|
||||
minitest (5.5.1)
|
||||
multi_json (1.10.1)
|
||||
multi_xml (0.5.5)
|
||||
netrc (0.8.0)
|
||||
newrelic_rpm (3.9.6.257)
|
||||
nokogiri (1.6.4.1)
|
||||
netrc (0.10.0)
|
||||
newrelic_rpm (3.9.8.273)
|
||||
nokogiri (1.6.5)
|
||||
mini_portile (~> 0.6.0)
|
||||
oauth (0.4.7)
|
||||
omniauth (1.2.2)
|
||||
@@ -216,75 +218,87 @@ GEM
|
||||
cliver (~> 0.3.1)
|
||||
multi_json (~> 1.0)
|
||||
websocket-driver (>= 0.2.0)
|
||||
polyglot (0.3.5)
|
||||
pry (0.10.1)
|
||||
coderay (~> 1.1.0)
|
||||
method_source (~> 0.8.1)
|
||||
slop (~> 3.4)
|
||||
rack (1.4.5)
|
||||
rack-cache (1.2)
|
||||
rack (>= 0.4)
|
||||
rack-ssl (1.3.4)
|
||||
rack
|
||||
rack-test (0.6.2)
|
||||
quiet_assets (1.1.0)
|
||||
railties (>= 3.1, < 5.0)
|
||||
rack (1.5.2)
|
||||
rack-test (0.6.3)
|
||||
rack (>= 1.0)
|
||||
rails (3.2.13)
|
||||
actionmailer (= 3.2.13)
|
||||
actionpack (= 3.2.13)
|
||||
activerecord (= 3.2.13)
|
||||
activeresource (= 3.2.13)
|
||||
activesupport (= 3.2.13)
|
||||
bundler (~> 1.0)
|
||||
railties (= 3.2.13)
|
||||
rails (4.1.9)
|
||||
actionmailer (= 4.1.9)
|
||||
actionpack (= 4.1.9)
|
||||
actionview (= 4.1.9)
|
||||
activemodel (= 4.1.9)
|
||||
activerecord (= 4.1.9)
|
||||
activesupport (= 4.1.9)
|
||||
bundler (>= 1.3.0, < 2.0)
|
||||
railties (= 4.1.9)
|
||||
sprockets-rails (~> 2.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)
|
||||
railties (3.2.13)
|
||||
actionpack (= 3.2.13)
|
||||
activesupport (= 3.2.13)
|
||||
rack-ssl (~> 1.3.2)
|
||||
railties (4.1.9)
|
||||
actionpack (= 4.1.9)
|
||||
activesupport (= 4.1.9)
|
||||
rake (>= 0.8.7)
|
||||
rdoc (~> 3.4)
|
||||
thor (>= 0.14.6, < 2.0)
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
raindrops (0.13.0)
|
||||
rake (10.3.2)
|
||||
rdoc (3.12.2)
|
||||
json (~> 1.4)
|
||||
rake (10.4.2)
|
||||
ref (1.0.5)
|
||||
responders (1.1.2)
|
||||
railties (>= 3.2, < 4.2)
|
||||
rest-client (1.7.2)
|
||||
mime-types (>= 1.16, < 3.0)
|
||||
netrc (~> 0.7)
|
||||
rspec-core (2.12.2)
|
||||
rspec-expectations (2.12.1)
|
||||
diff-lcs (~> 1.1.3)
|
||||
rspec-mocks (2.12.2)
|
||||
rspec-rails (2.12.2)
|
||||
rspec-activemodel-mocks (1.0.1)
|
||||
activemodel (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
rspec-mocks (>= 2.99, < 4.0)
|
||||
rspec-core (3.1.7)
|
||||
rspec-support (~> 3.1.0)
|
||||
rspec-expectations (3.1.2)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.1.0)
|
||||
rspec-mocks (3.1.3)
|
||||
rspec-support (~> 3.1.0)
|
||||
rspec-rails (3.1.0)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
rspec-core (~> 2.12.0)
|
||||
rspec-expectations (~> 2.12.0)
|
||||
rspec-mocks (~> 2.12.0)
|
||||
rspec-core (~> 3.1.0)
|
||||
rspec-expectations (~> 3.1.0)
|
||||
rspec-mocks (~> 3.1.0)
|
||||
rspec-support (~> 3.1.0)
|
||||
rspec-support (3.1.2)
|
||||
ruby_parser (3.1.3)
|
||||
sexp_processor (~> 4.1)
|
||||
sass (3.2.19)
|
||||
sass-rails (3.2.6)
|
||||
railties (~> 3.2.0)
|
||||
sass (>= 3.1.10)
|
||||
tilt (~> 1.3)
|
||||
sass-rails (4.0.5)
|
||||
railties (>= 4.0.0, < 5.0)
|
||||
sass (~> 3.2.2)
|
||||
sprockets (~> 2.8, < 3.0)
|
||||
sprockets-rails (~> 2.0)
|
||||
sexp_processor (4.4.4)
|
||||
simplecov (0.9.1)
|
||||
docile (~> 1.1.0)
|
||||
multi_json (~> 1.0)
|
||||
simplecov-html (~> 0.8.0)
|
||||
simplecov-html (0.8.0)
|
||||
slop (3.6.0)
|
||||
sprockets (2.2.3)
|
||||
sprockets (2.12.3)
|
||||
hike (~> 1.2)
|
||||
multi_json (~> 1.0)
|
||||
rack (~> 1.0)
|
||||
tilt (~> 1.1, != 1.3.0)
|
||||
sprockets-rails (0.0.1)
|
||||
sprockets (>= 1.0.2)
|
||||
sprockets-rails (2.2.2)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
sprockets (>= 2.8, < 4.0)
|
||||
term-ansicolor (1.3.0)
|
||||
tins (~> 1.0)
|
||||
terminal-table (1.4.5)
|
||||
@@ -296,13 +310,11 @@ GEM
|
||||
thread_safe (0.3.4)
|
||||
tilt (1.4.1)
|
||||
tins (1.3.3)
|
||||
treetop (1.4.15)
|
||||
polyglot
|
||||
polyglot (>= 0.3.1)
|
||||
tzinfo (0.3.42)
|
||||
uglifier (2.2.1)
|
||||
tzinfo (1.2.2)
|
||||
thread_safe (~> 0.1)
|
||||
uglifier (2.5.3)
|
||||
execjs (>= 0.3.0)
|
||||
multi_json (~> 1.0, >= 1.0.2)
|
||||
json (>= 1.8.0)
|
||||
unicorn (4.8.3)
|
||||
kgio (~> 2.6)
|
||||
rack
|
||||
@@ -313,7 +325,9 @@ GEM
|
||||
nokogiri (>= 1.2.0)
|
||||
rack (>= 1.0)
|
||||
rack-test (>= 0.5.3)
|
||||
websocket-driver (0.4.0)
|
||||
websocket-driver (0.5.0)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.0)
|
||||
will_paginate (3.0.7)
|
||||
xpath (2.0.0)
|
||||
nokogiri (~> 1.3)
|
||||
@@ -330,37 +344,36 @@ DEPENDENCIES
|
||||
bootstrap-datepicker-rails
|
||||
bundler (>= 1.1.5)
|
||||
byebug
|
||||
cancan
|
||||
cancancan (~> 1.9)
|
||||
capybara
|
||||
capybara-email
|
||||
coffee-rails (~> 3.2.1)
|
||||
compass-rails (~> 1.0.3)
|
||||
coffee-rails (~> 4.1.0)
|
||||
coveralls
|
||||
csv_shaper
|
||||
dalli
|
||||
database_cleaner (~> 1.3.0)
|
||||
devise (~> 3.2.0)
|
||||
factory_girl_rails (~> 4.0)
|
||||
devise (~> 3.4.1)
|
||||
factory_girl_rails (~> 4.5.0)
|
||||
figaro
|
||||
flickraw
|
||||
friendly_id (~> 4.0.10)
|
||||
friendly_id (~> 5.0.4)
|
||||
geocoder!
|
||||
gibbon
|
||||
gravatar-ultimate
|
||||
haml
|
||||
haml-rails
|
||||
heroku-api
|
||||
i18n-tasks
|
||||
jquery-rails
|
||||
jquery-ui-rails
|
||||
jquery-ui-rails (~> 5.0.2)
|
||||
js-routes
|
||||
json (~> 1.7.7)
|
||||
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.3)
|
||||
libv8 (= 3.16.14.7)
|
||||
memcachier
|
||||
newrelic_rpm
|
||||
omniauth
|
||||
@@ -369,14 +382,15 @@ DEPENDENCIES
|
||||
pg
|
||||
poltergeist (~> 1.5.1)
|
||||
pry
|
||||
rack (~> 1.4.5)
|
||||
rails (= 3.2.13)
|
||||
quiet_assets
|
||||
rails (= 4.1.9)
|
||||
rails_12factor
|
||||
rake (>= 10.0.0)
|
||||
rspec-rails (~> 2.12.1)
|
||||
sass-rails (~> 3.2.3)
|
||||
rspec-activemodel-mocks
|
||||
rspec-rails (~> 3.1.0)
|
||||
sass-rails (~> 4.0.4)
|
||||
therubyracer (~> 0.12)
|
||||
uglifier (>= 1.0.3)
|
||||
uglifier (~> 2.5.3)
|
||||
unicorn
|
||||
webrat
|
||||
will_paginate (~> 3.0)
|
||||
|
||||
36
README.md
36
README.md
@@ -16,18 +16,42 @@ encourage participation from people of all backgrounds and skill levels.
|
||||
|
||||
## Important links
|
||||
|
||||
* [Wiki](http://wiki.growstuff.org/) (general documentation)
|
||||
* [Task tracker](http://tracker.growstuff.org/) (recent and upcoming work, bugs, etc)
|
||||
* [Issues](http://github.com/Growstuff/growstuff/issues) (features we're
|
||||
working on, known bugs, etc)
|
||||
* [Discussion forums](http://wiki.growstuff.org/index.php/Discussion_forums) (mailing lists, IRC, etc)
|
||||
* [Wiki](http://wiki.growstuff.org/) (general documentation)
|
||||
|
||||
## For developers
|
||||
## For coders
|
||||
|
||||
Growstuff is built in Ruby on Rails and also uses JavaScript for
|
||||
frontend features. We welcome contributions -- see
|
||||
[CONTRIBUTING](CONTRIBUTING.md) for details.
|
||||
|
||||
* Start by looking at our [task tracker](http://tracker.growstuff.org/) for something to work on.
|
||||
* Drop in to one of our [discussion forums](http://wiki.growstuff.org/index.php/Discussion_forums) to talk to our team about it.
|
||||
* To set up your development environment, see [Getting started](http://wiki.growstuff.org/index.php/Development/Getting_Started).
|
||||
* We encourage [pair programming](http://wiki.growstuff.org/index.php/Pairing), especially for newer developers.
|
||||
* We encourage [pair programming](http://wiki.growstuff.org/index.php/Pairing), especially for newer developers. [Find a pair programming partner.](http://talk.growstuff.org/t/find-a-pair-programming-partner/13)
|
||||
* 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).
|
||||
|
||||
## For designers, writers, researchers, data wranglers, and other contributors
|
||||
|
||||
There are heaps of ways to get involved and contribute no matter what
|
||||
your skills and interests.
|
||||
|
||||
You might like to check out:
|
||||
|
||||
* The [Get Involved](http://wiki.growstuff.org/index.php/Get_involved)
|
||||
page on our wiki, which has lots of detail for different areas
|
||||
* [Growstuff Talk](http://talk.growstuff.org/) especially the [Idea category](http://talk.growstuff.org/c/idea)
|
||||
|
||||
Here on Github, you might find these useful:
|
||||
|
||||
* [needs: design](https://github.com/Growstuff/growstuff/labels/needs:%20design) - tasks requiring high-level design
|
||||
* [needs: visual design](https://github.com/Growstuff/growstuff/labels/needs:%20visual design) - tasks requiring visual/graphical design
|
||||
* [needs: documentation](https://github.com/Growstuff/growstuff/labels/needs:%20documentation)
|
||||
* [needs: data](https://github.com/Growstuff/growstuff/labels/needs:%20data) - tasks requiring data entry, data design, data import, or similar
|
||||
|
||||
Feel free to comment on any of the issues you find there, or open up a broader conversation on [Growstuff Talk](http://talk.growstuff.org).
|
||||
|
||||
## Contact
|
||||
|
||||
For more information about this project, contact [info@growstuff.org](mailto:info@growstuff.org).
|
||||
|
||||
BIN
app/assets/images/facebook_32.png
Normal file
BIN
app/assets/images/facebook_32.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 613 B |
@@ -15,7 +15,7 @@
|
||||
//= require js-routes
|
||||
//= require jquery
|
||||
//= require jquery_ujs
|
||||
//= require jquery.ui.autocomplete
|
||||
//= require jquery-ui/autocomplete
|
||||
//= require twitter/bootstrap
|
||||
//= require_tree .
|
||||
//= require bootstrap-datepicker
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* 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 jquery-ui/autocomplete
|
||||
*= require bootstrap-datepicker
|
||||
*= require leaflet
|
||||
*= require leaflet.markercluster
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
|
||||
|
||||
@import "twitter/bootstrap/bootstrap";
|
||||
@import "custom_bootstrap/variables";
|
||||
// this padding needs to be done before the responsive stuff is imported
|
||||
@@ -122,7 +124,7 @@ p.stats {
|
||||
color: @brown;
|
||||
}
|
||||
|
||||
.crop-thumbnail {
|
||||
.photo-thumbnail {
|
||||
position:relative;
|
||||
padding:0;
|
||||
img {
|
||||
@@ -149,16 +151,56 @@ p.stats {
|
||||
}
|
||||
}
|
||||
|
||||
.member-thumbnail {
|
||||
img {
|
||||
height: 85px;
|
||||
width: 85px;
|
||||
max-width: 85px
|
||||
}
|
||||
}
|
||||
|
||||
.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 {
|
||||
@@ -174,31 +216,48 @@ li.crop-hierarchy {
|
||||
margin: 40px 0px 0px 0px !important;
|
||||
}
|
||||
|
||||
// navbar centering
|
||||
footer .navbar .nav {
|
||||
float: none;
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
/* ie7 fix */
|
||||
*zoom: 1;
|
||||
/* hasLayout ie7 trigger */
|
||||
vertical-align: top;
|
||||
> li {
|
||||
float: none;
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
/* ie7 fix */
|
||||
*zoom: 1;
|
||||
/* hasLayout ie7 trigger */
|
||||
vertical-align: top;
|
||||
// footer
|
||||
|
||||
footer {
|
||||
#contact, #about-growstuff, #policies {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
.navbar-bottom.navbar {
|
||||
text-align: center;
|
||||
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%;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
class AccountTypesController < ApplicationController
|
||||
before_filter :authenticate_member!
|
||||
load_and_authorize_resource
|
||||
|
||||
# GET /account_types
|
||||
def index
|
||||
@account_types = AccountType.all
|
||||
@@ -34,7 +36,7 @@ class AccountTypesController < ApplicationController
|
||||
|
||||
# POST /account_types
|
||||
def create
|
||||
@account_type = AccountType.new(params[:account_type])
|
||||
@account_type = AccountType.new(account_type_params)
|
||||
|
||||
respond_to do |format|
|
||||
if @account_type.save
|
||||
@@ -50,7 +52,7 @@ class AccountTypesController < ApplicationController
|
||||
@account_type = AccountType.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
if @account_type.update_attributes(params[:account_type])
|
||||
if @account_type.update(account_type_params)
|
||||
format.html { redirect_to @account_type, notice: 'Account type was successfully updated.' }
|
||||
else
|
||||
format.html { render action: "edit" }
|
||||
@@ -67,4 +69,10 @@ class AccountTypesController < ApplicationController
|
||||
format.html { redirect_to account_types_url, notice: 'Account type was successfully deleted.' }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def account_type_params
|
||||
params.require(:account_type).permit(:is_paid, :is_permanent_paid, :name)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
class AccountsController < ApplicationController
|
||||
before_filter :authenticate_member!
|
||||
load_and_authorize_resource
|
||||
|
||||
# GET /accounts
|
||||
def index
|
||||
@accounts = Account.all
|
||||
@@ -28,7 +30,7 @@ class AccountsController < ApplicationController
|
||||
@account = Account.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
if @account.update_attributes(params[:account])
|
||||
if @account.update(params[:account])
|
||||
format.html { redirect_to @account, notice: 'Account detail was successfully updated.' }
|
||||
else
|
||||
format.html { render action: "edit" }
|
||||
@@ -36,4 +38,10 @@ class AccountsController < ApplicationController
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def account_params
|
||||
params.require(:account).permit(:account_type_id, :member_id, :paid_until)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
class AlternateNamesController < ApplicationController
|
||||
before_filter :authenticate_member!, :except => [:index, :show]
|
||||
load_and_authorize_resource
|
||||
|
||||
# GET /alternate_names
|
||||
@@ -44,7 +45,7 @@ class AlternateNamesController < ApplicationController
|
||||
# POST /alternate_names.json
|
||||
def create
|
||||
params[:alternate_name][:creator_id] = current_member.id
|
||||
@alternate_name = AlternateName.new(params[:alternate_name])
|
||||
@alternate_name = AlternateName.new(alternate_name_params)
|
||||
|
||||
respond_to do |format|
|
||||
if @alternate_name.save
|
||||
@@ -63,7 +64,7 @@ class AlternateNamesController < ApplicationController
|
||||
@alternate_name = AlternateName.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
if @alternate_name.update_attributes(params[:alternate_name])
|
||||
if @alternate_name.update(alternate_name_params)
|
||||
format.html { redirect_to @alternate_name.crop, notice: 'Alternate name was successfully updated.' }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
@@ -87,4 +88,10 @@ class AlternateNamesController < ApplicationController
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def alternate_name_params
|
||||
params.require(:alternate_name).permit(:crop_id, :name, :creator_id)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -43,4 +43,36 @@ class ApplicationController < ActionController::Base
|
||||
I18n.available_locales.map(&:to_s).include?(parsed_locale) ? parsed_locale : nil
|
||||
end
|
||||
|
||||
before_action :configure_permitted_parameters, if: :devise_controller?
|
||||
|
||||
protected
|
||||
|
||||
def configure_permitted_parameters
|
||||
devise_parameter_sanitizer.for(:sign_up) do |member|
|
||||
member.permit(:login_name, :email, :password, :password_confirmation,
|
||||
:remember_me, :login,
|
||||
# terms of service
|
||||
:tos_agreement,
|
||||
# profile stuff
|
||||
:bio, :location, :latitude, :longitude,
|
||||
# email settings
|
||||
:show_email, :newsletter, :send_notification_email, :send_planting_reminder
|
||||
)
|
||||
end
|
||||
|
||||
devise_parameter_sanitizer.for(:account_update) do |member|
|
||||
member.permit(:login_name, :email, :password, :password_confirmation,
|
||||
:remember_me, :login,
|
||||
# terms of service
|
||||
:tos_agreement,
|
||||
# profile stuff
|
||||
:bio, :location, :latitude, :longitude,
|
||||
# email settings
|
||||
:show_email, :newsletter, :send_notification_email, :send_planting_reminder,
|
||||
#update password
|
||||
:current_password
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,15 +1,7 @@
|
||||
class AuthenticationsController < ApplicationController
|
||||
before_filter :authenticate_member!
|
||||
load_and_authorize_resource
|
||||
|
||||
# GET /authentications
|
||||
def index
|
||||
@authentications = current_member.authentications if member_signed_in?
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
end
|
||||
end
|
||||
|
||||
# POST /authentications
|
||||
def create
|
||||
auth = request.env['omniauth.auth']
|
||||
@@ -26,12 +18,17 @@ class AuthenticationsController < ApplicationController
|
||||
name = auth['info']['name']
|
||||
end
|
||||
|
||||
@authentication = current_member.authentications.find_or_create_by_provider_and_uid(
|
||||
:provider => auth['provider'],
|
||||
:uid => auth['uid'],
|
||||
@authentication = current_member.authentications
|
||||
.create_with(
|
||||
:name => name,
|
||||
:token => auth['credentials']['token'],
|
||||
:secret => auth['credentials']['secret'])
|
||||
:secret => auth['credentials']['secret']
|
||||
)
|
||||
.find_or_create_by(
|
||||
:provider => auth['provider'],
|
||||
:uid => auth['uid'],
|
||||
:name => name)
|
||||
|
||||
flash[:notice] = "Authentication successful."
|
||||
else
|
||||
flash[:notice] = "Authentication failed."
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
class CommentsController < ApplicationController
|
||||
before_filter :authenticate_member!, :except => [:index, :show]
|
||||
load_and_authorize_resource
|
||||
|
||||
cache_sweeper :comment_sweeper
|
||||
|
||||
# GET /comments
|
||||
# GET /comments.json
|
||||
def index
|
||||
@@ -54,11 +53,11 @@ class CommentsController < ApplicationController
|
||||
# POST /comments.json
|
||||
def create
|
||||
params[:comment][:author_id] = current_member.id
|
||||
@comment = Comment.new(params[:comment])
|
||||
@comment = Comment.new(comment_params)
|
||||
|
||||
respond_to do |format|
|
||||
if @comment.save
|
||||
format.html { redirect_to @comment.post, notice: 'Comment was successfully created.' }
|
||||
format.html { redirect_to @comment.post, notice: "Comment was successfully created." }
|
||||
format.json { render json: @comment, status: :created, location: @comment }
|
||||
else
|
||||
format.html { render action: "new" }
|
||||
@@ -78,7 +77,7 @@ class CommentsController < ApplicationController
|
||||
params[:comment].delete("author_id")
|
||||
|
||||
respond_to do |format|
|
||||
if @comment.update_attributes(params[:comment])
|
||||
if @comment.update(comment_params)
|
||||
format.html { redirect_to @comment.post, notice: 'Comment was successfully updated.' }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
@@ -100,4 +99,10 @@ class CommentsController < ApplicationController
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def comment_params
|
||||
params.require(:comment).permit(:author_id, :body, :post_id)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
class CropsController < ApplicationController
|
||||
before_filter :authenticate_member!, :except => [:index, :hierarchy, :search, :show]
|
||||
load_and_authorize_resource
|
||||
skip_authorize_resource :only => [:hierarchy, :search]
|
||||
|
||||
cache_sweeper :crop_sweeper
|
||||
|
||||
# GET /crops
|
||||
# GET /crops.json
|
||||
def index
|
||||
@@ -55,7 +54,7 @@ class CropsController < ApplicationController
|
||||
|
||||
@partial_matches = Crop.search(params[:search])
|
||||
# exclude exact match from partial match list
|
||||
@partial_matches.reject!{ |r| @exact_match && r.eql?(@exact_match) }
|
||||
@partial_matches = @partial_matches.reject{ |r| @exact_match && r.eql?(@exact_match) }
|
||||
|
||||
@fuzzy = Crop.search(params[:term])
|
||||
|
||||
@@ -103,7 +102,7 @@ class CropsController < ApplicationController
|
||||
# POST /crops.json
|
||||
def create
|
||||
params[:crop][:creator_id] = current_member.id
|
||||
@crop = Crop.new(params[:crop])
|
||||
@crop = Crop.new(crop_params)
|
||||
|
||||
respond_to do |format|
|
||||
if @crop.save
|
||||
@@ -122,7 +121,7 @@ class CropsController < ApplicationController
|
||||
@crop = Crop.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
if @crop.update_attributes(params[:crop])
|
||||
if @crop.update(crop_params)
|
||||
format.html { redirect_to @crop, notice: 'Crop was successfully updated.' }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
@@ -143,4 +142,10 @@ class CropsController < ApplicationController
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def crop_params
|
||||
params.require(:crop).permit(:en_wikipedia_url, :name, :parent_id, :creator_id, :scientific_names_attributes => [:scientific_name])
|
||||
end
|
||||
end
|
||||
|
||||
35
app/controllers/follows_controller.rb
Normal file
35
app/controllers/follows_controller.rb
Normal file
@@ -0,0 +1,35 @@
|
||||
class FollowsController < ApplicationController
|
||||
before_filter :authenticate_member!
|
||||
load_and_authorize_resource
|
||||
skip_load_resource :only => :create
|
||||
|
||||
# POST /follows
|
||||
def create
|
||||
|
||||
@follow = current_member.follows.build(:followed_id => follow_params[:followed_id])
|
||||
|
||||
if @follow.save
|
||||
flash[:notice] = "Followed #{ @follow.followed.login_name }"
|
||||
redirect_to :back
|
||||
else
|
||||
flash[:error] = "Already following or error while following."
|
||||
redirect_to :back
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /follows/1
|
||||
def destroy
|
||||
@follow = current_member.follows.find(follow_params[:id])
|
||||
unfollowed_name = @follow.followed.login_name
|
||||
@follow.destroy
|
||||
|
||||
flash[:notice] = "Unfollowed #{ unfollowed_name }"
|
||||
redirect_to root_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def follow_params
|
||||
params.permit(:id, :followed_id, :follower_id, :authenticity_token, :_method)
|
||||
end
|
||||
end
|
||||
@@ -1,8 +1,6 @@
|
||||
class ForumsController < ApplicationController
|
||||
load_and_authorize_resource
|
||||
|
||||
cache_sweeper :forum_sweeper
|
||||
|
||||
# GET /forums
|
||||
# GET /forums.json
|
||||
def index
|
||||
@@ -44,7 +42,7 @@ class ForumsController < ApplicationController
|
||||
# POST /forums
|
||||
# POST /forums.json
|
||||
def create
|
||||
@forum = Forum.new(params[:forum])
|
||||
@forum = Forum.new(forum_params)
|
||||
|
||||
respond_to do |format|
|
||||
if @forum.save
|
||||
@@ -63,7 +61,7 @@ class ForumsController < ApplicationController
|
||||
@forum = Forum.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
if @forum.update_attributes(params[:forum])
|
||||
if @forum.update(forum_params)
|
||||
format.html { redirect_to @forum, notice: 'Forum was successfully updated.' }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
@@ -84,4 +82,10 @@ class ForumsController < ApplicationController
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def forum_params
|
||||
params.require(:forum).permit(:description, :name, :owner_id, :slug)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
class GardensController < ApplicationController
|
||||
before_filter :authenticate_member!, :except => [:index, :show]
|
||||
load_and_authorize_resource
|
||||
|
||||
cache_sweeper :garden_sweeper
|
||||
|
||||
# GET /gardens
|
||||
# GET /gardens.json
|
||||
@@ -49,12 +49,13 @@ class GardensController < ApplicationController
|
||||
# POST /gardens.json
|
||||
def create
|
||||
params[:garden][:owner_id] = current_member.id
|
||||
@garden = Garden.new(params[:garden])
|
||||
@garden = Garden.new(garden_params)
|
||||
|
||||
respond_to do |format|
|
||||
if @garden.save
|
||||
format.html { redirect_to @garden, notice: 'Garden was successfully created.' }
|
||||
format.json { render json: @garden, status: :created, location: @garden }
|
||||
expire_fragment("homepage_stats")
|
||||
else
|
||||
format.html { render action: "new" }
|
||||
format.json { render json: @garden.errors, status: :unprocessable_entity }
|
||||
@@ -68,7 +69,7 @@ class GardensController < ApplicationController
|
||||
@garden = Garden.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
if @garden.update_attributes(params[:garden])
|
||||
if @garden.update(garden_params)
|
||||
format.html { redirect_to @garden, notice: 'Garden was successfully updated.' }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
@@ -83,10 +84,18 @@ class GardensController < ApplicationController
|
||||
def destroy
|
||||
@garden = Garden.find(params[:id])
|
||||
@garden.destroy
|
||||
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.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def garden_params
|
||||
params.require(:garden).permit(:name, :slug, :owner_id, :description, :active,
|
||||
:location, :latitude, :longitude, :area, :area_unit)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
class HarvestsController < ApplicationController
|
||||
|
||||
before_filter :authenticate_member!, :except => [:index, :show]
|
||||
load_and_authorize_resource
|
||||
|
||||
|
||||
# GET /harvests
|
||||
# GET /harvests.json
|
||||
@@ -61,7 +62,7 @@ class HarvestsController < ApplicationController
|
||||
def create
|
||||
params[:harvest][:owner_id] = current_member.id
|
||||
params[:harvested_at] = parse_date(params[:harvested_at])
|
||||
@harvest = Harvest.new(params[:harvest])
|
||||
@harvest = Harvest.new(harvest_params)
|
||||
|
||||
respond_to do |format|
|
||||
if @harvest.save
|
||||
@@ -80,7 +81,7 @@ class HarvestsController < ApplicationController
|
||||
@harvest = Harvest.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
if @harvest.update_attributes(params[:harvest])
|
||||
if @harvest.update(harvest_params)
|
||||
format.html { redirect_to @harvest, notice: 'Harvest was successfully updated.' }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
@@ -101,4 +102,11 @@ class HarvestsController < ApplicationController
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def harvest_params
|
||||
params.require(:harvest).permit(:crop_id, :harvested_at, :description, :owner_id,
|
||||
:quantity, :unit, :weight_quantity, :weight_unit, :plant_part_id, :slug)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
class MembersController < ApplicationController
|
||||
load_and_authorize_resource
|
||||
|
||||
cache_sweeper :member_sweeper
|
||||
|
||||
skip_authorize_resource :only => :nearby
|
||||
|
||||
after_action :expire_cache_fragments, :only => :create
|
||||
|
||||
def index
|
||||
@members = Member.confirmed.paginate(:page => params[:page])
|
||||
|
||||
@@ -23,7 +23,7 @@ class MembersController < ApplicationController
|
||||
# it requires a garden to be passed in @garden.
|
||||
# The new garden is not persisted unless Garden#save is called.
|
||||
@garden = Garden.new
|
||||
|
||||
|
||||
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]) }
|
||||
@@ -34,4 +34,20 @@ class MembersController < ApplicationController
|
||||
end
|
||||
end
|
||||
|
||||
def view_follows
|
||||
@member = Member.confirmed.find(params[:login_name])
|
||||
@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])
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def expire_cache_fragments
|
||||
expire_fragment("homepage_stats")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
class NotificationsController < ApplicationController
|
||||
include NotificationsHelper
|
||||
before_filter :authenticate_member!
|
||||
load_and_authorize_resource
|
||||
|
||||
# GET /notifications
|
||||
def index
|
||||
@notifications = Notification.find_all_by_recipient_id(current_member)
|
||||
@notifications = Notification.where(recipient_id: current_member)
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
@@ -47,7 +49,7 @@ class NotificationsController < ApplicationController
|
||||
# POST /notifications
|
||||
def create
|
||||
params[:notification][:sender_id] = current_member.id
|
||||
@notification = Notification.new(params[:notification])
|
||||
@notification = Notification.new(notification_params)
|
||||
@recipient = Member.find_by_id(params[:notification][:recipient_id])
|
||||
|
||||
respond_to do |format|
|
||||
@@ -58,4 +60,10 @@ class NotificationsController < ApplicationController
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def notification_params
|
||||
params.require(:notification).permit(:sender_id, :recipient_id, :subject, :body, :post_id, :read)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
class OrderItemsController < ApplicationController
|
||||
before_filter :authenticate_member!
|
||||
load_and_authorize_resource
|
||||
|
||||
# POST /order_items
|
||||
@@ -6,7 +7,7 @@ class OrderItemsController < ApplicationController
|
||||
if params[:order_item][:price]
|
||||
params[:order_item][:price] = params[:order_item][:price].to_f * 100 # convert to cents
|
||||
end
|
||||
@order_item = OrderItem.new(params[:order_item])
|
||||
@order_item = OrderItem.new(order_item_params)
|
||||
@order_item.order = current_member.current_order || Order.create(:member_id => current_member.id)
|
||||
|
||||
respond_to do |format|
|
||||
@@ -19,4 +20,10 @@ class OrderItemsController < ApplicationController
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def order_item_params
|
||||
params.require(:order_item).permit(:order_id, :price, :product_id, :quantity)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
class OrdersController < ApplicationController
|
||||
before_filter :authenticate_member!
|
||||
load_and_authorize_resource
|
||||
|
||||
# GET /orders
|
||||
def index
|
||||
@orders = Order.find_all_by_member_id(current_member.id)
|
||||
@orders = Order.where(member_id: current_member.id)
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
class PhotosController < ApplicationController
|
||||
before_filter :authenticate_member!, :except => [:index, :show]
|
||||
load_and_authorize_resource
|
||||
|
||||
cache_sweeper :photo_sweeper
|
||||
|
||||
# GET /photos
|
||||
# GET /photos.json
|
||||
def index
|
||||
@@ -60,7 +59,7 @@ class PhotosController < ApplicationController
|
||||
# POST /photos.json
|
||||
def create
|
||||
@photo = Photo.find_by_flickr_photo_id(params[:photo][:flickr_photo_id]) ||
|
||||
Photo.new(params[:photo])
|
||||
Photo.new(photo_params)
|
||||
@photo.owner_id = current_member.id
|
||||
@photo.set_flickr_metadata
|
||||
|
||||
@@ -110,7 +109,7 @@ class PhotosController < ApplicationController
|
||||
@photo = Photo.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
if @photo.update_attributes(params[:photo])
|
||||
if @photo.update(photo_params)
|
||||
format.html { redirect_to @photo, notice: 'Photo was successfully updated.' }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
@@ -131,4 +130,11 @@ class PhotosController < ApplicationController
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def photo_params
|
||||
params.require(:photo).permit(:flickr_photo_id, :owner_id, :title, :license_name,
|
||||
:license_url, :thumbnail_url, :fullsize_url, :link_url)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -42,7 +42,7 @@ class PlantPartsController < ApplicationController
|
||||
# POST /plant_parts
|
||||
# POST /plant_parts.json
|
||||
def create
|
||||
@plant_part = PlantPart.new(params[:plant_part])
|
||||
@plant_part = PlantPart.new(plant_part_params)
|
||||
|
||||
respond_to do |format|
|
||||
if @plant_part.save
|
||||
@@ -61,7 +61,7 @@ class PlantPartsController < ApplicationController
|
||||
@plant_part = PlantPart.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
if @plant_part.update_attributes(params[:plant_part])
|
||||
if @plant_part.update(plant_part_params)
|
||||
format.html { redirect_to @plant_part, notice: 'Plant part was successfully updated.' }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
@@ -82,4 +82,10 @@ class PlantPartsController < ApplicationController
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def plant_part_params
|
||||
params.require(:plant_part).permit(:name, :slug)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
class PlantingsController < ApplicationController
|
||||
before_filter :authenticate_member!, :except => [:index, :show]
|
||||
load_and_authorize_resource
|
||||
|
||||
cache_sweeper :planting_sweeper
|
||||
|
||||
# GET /plantings
|
||||
# GET /plantings.json
|
||||
def index
|
||||
@@ -31,7 +30,7 @@ class PlantingsController < ApplicationController
|
||||
# GET /plantings/1
|
||||
# GET /plantings/1.json
|
||||
def show
|
||||
@planting = Planting.includes(:owner, :crop, :garden, :photos).find(params[:id])
|
||||
@planting = Planting.includes(:owner, :crop, :garden, :photos).friendly.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
format.html # show.html.erb
|
||||
@@ -66,14 +65,15 @@ class PlantingsController < ApplicationController
|
||||
# POST /plantings
|
||||
# POST /plantings.json
|
||||
def create
|
||||
params[:planting][:owner_id] = current_member.id
|
||||
params[:planted_at] = parse_date(params[:planted_at])
|
||||
@planting = Planting.new(params[:planting])
|
||||
@planting = Planting.new(planting_params)
|
||||
@planting.owner = current_member
|
||||
|
||||
respond_to do |format|
|
||||
if @planting.save
|
||||
format.html { redirect_to @planting, notice: 'Planting was successfully created.' }
|
||||
format.json { render json: @planting, status: :created, location: @planting }
|
||||
expire_fragment("homepage_stats")
|
||||
else
|
||||
format.html { render action: "new" }
|
||||
format.json { render json: @planting.errors, status: :unprocessable_entity }
|
||||
@@ -88,7 +88,7 @@ class PlantingsController < ApplicationController
|
||||
params[:planted_at] = parse_date(params[:planted_at])
|
||||
|
||||
respond_to do |format|
|
||||
if @planting.update_attributes(params[:planting])
|
||||
if @planting.update(planting_params)
|
||||
format.html { redirect_to @planting, notice: 'Planting was successfully updated.' }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
@@ -104,10 +104,19 @@ class PlantingsController < ApplicationController
|
||||
@planting = Planting.find(params[:id])
|
||||
@garden = @planting.garden
|
||||
@planting.destroy
|
||||
expire_fragment("homepage_stats")
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to @garden }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def planting_params
|
||||
params.require(:planting).permit(:crop_id, :description, :garden_id, :planted_at,
|
||||
:quantity, :sunniness, :planted_from, :owner_id, :finished,
|
||||
:finished_at)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
class PostsController < ApplicationController
|
||||
before_filter :authenticate_member!, :except => [:index, :show]
|
||||
load_and_authorize_resource
|
||||
|
||||
cache_sweeper :post_sweeper
|
||||
|
||||
# GET /posts
|
||||
# GET /posts.json
|
||||
|
||||
@@ -57,7 +56,7 @@ class PostsController < ApplicationController
|
||||
# POST /posts.json
|
||||
def create
|
||||
params[:post][:author_id] = current_member.id
|
||||
@post = Post.new(params[:post])
|
||||
@post = Post.new(post_params)
|
||||
|
||||
respond_to do |format|
|
||||
if @post.save
|
||||
@@ -76,7 +75,7 @@ class PostsController < ApplicationController
|
||||
@post = Post.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
if @post.update_attributes(params[:post])
|
||||
if @post.update(post_params)
|
||||
format.html { redirect_to @post, notice: 'Post was successfully updated.' }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
@@ -97,4 +96,10 @@ class PostsController < ApplicationController
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def post_params
|
||||
params.require(:post).permit(:body, :subject, :author_id, :forum_id)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
class ProductsController < ApplicationController
|
||||
before_filter :authenticate_member!
|
||||
load_and_authorize_resource
|
||||
|
||||
# GET /products
|
||||
def index
|
||||
@products = Product.all
|
||||
@@ -34,7 +36,7 @@ class ProductsController < ApplicationController
|
||||
|
||||
# POST /products
|
||||
def create
|
||||
@product = Product.new(params[:product])
|
||||
@product = Product.new(product_params)
|
||||
|
||||
respond_to do |format|
|
||||
if @product.save
|
||||
@@ -50,7 +52,7 @@ class ProductsController < ApplicationController
|
||||
@product = Product.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
if @product.update_attributes(params[:product])
|
||||
if @product.update(product_params)
|
||||
format.html { redirect_to @product, notice: 'Product was successfully updated.' }
|
||||
else
|
||||
format.html { render action: "edit" }
|
||||
@@ -67,4 +69,11 @@ class ProductsController < ApplicationController
|
||||
format.html { redirect_to products_url }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def product_params
|
||||
params.require(:product).permit(:description, :min_price, :recommended_price, :name,
|
||||
:account_type_id, :paid_months)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
class RegistrationsController < Devise::RegistrationsController
|
||||
|
||||
cache_sweeper :member_sweeper
|
||||
|
||||
def edit
|
||||
@twitter_auth = current_member.auth('twitter')
|
||||
@flickr_auth = current_member.auth('flickr')
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
class RolesController < ApplicationController
|
||||
before_filter :authenticate_member!
|
||||
load_and_authorize_resource
|
||||
|
||||
# GET /roles
|
||||
def index
|
||||
@roles = Role.all
|
||||
@@ -34,7 +36,7 @@ class RolesController < ApplicationController
|
||||
|
||||
# POST /roles
|
||||
def create
|
||||
@role = Role.new(params[:role])
|
||||
@role = Role.new(role_params)
|
||||
|
||||
respond_to do |format|
|
||||
if @role.save
|
||||
@@ -50,7 +52,7 @@ class RolesController < ApplicationController
|
||||
@role = Role.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
if @role.update_attributes(params[:role])
|
||||
if @role.update(role_params)
|
||||
format.html { redirect_to @role, notice: 'Role was successfully updated.' }
|
||||
else
|
||||
format.html { render action: "edit" }
|
||||
@@ -67,4 +69,10 @@ class RolesController < ApplicationController
|
||||
format.html { redirect_to roles_url }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def role_params
|
||||
params.require(:role).permit(:description, :name, :members, :slug)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
class ScientificNamesController < ApplicationController
|
||||
before_filter :authenticate_member!, :except => [:index, :show]
|
||||
load_and_authorize_resource
|
||||
|
||||
cache_sweeper :scientific_name_sweeper
|
||||
|
||||
# GET /scientific_names
|
||||
# GET /scientific_names.json
|
||||
def index
|
||||
@@ -46,7 +45,7 @@ class ScientificNamesController < ApplicationController
|
||||
# POST /scientific_names.json
|
||||
def create
|
||||
params[:scientific_name][:creator_id] = current_member.id
|
||||
@scientific_name = ScientificName.new(params[:scientific_name])
|
||||
@scientific_name = ScientificName.new(scientific_name_params)
|
||||
|
||||
respond_to do |format|
|
||||
if @scientific_name.save
|
||||
@@ -65,7 +64,7 @@ class ScientificNamesController < ApplicationController
|
||||
@scientific_name = ScientificName.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
if @scientific_name.update_attributes(params[:scientific_name])
|
||||
if @scientific_name.update(scientific_name_params)
|
||||
format.html { redirect_to @scientific_name.crop, notice: 'Scientific name was successfully updated.' }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
@@ -89,4 +88,10 @@ class ScientificNamesController < ApplicationController
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def scientific_name_params
|
||||
params.require(:scientific_name).permit(:crop_id, :scientific_name, :creator_id)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
class SeedsController < ApplicationController
|
||||
before_filter :authenticate_member!, :except => [:index, :show]
|
||||
load_and_authorize_resource
|
||||
|
||||
cache_sweeper :seed_sweeper
|
||||
|
||||
# GET /seeds
|
||||
# GET /seeds.json
|
||||
def index
|
||||
@@ -67,7 +66,7 @@ class SeedsController < ApplicationController
|
||||
# POST /seeds.json
|
||||
def create
|
||||
params[:seed][:owner_id] = current_member.id
|
||||
@seed = Seed.new(params[:seed])
|
||||
@seed = Seed.new(seed_params)
|
||||
|
||||
respond_to do |format|
|
||||
if @seed.save
|
||||
@@ -86,7 +85,7 @@ class SeedsController < ApplicationController
|
||||
@seed = Seed.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
if @seed.update_attributes(params[:seed])
|
||||
if @seed.update(seed_params)
|
||||
format.html { redirect_to @seed, notice: 'Seed was successfully updated.' }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
@@ -107,4 +106,11 @@ class SeedsController < ApplicationController
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def seed_params
|
||||
params.require(:seed).permit(:owner_id, :crop_id, :description, :quantity, :plant_before,
|
||||
:tradable_to, :slug)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -24,5 +24,12 @@ module ApplicationHelper
|
||||
:target => "_blank"
|
||||
end
|
||||
|
||||
# Produces a cache key for uniquely identifying cached fragments.
|
||||
def cache_key_for(klass, identifier="all")
|
||||
count = klass.count
|
||||
max_updated_at = klass.maximum(:updated_at).try(:utc).try(:to_s, :number)
|
||||
"#{klass.name.downcase.pluralize}/#{identifier}-#{count}-#{max_updated_at}"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@ class Notifier < ActionMailer::Base
|
||||
def planting_reminder(member)
|
||||
@member = member
|
||||
|
||||
@plantings = @member.plantings.reorder.last(5)
|
||||
@harvests = @member.harvests.reorder.last(5)
|
||||
@plantings = @member.plantings.first(5)
|
||||
@harvests = @member.harvests.first(5)
|
||||
|
||||
if @member.send_planting_reminder
|
||||
mail(:to => @member.email,
|
||||
|
||||
@@ -6,6 +6,8 @@ class Ability
|
||||
|
||||
# everyone can do these things, even non-logged in
|
||||
can :read, :all
|
||||
can :view_follows, Member
|
||||
can :view_followers, Member
|
||||
|
||||
# except these, which don't make sense if you're not logged in
|
||||
cannot :read, Notification
|
||||
@@ -91,6 +93,13 @@ class Ability
|
||||
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
|
||||
|
||||
can :destroy, Follow
|
||||
cannot :destroy, Follow, :followed_id => member.id # can't unfollow yourself
|
||||
|
||||
if member.has_role? :admin
|
||||
|
||||
can :read, :all
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
class Account < ActiveRecord::Base
|
||||
attr_accessible :account_type_id, :member_id, :paid_until
|
||||
belongs_to :member
|
||||
belongs_to :account_type
|
||||
|
||||
@@ -9,7 +8,7 @@ class Account < ActiveRecord::Base
|
||||
|
||||
before_create do |account|
|
||||
unless account.account_type
|
||||
account.account_type = AccountType.find_or_create_by_name(
|
||||
account.account_type = AccountType.find_or_create_by(name:
|
||||
Growstuff::Application.config.default_account_type
|
||||
)
|
||||
end
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
class AccountType < ActiveRecord::Base
|
||||
attr_accessible :is_paid, :is_permanent_paid, :name
|
||||
has_many :products
|
||||
|
||||
def to_s
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
class AlternateName < ActiveRecord::Base
|
||||
attr_accessible :crop_id, :name, :creator_id
|
||||
belongs_to :crop
|
||||
belongs_to :creator, :class_name => 'Member'
|
||||
end
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
class Authentication < ActiveRecord::Base
|
||||
belongs_to :member
|
||||
attr_accessible :provider, :uid, :token, :secret, :name
|
||||
end
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
class Comment < ActiveRecord::Base
|
||||
attr_accessible :author_id, :body, :post_id
|
||||
belongs_to :author, :class_name => 'Member'
|
||||
belongs_to :post
|
||||
|
||||
default_scope order("created_at DESC")
|
||||
scope :post_order, reorder("created_at ASC") # for display on post page
|
||||
default_scope { order("created_at DESC") }
|
||||
scope :post_order, -> { reorder("created_at ASC") } # for display on post page
|
||||
|
||||
after_create do
|
||||
recipient = self.post.author.id
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
class CommentSweeper < ActionController::Caching::Sweeper
|
||||
observe Comment
|
||||
|
||||
def after_create(comment)
|
||||
expire_fragment('recent_posts')
|
||||
end
|
||||
|
||||
def after_update(comment)
|
||||
end
|
||||
|
||||
def after_destroy(comment)
|
||||
expire_fragment('recent_posts')
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,7 +1,6 @@
|
||||
class Crop < ActiveRecord::Base
|
||||
extend FriendlyId
|
||||
friendly_id :name, use: :slugged
|
||||
attr_accessible :en_wikipedia_url, :name, :parent_id, :creator_id, :scientific_names_attributes
|
||||
friendly_id :name, use: [:slugged, :finders]
|
||||
|
||||
has_many :scientific_names
|
||||
accepts_nested_attributes_for :scientific_names,
|
||||
@@ -13,7 +12,7 @@ class Crop < ActiveRecord::Base
|
||||
has_many :photos, :through => :plantings
|
||||
has_many :seeds
|
||||
has_many :harvests
|
||||
has_many :plant_parts, :through => :harvests, :uniq => :true
|
||||
has_many :plant_parts, -> { uniq }, :through => :harvests
|
||||
belongs_to :creator, :class_name => 'Member'
|
||||
|
||||
belongs_to :parent, :class_name => 'Crop'
|
||||
@@ -21,16 +20,15 @@ class Crop < ActiveRecord::Base
|
||||
has_and_belongs_to_many :posts
|
||||
before_destroy {|crop| crop.posts.clear}
|
||||
|
||||
|
||||
default_scope order("lower(name) asc")
|
||||
scope :recent, reorder("created_at desc")
|
||||
scope :toplevel, where(:parent_id => nil)
|
||||
scope :popular, reorder("plantings_count desc, lower(name) asc")
|
||||
scope :randomized, reorder('random()') # ok on sqlite and psql, but not on mysql
|
||||
default_scope { order("lower(name) asc") }
|
||||
scope :recent, -> { reorder("created_at desc") }
|
||||
scope :toplevel, -> { where(:parent_id => nil) }
|
||||
scope :popular, -> { reorder("plantings_count desc, lower(name) asc") }
|
||||
scope :randomized, -> { reorder('random()') } # ok on sqlite and psql, but not on mysql
|
||||
|
||||
validates :en_wikipedia_url,
|
||||
:format => {
|
||||
:with => /^https?:\/\/en\.wikipedia\.org\/wiki/,
|
||||
:with => /\Ahttps?:\/\/en\.wikipedia\.org\/wiki/,
|
||||
:message => 'is not a valid English Wikipedia URL'
|
||||
}
|
||||
|
||||
@@ -122,17 +120,17 @@ class Crop < ActiveRecord::Base
|
||||
# used by db/seeds.rb and rake growstuff:import_crops
|
||||
# CSV fields:
|
||||
# - name (required)
|
||||
# - scientific name (optional, can be picked up from parent if it has one)
|
||||
# - en_wikipedia_url (required)
|
||||
# - parent (name, optional)
|
||||
# - scientific name (optional, can be picked up from parent if it has one)
|
||||
|
||||
def Crop.create_from_csv(row)
|
||||
name,scientific_name,en_wikipedia_url,parent = row
|
||||
name,en_wikipedia_url,parent,scientific_names,alternate_names = row
|
||||
|
||||
cropbot = Member.find_by_login_name('cropbot')
|
||||
raise "cropbot account not found: run rake db:seed" unless cropbot
|
||||
|
||||
crop = Crop.find_or_create_by_name(name)
|
||||
crop = Crop.find_or_create_by(name: name)
|
||||
crop.update_attributes(
|
||||
:en_wikipedia_url => en_wikipedia_url,
|
||||
:creator_id => cropbot.id
|
||||
@@ -147,34 +145,59 @@ class Crop < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
crop.add_scientific_name_from_csv(scientific_name)
|
||||
crop.add_scientific_names_from_csv(scientific_names)
|
||||
crop.add_alternate_names_from_csv(alternate_names)
|
||||
|
||||
end
|
||||
|
||||
def add_scientific_name_from_csv(scientific_name)
|
||||
name_to_add = nil
|
||||
if ! scientific_name.blank? # i.e. we actually passed one in, which isn't a given
|
||||
name_to_add = scientific_name
|
||||
elsif parent && parent.default_scientific_name
|
||||
name_to_add = parent.default_scientific_name
|
||||
def add_scientific_names_from_csv(scientific_names)
|
||||
names_to_add = []
|
||||
if ! scientific_names.blank? # i.e. we actually passed something in, which isn't a given
|
||||
names_to_add = scientific_names.split(%r{,\s*})
|
||||
elsif parent && parent.scientific_names.size > 0 # pick up from parent
|
||||
names_to_add = parent.scientific_names.map{|s| s.scientific_name}
|
||||
else
|
||||
logger.warn("Warning: no scientific name (not even on parent crop) for #{self}")
|
||||
end
|
||||
|
||||
if name_to_add
|
||||
if scientific_names.exists?(:scientific_name => name_to_add)
|
||||
logger.warn("Warning: skipping duplicate scientific name #{name_to_add} for #{self}")
|
||||
else
|
||||
cropbot = Member.find_by_login_name('cropbot')
|
||||
raise "cropbot account not found: run rake db:seed" unless cropbot
|
||||
if names_to_add.size > 0
|
||||
cropbot = Member.find_by_login_name('cropbot')
|
||||
raise "cropbot account not found: run rake db:seed" unless cropbot
|
||||
|
||||
scientific_names.create(
|
||||
:scientific_name => name_to_add,
|
||||
:creator_id => cropbot.id
|
||||
)
|
||||
names_to_add.each do |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
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def add_alternate_names_from_csv(alternate_names)
|
||||
names_to_add = []
|
||||
if ! alternate_names.blank? # i.e. we actually passed something in, which isn't a given
|
||||
cropbot = Member.find_by_login_name('cropbot')
|
||||
raise "cropbot account not found: run rake db:seed" unless cropbot
|
||||
|
||||
names_to_add = alternate_names.split(%r{,\s*})
|
||||
|
||||
names_to_add.each do |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
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
# Crop.search(string)
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
class CropSweeper < ActionController::Caching::Sweeper
|
||||
observe Crop
|
||||
|
||||
def after_create(crop)
|
||||
expire_fragment('homepage_stats')
|
||||
expire_fragment('recent_crops')
|
||||
expire_fragment('full_crop_hierarchy')
|
||||
end
|
||||
|
||||
def after_update(crop)
|
||||
expire_fragment("crop_image_#{crop.id}")
|
||||
end
|
||||
|
||||
def after_destroy(crop)
|
||||
expire_fragment('homepage_stats')
|
||||
expire_fragment('recent_crops')
|
||||
expire_fragment('full_crop_hierarchy')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
16
app/models/follow.rb
Normal file
16
app/models/follow.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
class Follow < ActiveRecord::Base
|
||||
belongs_to :follower, class_name: "Member"
|
||||
belongs_to :followed, class_name: "Member"
|
||||
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"]}. "
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
@@ -1,7 +1,7 @@
|
||||
class Forum < ActiveRecord::Base
|
||||
extend FriendlyId
|
||||
friendly_id :name, use: :slugged
|
||||
attr_accessible :description, :name, :owner_id, :slug
|
||||
friendly_id :name, use: [:slugged, :finders]
|
||||
|
||||
has_many :posts
|
||||
belongs_to :owner, :class_name => "Member"
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
class ForumSweeper < ActionController::Caching::Sweeper
|
||||
observe Forum
|
||||
|
||||
def after_create(forum)
|
||||
expire_fragment('homepage_forums')
|
||||
end
|
||||
|
||||
def after_update(forum)
|
||||
expire_fragment('homepage_forums')
|
||||
end
|
||||
|
||||
def after_destroy(forum)
|
||||
expire_fragment('homepage_forums')
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,13 +1,10 @@
|
||||
class Garden < ActiveRecord::Base
|
||||
include Geocodable
|
||||
extend FriendlyId
|
||||
friendly_id :garden_slug, use: :slugged
|
||||
|
||||
attr_accessible :name, :slug, :owner_id, :description, :active,
|
||||
:location, :latitude, :longitude, :area, :area_unit
|
||||
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 :plantings, -> { order(created_at: :desc) }, :dependent => :destroy
|
||||
has_many :crops, :through => :plantings
|
||||
|
||||
# set up geocoding
|
||||
@@ -16,9 +13,9 @@ class Garden < ActiveRecord::Base
|
||||
after_validation :empty_unwanted_geocodes
|
||||
after_save :mark_inactive_garden_plantings_as_finished
|
||||
|
||||
default_scope order("lower(name) asc")
|
||||
scope :active, where(:active => true)
|
||||
scope :inactive, where(:active => false)
|
||||
default_scope { order("lower(name) asc") }
|
||||
scope :active, -> { where(:active => true) }
|
||||
scope :inactive, -> { where(:active => false) }
|
||||
|
||||
validates :name,
|
||||
:format => {
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
class GardenSweeper < ActionController::Caching::Sweeper
|
||||
observe Garden
|
||||
|
||||
def after_create(garden)
|
||||
expire_fragment('homepage_stats')
|
||||
expire_fragment('interesting_members') if garden.owner.interesting?
|
||||
expire_fragment("member_thumbnail_#{garden.owner.id}")
|
||||
end
|
||||
|
||||
def after_destroy(garden)
|
||||
expire_fragment('homepage_stats')
|
||||
expire_fragment('interesting_members') if garden.owner.interesting?
|
||||
expire_fragment("member_thumbnail_#{garden.owner.id}")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
class Harvest < ActiveRecord::Base
|
||||
include ActionView::Helpers::NumberHelper
|
||||
extend FriendlyId
|
||||
friendly_id :harvest_slug, use: :slugged
|
||||
|
||||
attr_accessible :crop_id, :harvested_at, :description, :owner_id,
|
||||
:quantity, :unit, :weight_quantity, :weight_unit, :plant_part_id, :slug, :si_weight
|
||||
friendly_id :harvest_slug, use: [:slugged, :finders]
|
||||
|
||||
belongs_to :crop
|
||||
belongs_to :owner, :class_name => 'Member'
|
||||
@@ -21,7 +18,7 @@ class Harvest < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
default_scope order('created_at DESC')
|
||||
default_scope { order('created_at DESC') }
|
||||
|
||||
validates :crop, :presence => {:message => "must be present and exist in our database"}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ class Member < ActiveRecord::Base
|
||||
include Geocodable
|
||||
extend FriendlyId
|
||||
|
||||
friendly_id :login_name, use: :slugged
|
||||
friendly_id :login_name, use: [:slugged, :finders]
|
||||
|
||||
has_many :posts, :foreign_key => 'author_id'
|
||||
has_many :comments, :foreign_key => 'author_id'
|
||||
@@ -27,11 +27,18 @@ class Member < ActiveRecord::Base
|
||||
|
||||
has_many :photos
|
||||
|
||||
default_scope order("lower(login_name) asc")
|
||||
scope :confirmed, where('confirmed_at IS NOT NULL')
|
||||
scope :located, where("location <> '' and latitude IS NOT NULL and longitude IS NOT NULL")
|
||||
scope :recently_signed_in, reorder('updated_at DESC')
|
||||
scope :wants_newsletter, where(:newsletter => true)
|
||||
|
||||
default_scope { order("lower(login_name) asc") }
|
||||
scope :confirmed, -> { where('confirmed_at IS NOT NULL') }
|
||||
scope :located, -> { where("location <> '' and latitude IS NOT NULL and longitude IS NOT NULL") }
|
||||
scope :recently_signed_in, -> { reorder('updated_at DESC') }
|
||||
scope :wants_newsletter, -> { where(:newsletter => true) }
|
||||
|
||||
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
|
||||
|
||||
# Include default devise modules. Others available are:
|
||||
# :token_authenticatable, :confirmable,
|
||||
@@ -40,16 +47,6 @@ class Member < ActiveRecord::Base
|
||||
:recoverable, :rememberable, :trackable, :validatable,
|
||||
:confirmable, :lockable, :timeoutable
|
||||
|
||||
# Setup accessible (or protected) attributes for your model
|
||||
attr_accessible :login_name, :email, :password, :password_confirmation,
|
||||
:remember_me, :login,
|
||||
# terms of service
|
||||
:tos_agreement,
|
||||
# profile stuff
|
||||
:bio, :location, :latitude, :longitude,
|
||||
# email settings
|
||||
:show_email, :newsletter, :send_notification_email, :send_planting_reminder
|
||||
|
||||
# set up geocoding
|
||||
geocoded_by :location
|
||||
after_validation :geocode
|
||||
@@ -74,7 +71,7 @@ class Member < ActiveRecord::Base
|
||||
:message => "name is reserved"
|
||||
},
|
||||
:format => {
|
||||
:with => /^\w+$/,
|
||||
:with => /\A\w+\z/,
|
||||
:message => "may only include letters, numbers, or underscores"
|
||||
},
|
||||
:uniqueness => {
|
||||
@@ -87,7 +84,7 @@ class Member < ActiveRecord::Base
|
||||
# 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 => member.id) }
|
||||
after_create {|member| Account.find_or_create_by(:member_id => member.id) }
|
||||
|
||||
after_save :update_newsletter_subscription
|
||||
|
||||
@@ -237,17 +234,19 @@ class Member < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
def newsletter_subscribe
|
||||
def newsletter_subscribe(testing=false)
|
||||
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 alredy confirmed their email with us
|
||||
:double_optin => false # they already confirmed their email with us
|
||||
})
|
||||
end
|
||||
|
||||
def newsletter_unsubscribe
|
||||
def newsletter_unsubscribe(testing=false)
|
||||
return true if (Rails.env.test? && !testing)
|
||||
gb = Gibbon::API.new
|
||||
res = gb.lists.unsubscribe({
|
||||
:id => ENV['GROWSTUFF_MAILCHIMP_NEWSLETTER_ID'],
|
||||
@@ -255,4 +254,12 @@ class Member < ActiveRecord::Base
|
||||
})
|
||||
end
|
||||
|
||||
def already_following?(member)
|
||||
self.follows.exists?(:followed_id => member.id)
|
||||
end
|
||||
|
||||
def get_follow(member)
|
||||
self.follows.where(:followed_id => member.id).first if already_following?(member)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
class MemberSweeper < ActionController::Caching::Sweeper
|
||||
observe Member
|
||||
|
||||
def after_create(member)
|
||||
expire_fragment('homepage_stats')
|
||||
end
|
||||
|
||||
def after_update(member)
|
||||
expire_fragment('interesting_members') if member.interesting?
|
||||
expire_fragment("interesting_seeds") if member.seeds.tradable.present?
|
||||
expire_fragment("member_thumbnail_#{member.id}")
|
||||
|
||||
if member.plantings.present?
|
||||
member.plantings.each do |p|
|
||||
expire_fragment("plantings_listitem_#{p.id}") if p.interesting?
|
||||
end
|
||||
expire_fragment('interesting_plantings')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
class Notification < ActiveRecord::Base
|
||||
attr_accessible :sender_id, :recipient_id,
|
||||
:subject, :body, :post_id, :read
|
||||
|
||||
belongs_to :sender, :class_name => 'Member'
|
||||
belongs_to :recipient, :class_name => 'Member'
|
||||
belongs_to :post
|
||||
|
||||
default_scope order('created_at DESC')
|
||||
scope :unread, where(:read => false)
|
||||
default_scope { order('created_at DESC') }
|
||||
scope :unread, -> { where(:read => false) }
|
||||
|
||||
before_create :replace_blank_subject
|
||||
after_create :send_email
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
class Order < ActiveRecord::Base
|
||||
attr_accessible :member_id, :completed_at, :referral_code
|
||||
belongs_to :member
|
||||
|
||||
has_many :order_items, :dependent => :destroy
|
||||
|
||||
default_scope order('created_at DESC')
|
||||
default_scope { order('created_at DESC') }
|
||||
|
||||
validates :referral_code, :format => {
|
||||
:with => /\A[a-zA-Z0-9 ]*\z/,
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
class OrderItem < ActiveRecord::Base
|
||||
attr_accessible :order_id, :price, :product_id, :quantity
|
||||
|
||||
belongs_to :order
|
||||
belongs_to :product
|
||||
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
class Photo < ActiveRecord::Base
|
||||
attr_accessible :flickr_photo_id, :owner_id, :title, :license_name,
|
||||
:license_url, :thumbnail_url, :fullsize_url, :link_url
|
||||
belongs_to :owner, :class_name => 'Member'
|
||||
|
||||
has_and_belongs_to_many :plantings
|
||||
@@ -10,7 +8,7 @@ class Photo < ActiveRecord::Base
|
||||
photo.harvests.clear
|
||||
end
|
||||
|
||||
default_scope order("created_at desc")
|
||||
default_scope { order("created_at desc") }
|
||||
|
||||
# remove photos that aren't used by anything
|
||||
def destroy_if_unused
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
class PhotoSweeper < ActionController::Caching::Sweeper
|
||||
observe Photo
|
||||
|
||||
def after_create(photo)
|
||||
expire_fragment('interesting_plantings')
|
||||
end
|
||||
|
||||
def after_destroy(photo)
|
||||
expire_fragment('interesting_plantings')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
class PlantPart < ActiveRecord::Base
|
||||
extend FriendlyId
|
||||
friendly_id :name, :use => :slugged
|
||||
friendly_id :name, :use => [:slugged, :finders]
|
||||
|
||||
has_many :harvests
|
||||
has_many :crops, :through => :harvests, :uniq => true
|
||||
|
||||
attr_accessible :name, :slug
|
||||
has_many :crops, -> { uniq }, :through => :harvests
|
||||
|
||||
def to_s
|
||||
return name
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
class Planting < ActiveRecord::Base
|
||||
extend FriendlyId
|
||||
friendly_id :planting_slug, use: :slugged
|
||||
|
||||
attr_accessible :crop_id, :description, :garden_id, :planted_at,
|
||||
:quantity, :sunniness, :planted_from, :owner_id, :finished,
|
||||
:finished_at
|
||||
friendly_id :planting_slug, use: [:slugged, :finders]
|
||||
|
||||
belongs_to :garden
|
||||
belongs_to :owner, :class_name => 'Member', :counter_cache => true
|
||||
@@ -21,9 +17,9 @@ class Planting < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
default_scope order("created_at desc")
|
||||
scope :finished, where(:finished => true)
|
||||
scope :current, where(:finished => false)
|
||||
default_scope { order("created_at desc") }
|
||||
scope :finished, -> { where(:finished => true) }
|
||||
scope :current, -> { where(:finished => false) }
|
||||
|
||||
delegate :name,
|
||||
:en_wikipedia_url,
|
||||
@@ -32,7 +28,7 @@ class Planting < ActiveRecord::Base
|
||||
:to => :crop,
|
||||
:prefix => true
|
||||
|
||||
default_scope order("created_at desc")
|
||||
default_scope { order("created_at desc") }
|
||||
|
||||
validates :crop_id, :presence => {:message => "must be present and exist in our database"}
|
||||
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
class PlantingSweeper < ActionController::Caching::Sweeper
|
||||
observe Planting
|
||||
|
||||
def after_create(planting)
|
||||
expire_fragment('homepage_stats')
|
||||
expire_fragment("member_thumbnail_#{planting.owner.id}")
|
||||
expire_fragment("interesting_members") if planting.owner.interesting?
|
||||
expire_fragment("crop_image_#{planting.crop.id}")
|
||||
end
|
||||
|
||||
def after_update(planting)
|
||||
expire_fragment("planting_listitem_#{planting.id}")
|
||||
expire_fragment("planting_image_#{planting.id}")
|
||||
expire_fragment("interesting_plantings")
|
||||
end
|
||||
|
||||
def after_destroy(planting)
|
||||
expire_fragment('homepage_stats')
|
||||
expire_fragment("crop_image_#{planting.crop.id}")
|
||||
expire_fragment('interesting_plantings') if planting.interesting?
|
||||
expire_fragment("interesting_members") if planting.owner.interesting?
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
class Post < ActiveRecord::Base
|
||||
extend FriendlyId
|
||||
friendly_id :author_date_subject, use: :slugged
|
||||
attr_accessible :body, :subject, :author_id, :forum_id
|
||||
friendly_id :author_date_subject, use: [:slugged, :finders]
|
||||
belongs_to :author, :class_name => 'Member'
|
||||
belongs_to :forum
|
||||
has_many :comments, :dependent => :destroy
|
||||
@@ -11,7 +10,7 @@ class Post < ActiveRecord::Base
|
||||
# also has_many notifications, but kinda meaningless to get at them
|
||||
# from this direction, so we won't set up an association for now.
|
||||
|
||||
default_scope order("created_at desc")
|
||||
default_scope { order("created_at desc") }
|
||||
|
||||
validates :subject,
|
||||
:format => {
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
class PostSweeper < ActionController::Caching::Sweeper
|
||||
observe Post
|
||||
|
||||
def after_create(post)
|
||||
expire_fragment('recent_posts')
|
||||
end
|
||||
|
||||
def after_update(post)
|
||||
expire_fragment('recent_posts')
|
||||
end
|
||||
|
||||
def after_destroy(post)
|
||||
expire_fragment('recent_posts')
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,7 +1,4 @@
|
||||
class Product < ActiveRecord::Base
|
||||
attr_accessible :description, :min_price, :recommended_price, :name,
|
||||
:account_type_id, :paid_months
|
||||
|
||||
has_and_belongs_to_many :orders
|
||||
belongs_to :account_type
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
class Role < ActiveRecord::Base
|
||||
extend FriendlyId
|
||||
friendly_id :name, use: :slugged
|
||||
attr_accessible :description, :name, :members, :slug
|
||||
friendly_id :name, use: [:slugged, :finders]
|
||||
|
||||
has_and_belongs_to_many :members
|
||||
|
||||
class << self
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
class ScientificName < ActiveRecord::Base
|
||||
attr_accessible :crop_id, :scientific_name, :creator_id
|
||||
belongs_to :crop
|
||||
belongs_to :creator, :class_name => 'Member'
|
||||
end
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
class ScientificNameSweeper < ActionController::Caching::Sweeper
|
||||
observe ScientificName
|
||||
|
||||
def after_create(scientific_name)
|
||||
expire_fragment("crop_image_#{scientific_name.crop.id}")
|
||||
end
|
||||
|
||||
def after_update(scientific_name)
|
||||
expire_fragment("crop_image_#{scientific_name.crop.id}")
|
||||
end
|
||||
|
||||
def after_destroy(scientific_name)
|
||||
expire_fragment("crop_image_#{scientific_name.crop.id}")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
class Seed < ActiveRecord::Base
|
||||
extend FriendlyId
|
||||
friendly_id :seed_slug, use: :slugged
|
||||
|
||||
attr_accessible :owner_id, :crop_id, :description, :quantity, :plant_before,
|
||||
:tradable_to, :slug
|
||||
friendly_id :seed_slug, use: [:slugged, :finders]
|
||||
|
||||
belongs_to :crop
|
||||
belongs_to :owner, :class_name => 'Member', :foreign_key => 'owner_id'
|
||||
|
||||
default_scope order("created_at desc")
|
||||
default_scope { order("created_at desc") }
|
||||
|
||||
validates :crop, :presence => {:message => "must be present and exist in our database"}
|
||||
validates :quantity,
|
||||
:numericality => { :only_integer => true },
|
||||
:allow_nil => true
|
||||
|
||||
scope :tradable, where("tradable_to != 'nowhere'")
|
||||
scope :tradable, -> { where("tradable_to != 'nowhere'") }
|
||||
|
||||
TRADABLE_TO_VALUES = %w(nowhere locally nationally internationally)
|
||||
validates :tradable_to, :inclusion => { :in => TRADABLE_TO_VALUES,
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
class SeedSweeper < ActionController::Caching::Sweeper
|
||||
observe Seed
|
||||
|
||||
def after_create(seed)
|
||||
if seed.tradable? && seed.interesting?
|
||||
expire_fragment('interesting_seeds')
|
||||
end
|
||||
expire_fragment('interesting_members') if seed.owner.interesting?
|
||||
expire_fragment("member_thumbnail_#{seed.owner.id}")
|
||||
end
|
||||
|
||||
def after_update(seed)
|
||||
expire_fragment('interesting_seeds')
|
||||
end
|
||||
|
||||
def after_destroy(seed)
|
||||
if seed.tradable? && seed.interesting?
|
||||
expire_fragment('interesting_seeds')
|
||||
end
|
||||
expire_fragment('interesting_members') if seed.owner.interesting?
|
||||
expire_fragment("member_thumbnail_#{seed.owner.id}")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
- content_for :title, "Linked accounts on other sites"
|
||||
|
||||
- if @authentications
|
||||
- unless @authentications.empty?
|
||||
.authentications
|
||||
- @authentications.each do |authentication|
|
||||
%a{ :href => "http://twitter.com/#{authentication.name}" }
|
||||
.authentication
|
||||
= image_tag "#{authentication.provider}_64.png", :size => "64x64"
|
||||
.provider
|
||||
= authentication.provider.titleize
|
||||
.name
|
||||
= authentication.name
|
||||
= link_to "X", authentication, :confirm => "Are you sure you want to remove this authentication?", :method => :delete, :class => "remove"
|
||||
.clear
|
||||
%p
|
||||
%strong Link another external account:
|
||||
- else
|
||||
%p
|
||||
%strong Link to an external account:
|
||||
|
||||
= link_to image_tag("twitter_64.png", :size => "64x64"), "/auth/twitter", :class => "auth_provider"
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
%rss{:version => 2.0}
|
||||
%channel
|
||||
%title #{ENV['GROWSTUFF_SITE_NAME']} - Recent comments on all posts
|
||||
%title Recent comments on all posts (#{ENV['GROWSTUFF_SITE_NAME']})
|
||||
%link= comments_url
|
||||
- @comments.each do |comment|
|
||||
%item
|
||||
|
||||
16
app/views/crops/_alternate_names.html.haml
Normal file
16
app/views/crops/_alternate_names.html.haml
Normal file
@@ -0,0 +1,16 @@
|
||||
.alternate_names
|
||||
%h4 Alternate names
|
||||
- if crop.alternate_names.empty?
|
||||
%p None known.
|
||||
- else
|
||||
%ul
|
||||
- crop.alternate_names.each do |an|
|
||||
%li
|
||||
= an.name
|
||||
- if can? :edit, an
|
||||
= link_to 'Edit', edit_alternate_name_path(an), { :class => 'btn btn-default btn-xs' }
|
||||
- if can? :destroy, an
|
||||
= link_to 'Delete', an, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'
|
||||
%p
|
||||
- if can? :edit, crop
|
||||
= link_to 'Add', new_alternate_name_path( :crop_id => crop.id ), { :class => 'btn btn-default btn-xs' }
|
||||
@@ -1,4 +1,4 @@
|
||||
%h4 Find seeds
|
||||
%h4 Find #{ crop.name } seeds
|
||||
- if crop.seeds.empty?
|
||||
%p
|
||||
There are no seeds available to trade.
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
- if ! crop.harvests.empty?
|
||||
%p
|
||||
%strong Grown for:
|
||||
%p
|
||||
%strong Grown for:
|
||||
- if crop.harvests.empty?
|
||||
not known.
|
||||
- else
|
||||
- popular_plant_parts = crop.popular_plant_parts.sort_by {|s, freq| freq }.reverse
|
||||
!= popular_plant_parts.map {|p, freq| link_to(p, p) + " (#{freq})" }.join(", ")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
%h4 Harvests
|
||||
%h4 #{ crop.name.capitalize } harvests
|
||||
- if crop.harvests.empty?
|
||||
%p
|
||||
Nobody has harvested this crop yet.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
- cache "crop_image_#{crop.id}" do
|
||||
- cache crop do
|
||||
= link_to |
|
||||
image_tag( |
|
||||
crop.default_photo ? crop.default_photo.thumbnail_url : 'placeholder_150.png', |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.well
|
||||
.row
|
||||
.col-md-4
|
||||
= link_to image_tag((crop.default_photo ? crop.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => '', :class => 'img-rounded crop-image'), crop
|
||||
= link_to image_tag((crop.default_photo ? crop.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => '', :class => 'img crop-image'), crop
|
||||
.col-md-8
|
||||
%h3{:style => 'padding-top: 0px; margin-top: 0px'}
|
||||
= link_to crop, crop
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
- if crop.planted_from.length > 0
|
||||
%p
|
||||
%strong Plant from:
|
||||
%p
|
||||
%strong Plant from:
|
||||
- if crop.planted_from.empty?
|
||||
not known.
|
||||
- else
|
||||
- planted_from = crop.planted_from.sort_by {|s, freq| freq }.reverse
|
||||
= planted_from.map {|s, freq| "#{s} (#{freq})" }.join(", ")
|
||||
- if crop.sunniness.length > 0
|
||||
%p
|
||||
%strong Plant in:
|
||||
|
||||
%p
|
||||
%strong Plant in:
|
||||
- if crop.sunniness.empty?
|
||||
not known.
|
||||
- else
|
||||
- sunniness = crop.sunniness.sort_by {|s, freq| freq }.reverse
|
||||
= sunniness.map {|s, freq| "#{s} (#{freq})" }.join(", ")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
%h4 Plantings
|
||||
%h4 See who's planted #{ crop.name.pluralize }
|
||||
- if crop.plantings.empty?
|
||||
%p
|
||||
Nobody has planted this crop yet.
|
||||
|
||||
16
app/views/crops/_scientific_names.html.haml
Normal file
16
app/views/crops/_scientific_names.html.haml
Normal file
@@ -0,0 +1,16 @@
|
||||
.scientific_names
|
||||
%h4 Scientific names
|
||||
- if crop.scientific_names.empty?
|
||||
%p None known.
|
||||
- else
|
||||
%ul
|
||||
- crop.scientific_names.each do |sn|
|
||||
%li
|
||||
= sn.scientific_name
|
||||
- if can? :edit, sn
|
||||
= link_to 'Edit', edit_scientific_name_path(sn), { :class => 'btn btn-default btn-xs' }
|
||||
- if can? :destroy, sn
|
||||
= link_to 'Delete', sn, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'
|
||||
%p
|
||||
- if can? :edit, crop
|
||||
= link_to 'Add', new_scientific_name_path( :crop_id => crop.id ), { :class => 'btn btn-default btn-xs' }
|
||||
@@ -1,14 +1,13 @@
|
||||
.thumbnail(style='height: 220px')
|
||||
- if crop
|
||||
= link_to image_tag((crop.default_photo ? crop.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => crop.name, :class => 'img-rounded'), crop
|
||||
%p
|
||||
= link_to crop.name, crop
|
||||
- if crop.scientific_names.count > 0
|
||||
%br/
|
||||
%i
|
||||
%small
|
||||
.thumbnail
|
||||
.crop-thumbnail
|
||||
- if crop
|
||||
= link_to image_tag((crop.default_photo ? crop.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => crop.name, :class => 'img'), crop
|
||||
.cropinfo
|
||||
.cropname
|
||||
= link_to crop.name, crop
|
||||
- if crop.scientific_names.count > 0
|
||||
.scientificname
|
||||
= crop.scientific_names.first.scientific_name
|
||||
%br/
|
||||
%small
|
||||
.plantingcount
|
||||
Planted
|
||||
= pluralize(crop.plantings.size, "time")
|
||||
|
||||
@@ -4,7 +4,12 @@
|
||||
is a variety of
|
||||
= succeed "." do
|
||||
= link_to crop.parent, crop.parent
|
||||
- if crop.varieties.count > 0
|
||||
%h3
|
||||
Varieties:
|
||||
|
||||
- unless crop.varieties.empty?
|
||||
%p
|
||||
Varieties of #{crop.name}:
|
||||
|
||||
= render :partial => 'hierarchy', :locals => { :display_crops => [ crop ] }
|
||||
|
||||
- if ! crop.parent and crop.varieties.empty?
|
||||
%p None known.
|
||||
|
||||
11
app/views/crops/_wrangle.html.haml
Normal file
11
app/views/crops/_wrangle.html.haml
Normal file
@@ -0,0 +1,11 @@
|
||||
- if can? :edit, crop or can? :destroy, crop
|
||||
%h4 Crop wrangling
|
||||
%p
|
||||
You are a
|
||||
= succeed "." do
|
||||
%strong CROP WRANGLER
|
||||
%p
|
||||
- if can? :edit, crop
|
||||
= link_to 'Edit crop', edit_crop_path(crop), { :class => 'btn btn-default btn-xs' }
|
||||
- if can? :destroy, crop
|
||||
= link_to 'Delete crop', crop, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'
|
||||
@@ -5,5 +5,5 @@
|
||||
= succeed "." do
|
||||
= link_to "crops database", crops_path
|
||||
|
||||
- cache("full_crop_hierarchy") do
|
||||
- cache cache_key_for(Crop) do
|
||||
= render :partial => "hierarchy", :locals => { :display_crops => @crops }
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
%rss{:version => 2.0}
|
||||
%channel
|
||||
%title #{ENV['GROWSTUFF_SITE_NAME']} - Recently added crops
|
||||
%title Recently added crops (#{ENV['GROWSTUFF_SITE_NAME']})
|
||||
%link= crops_url
|
||||
- @crops.each do |crop|
|
||||
%item
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
|
||||
.row
|
||||
.col-md-9
|
||||
- unless current_member
|
||||
Learn how to grow #{ @crop.name.pluralize } from growers around the world. #{ ENV['GROWSTUFF_SITE_NAME'] } has tips and advice from real-life growers, including when to plant #{ @crop.name.pluralize }, how to harvest #{ @crop.name.pluralize }, and more.
|
||||
|
||||
= render :partial => 'photos', :locals => { :crop => @crop }
|
||||
|
||||
@@ -34,69 +36,46 @@
|
||||
%div#cropmap
|
||||
|
||||
%a{:name => 'posts'}
|
||||
%div.pagination
|
||||
= page_entries_info @posts, :model => "posts"
|
||||
= will_paginate @posts, :params => {:anchor => "posts"}
|
||||
%h2 What people are saying about #{ @crop.name.pluralize }
|
||||
|
||||
- unless @posts.empty?
|
||||
- if @posts.empty?
|
||||
%p
|
||||
Nobody has posted about #{ @crop.name.pluralize } yet.
|
||||
%p
|
||||
- if can? :create, Post
|
||||
= link_to "Post something", new_post_path, :class => 'btn btn-default'
|
||||
- else
|
||||
= render :partial => "shared/signin_signup", :locals => { :to => "post your tips and experiences growing #{ @crop.name.pluralize }" }
|
||||
- else
|
||||
%div.pagination
|
||||
= page_entries_info @posts, :model => "posts"
|
||||
= will_paginate @posts, :params => {:anchor => "posts"}
|
||||
- @posts.each do |post|
|
||||
= render :partial => "posts/single", :locals => { :post => post, :subject => true }
|
||||
|
||||
%div.pagination
|
||||
= page_entries_info @posts, :model => "posts"
|
||||
= will_paginate @posts, :params => {:anchor => "posts"}
|
||||
%div.pagination
|
||||
= page_entries_info @posts, :model => "posts"
|
||||
= will_paginate @posts, :params => {:anchor => "posts"}
|
||||
|
||||
.col-md-3
|
||||
- if can? :edit, @crop or can? :destroy, @crop
|
||||
%h4 Crop wrangling
|
||||
%p
|
||||
You are a
|
||||
= succeed "." do
|
||||
%strong CROP WRANGLER
|
||||
%p
|
||||
- if can? :edit, @crop
|
||||
= link_to 'Edit crop', edit_crop_path(@crop), { :class => 'btn btn-default btn-xs' }
|
||||
- if can? :destroy, @crop
|
||||
= link_to 'Delete crop', @crop, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'
|
||||
|
||||
.scientific_names
|
||||
%h4 Scientific names
|
||||
%ul
|
||||
- @crop.scientific_names.each do |sn|
|
||||
%li
|
||||
= sn.scientific_name
|
||||
- if can? :edit, sn
|
||||
= link_to 'Edit', edit_scientific_name_path(sn), { :class => 'btn btn-default btn-xs' }
|
||||
- if can? :destroy, sn
|
||||
= link_to 'Delete', sn, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'
|
||||
%p
|
||||
- if can? :edit, @crop
|
||||
= link_to 'Add', new_scientific_name_path( :crop_id => @crop.id ), { :class => 'btn btn-default btn-xs' }
|
||||
= render :partial => 'wrangle', :locals => { :crop => @crop }
|
||||
|
||||
.alternate_names
|
||||
%h4 Alternate names
|
||||
%ul
|
||||
- @crop.alternate_names.each do |an|
|
||||
%li
|
||||
= an.name
|
||||
- if can? :edit, an
|
||||
= link_to 'Edit', edit_alternate_name_path(an), { :class => 'btn btn-default btn-xs' }
|
||||
- if can? :destroy, an
|
||||
= link_to 'Delete', an, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'
|
||||
%p
|
||||
- if can? :edit, @crop
|
||||
= link_to 'Add', new_alternate_name_path( :crop_id => @crop.id ), { :class => 'btn btn-default btn-xs' }
|
||||
|
||||
= render :partial => 'varieties', :locals => { :crop => @crop }
|
||||
%h4 How to grow #{ @crop.name.pluralize }
|
||||
|
||||
= render :partial => 'grown_for', :locals => { :crop => @crop }
|
||||
|
||||
= render :partial => 'planting_advice', :locals => { :crop => @crop }
|
||||
|
||||
%h4 More information
|
||||
%ul
|
||||
%li= link_to 'Wikipedia (English)', @crop.en_wikipedia_url
|
||||
= render :partial => 'scientific_names', :locals => { :crop => @crop }
|
||||
= render :partial => 'alternate_names', :locals => { :crop => @crop }
|
||||
|
||||
%h4 #{ @crop.name.capitalize } varieties
|
||||
= render :partial => 'varieties', :locals => { :crop => @crop }
|
||||
|
||||
= render :partial => 'plantings', :locals => { :crop => @crop }
|
||||
= render :partial => 'harvests', :locals => { :crop => @crop }
|
||||
= render :partial => 'find_seeds', :locals => { :crop => @crop }
|
||||
|
||||
%h4 Learn more about #{ @crop.name.pluralize }
|
||||
%ul
|
||||
%li= link_to 'Wikipedia (English)', @crop.en_wikipedia_url
|
||||
|
||||
@@ -1,19 +1,24 @@
|
||||
.row
|
||||
.col-md-6.hidden-xs
|
||||
- cache "interesting_crops", :expires_in => 1.day do
|
||||
.col-md-8
|
||||
- cache cache_key_for(Crop, 'interesting'), :expires_in => 1.day do
|
||||
%h2= t('.our_crops')
|
||||
- Crop.interesting.each do |c|
|
||||
.col-md-3{:style => 'margin:0px; padding: 3px'}
|
||||
= render :partial => 'crops/image_with_popover', :locals => { :crop => c }
|
||||
.hidden-xs
|
||||
- Crop.interesting.first(8).each do |c|
|
||||
.col-md-3
|
||||
= render :partial => 'crops/thumbnail', :locals => { :crop => c }
|
||||
.visible-xs
|
||||
- Crop.interesting.first(3).each do |c|
|
||||
.col-md-3
|
||||
= render :partial => 'crops/thumbnail', :locals => { :crop => c }
|
||||
|
||||
.col-md-6
|
||||
- cache "interesting_plantings" do
|
||||
.col-md-4.hidden-xs
|
||||
- cache cache_key_for(Planting) do
|
||||
%h2= t('.recently_planted')
|
||||
= render :partial => 'plantings/list', :locals => { :plantings => Planting.interesting.first(4) }
|
||||
= render :partial => 'plantings/list', :locals => { :plantings => Planting.interesting.first(6) }
|
||||
|
||||
.row
|
||||
.col-md-12
|
||||
- cache "recent_crops" do
|
||||
- cache cache_key_for(Crop, 'recent') do
|
||||
%p{ :style => 'margin-top: 11.25px' }
|
||||
%strong
|
||||
#{t('.recently_added')}:
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
%h2= t('.discussion')
|
||||
|
||||
- cache "recent_posts" do
|
||||
- posts = Post.limit(6)
|
||||
- if posts
|
||||
=render :partial => "posts/summary", :locals => { :posts => posts, :howmany => 6 }
|
||||
- posts = Post.limit(6)
|
||||
- if posts
|
||||
=render :partial => "posts/summary", :locals => { :posts => posts, :howmany => 6 }
|
||||
|
||||
- cache "homepage_forums" do
|
||||
- cache cache_key_for(Forum) do
|
||||
- forums = Forum.all
|
||||
- if forums
|
||||
%ul.list-inline
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
%h2= t('.keep_in_touch')
|
||||
|
||||
%p
|
||||
=image_tag("twitter_32.png", :alt => '')
|
||||
= t('.twitter_html', link: link_to(t('.twitter_linktext'), 'http://twitter.com/growstufforg'))
|
||||
|
||||
%p
|
||||
=image_tag("blog_32.png", :alt => '')
|
||||
= t('.blog_html', link: link_to(t('.blog_linktext'), 'http://blog.growstuff.org/'))
|
||||
|
||||
%p
|
||||
=image_tag("email_32.png", :alt => '')
|
||||
= t('.newsletter_html', link: link_to(t('.newsletter_linktext'), 'http://blog.growstuff.org/newsletter'))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
- cache "interesting_members" do
|
||||
- cache cache_key_for(Member) do
|
||||
.hidden-xs
|
||||
- members = Member.interesting.first(6)
|
||||
- if members.present?
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
.row
|
||||
- members.each do |m|
|
||||
.col-md-6.homepage-members
|
||||
.col-md-4.homepage-members
|
||||
= render :partial => "members/thumbnail", :locals => { :member => m }
|
||||
|
||||
%p.text-right
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
%h2= t('.open_source_title')
|
||||
|
||||
%p
|
||||
= t('.open_source_body_html', why: link_to(t('.why_linktext'), 'http://blog.growstuff.org/2013/02/20/why-growstuff-is-open-source/'),
|
||||
github: link_to(t('.github_linktext'), 'http://github.com/Growstuff/growstuff'),
|
||||
site_name: ENV['GROWSTUFF_SITE_NAME'] )
|
||||
|
||||
|
||||
%h2= t('.open_data_title')
|
||||
|
||||
%p
|
||||
= t('.open_data_body_html', creative_commons_link: link_to(t('.creative_commons_linktext'), 'http://creativecommons.org/licenses/by-sa/3.0/'),
|
||||
wiki_link: link_to(t('.wiki_linktext'), 'http://wiki.growstuff.org/index.php/Open_data'),
|
||||
api_docs_link: link_to(t('.api_docs_linktext'), 'http://wiki.growstuff.org/index.php/API'))
|
||||
|
||||
|
||||
|
||||
%h2= t('.get_involved_title')
|
||||
|
||||
%p
|
||||
= t('.get_involved_body_html', talk_link: link_to(t('.talk_linktext'), 'http://talk.growstuff.org/'),
|
||||
wiki_link: link_to(t('.wiki_linktext'), 'http://wiki.growstuff.org/'))
|
||||
|
||||
|
||||
%h2= t('.support_title')
|
||||
|
||||
%p
|
||||
= t('.support_body_html', ad_free: link_to(t('.ad_free_linktext'), 'http://wiki.growstuff.org/index.php/Why_no_ads%3F'),
|
||||
buy_account: link_to(t('.buy_account_linktext'), shop_path))
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
%h2= t('.title')
|
||||
|
||||
- cache "interesting_seeds" do
|
||||
- cache cache_key_for(Seed) do
|
||||
- if seeds.length > 0
|
||||
|
||||
%table.table.table-striped
|
||||
|
||||
@@ -17,13 +17,9 @@
|
||||
= render :partial => 'blurb'
|
||||
.visible-xs
|
||||
= render :partial => 'blurb'
|
||||
.row
|
||||
.col-md-8.main
|
||||
|
||||
= render :partial => 'crops'
|
||||
= render :partial => 'seeds'
|
||||
= render :partial => 'members'
|
||||
= render :partial => 'discuss'
|
||||
|
||||
.col-md-4.sidebar
|
||||
= render :partial => 'keep_in_touch'
|
||||
= render :partial => 'open'
|
||||
|
||||
@@ -1,10 +1,29 @@
|
||||
.navbar.navbar-default.navbar-bottom
|
||||
.container
|
||||
%ul.nav.navbar-nav.text-center
|
||||
%li= link_to "About", "http://wiki.growstuff.org/index.php/About%20Growstuff"
|
||||
%li= link_to "Contact", url_for(:controller => '/about', :action => 'contact')
|
||||
%li= link_to "Terms of Service", url_for(:controller => '/policy', :action => 'tos')
|
||||
%li= link_to "Privacy Policy", url_for(:controller => %'/policy', :action => 'privacy')
|
||||
%li= link_to "Community Guidelines", url_for(:controller => '/policy', :action => 'community')
|
||||
%li= link_to "Support/FAQ", url_for(:controller => '/support')
|
||||
%li= link_to "Open Source", "https://github.com/Growstuff/growstuff"
|
||||
.row
|
||||
.col-md-4#about-growstuff
|
||||
%ul
|
||||
%li= link_to t('about'), "http://wiki.growstuff.org/index.php/About%20Growstuff"
|
||||
%li= link_to t('our_values'), "http://wiki.growstuff.org/index.php/Values"
|
||||
%li= link_to t('open_source'), "https://github.com/Growstuff/growstuff"
|
||||
%li= link_to t('growstuff_team'), "http://wiki.growstuff.org/index.php/Team"
|
||||
%li= link_to t('get_involved'), "http://wiki.growstuff.org/index.php/Get_involved"
|
||||
.col-md-4#policies
|
||||
%ul
|
||||
%li= link_to t('terms_of_service'), url_for(:controller => '/policy', :action => 'tos')
|
||||
%li= link_to t('privacy_policy'), url_for(:controller => '/policy', :action => 'privacy')
|
||||
%li= link_to t('data_use_policy'), url_for(:controller => '/policy', :action => 'api')
|
||||
%li= link_to t('community_guidelines'), url_for(:controller => '/policy', :action => 'community')
|
||||
.col-md-4#contact
|
||||
%ul
|
||||
%li= link_to t('support_'), url_for(:controller => '/support')
|
||||
%li= link_to t('contact'), url_for(:controller => '/about', :action => 'contact')
|
||||
%p
|
||||
= link_to('http://twitter.com/growstufforg', :target => "_blank") do
|
||||
= image_tag("twitter_32.png", :alt => 'Twitter: @growstufforg')
|
||||
|
||||
= link_to('https://www.facebook.com/Growstufforg', :target => "_blank") do
|
||||
= image_tag("facebook_32.png", :alt => 'Facebook')
|
||||
|
||||
= link_to('http://blog.growstuff.org/', :target => "_blank") do
|
||||
= image_tag("blog_32.png", :alt => 'Growstuff Blog')
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
%span.icon-bar
|
||||
%span.icon-bar
|
||||
%a.navbar-brand(href=root_path)
|
||||
= image_tag("/assets/growstuff-brand.png", :size => "200x50", :alt => ENV['GROWSTUFF_SITE_NAME'])
|
||||
= image_tag("growstuff-brand.png", :size => "200x50", :alt => ENV['GROWSTUFF_SITE_NAME'])
|
||||
.navbar-collapse.collapse#navbar-collapse
|
||||
%ul.nav.navbar-nav
|
||||
%li.dropdown<
|
||||
|
||||
@@ -16,5 +16,5 @@
|
||||
= javascript_include_tag "http://html5shim.googlecode.com/svn/trunk/html5.js"
|
||||
= stylesheet_link_tag "application", :media => "all"
|
||||
|
||||
%link(href="/assets/growstuff-apple-touch-icon-precomposed.png" rel="apple-touch-icon-precomposed")
|
||||
= favicon_link_tag '/assets/favicon.ico'
|
||||
%link(href="/growstuff-apple-touch-icon-precomposed.png" rel="apple-touch-icon-precomposed")
|
||||
= favicon_link_tag 'favicon.ico'
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
= render :partial => "layouts/header"
|
||||
= render :partial => "layouts/crowdfunding"
|
||||
|
||||
.container
|
||||
#maincontainer.container
|
||||
.row
|
||||
.col-md-12
|
||||
- if content_for?(:title)
|
||||
|
||||
@@ -9,4 +9,3 @@
|
||||
= member.account_type
|
||||
account
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user