Compare commits

..

258 Commits

Author SHA1 Message Date
Cesy
e578ca2c77 Merge pull request #1153 from Growstuff/dev
Release 18
2017-01-22 07:47:42 +00:00
Daniel O'Connor
c4c50a4174 Merge pull request #1158 from Br3nda/bw/controller-translations
more controller translations
2017-01-22 15:34:14 +10:30
Brenda Wallace
a1c74bfdfb Translations for members controller 2017-01-22 17:36:48 +13:00
Brenda Wallace
2f9453780e Translations for harvests controller 2017-01-22 17:28:49 +13:00
Brenda Wallace
725ae817d4 Translations for gardens controller 2017-01-22 17:26:30 +13:00
Daniel O'Connor
eab9bcb37d Merge pull request #1157 from Br3nda/bw/rubocop-hash-braces
Removed unnecesary braces on hash args
2017-01-22 13:22:11 +10:30
Brenda Wallace
40a981c94d Removed unnecesary braces on hash args 2017-01-22 15:10:11 +13:00
Cesy
dd2af6a0e3 Merge pull request #1155 from CloCkWeRX/2017-01-21-gem-updates
2017 01 21 gem updates
2017-01-21 19:49:05 +00:00
Daniel O'Connor
9192ccf52b Update coveralls 2017-01-21 17:02:40 +10:30
Daniel O'Connor
4e79fd201c Update omniauth 2017-01-21 17:01:59 +10:30
Daniel O'Connor
d266d7ed1a Update i18n-tasks 2017-01-21 16:52:24 +10:30
Daniel O'Connor
f7f1907b74 Silence config/routes.rb:1:39: W: Lint/UnneededDisable: Unnecessary disabling of Metrics/BlockLength for now 2017-01-21 16:45:04 +10:30
Daniel O'Connor
c42e9ca410 Upgrade factory_girl_rails 2017-01-21 16:42:04 +10:30
Daniel O'Connor
f97c465a92 Update geocoder 2017-01-21 16:41:15 +10:30
Daniel O'Connor
a5b566a207 Update lumberjack 2017-01-21 16:40:27 +10:30
Daniel O'Connor
c6d16c92f5 Update public_suffix 2017-01-21 16:40:04 +10:30
Daniel O'Connor
c5b2e37730 Update diff-lcs 2017-01-21 16:39:31 +10:30
Daniel O'Connor
5c642dfef9 Really disable 2017-01-21 16:37:30 +10:30
Daniel O'Connor
a9b8253dfa Update connection_pool 2017-01-21 16:35:33 +10:30
Daniel O'Connor
58a3cbf569 Disable check for now 2017-01-21 16:28:57 +10:30
Daniel O'Connor
8b4c8fef3b Pin to earlier version of rainbow until https://github.com/sickill/rainbow/issues/44 is sorted 2017-01-21 16:14:37 +10:30
Daniel O'Connor
36c0de4504 Upgrade to selenium-webdriver 3.0.0 2017-01-21 16:04:15 +10:30
Daniel O'Connor
3208bf9fb6 Regenerate rubocop configuration 2017-01-21 15:58:52 +10:30
Daniel O'Connor
4eebf5c867 Error: The Style/MethodCallParentheses cop has been renamed to Style/MethodCallWithoutArgsParentheses. 2017-01-21 15:57:01 +10:30
Daniel O'Connor
61f7bdfdd2 Update rubocop 2017-01-21 15:56:02 +10:30
Daniel O'Connor
06838d7ad1 Update ruby_dep, unicode-display_width 2017-01-21 15:55:22 +10:30
Daniel O'Connor
676f246e85 Merge pull request #1154 from Br3nda/bw/translations
More translations
2017-01-21 15:51:41 +10:30
Shiny
6121a9bc6e Merge branch 'dev' into bw/translations 2017-01-20 21:05:31 +11:00
Brenda Wallace
c2804f1725 Merge branch 'bw/controller-translations' into bw/translations
Conflicts:
	config/locales/en.yml
2017-01-20 23:04:00 +13:00
Brenda Wallace
b198305d36 Translations for account controller 2017-01-20 22:48:04 +13:00
Brenda Wallace
7d7f5bfda3 Translations for account types 2017-01-20 22:46:12 +13:00
Brenda Wallace
d97af8e76e Adding missing translation for harvests 2017-01-20 22:40:14 +13:00
Brenda Wallace
91adc5f59e Normalise english translations file 2017-01-20 22:23:38 +13:00
pozorvlak
a8d5b14d46 Merge pull request #1150 from Br3nda/bw/rubocop
Rubocop fix up for the models
2017-01-17 17:43:24 +00:00
pozorvlak
cc59c4f49b Merge branch 'dev' into bw/rubocop 2017-01-17 16:47:07 +00:00
pozorvlak
8a7b7e75ef Merge pull request #1141 from Br3nda/bw/active-plantings
Show only active plantings by default
2017-01-17 16:41:22 +00:00
Shiny
f8dda12de6 Merge branch 'dev' into bw/active-plantings 2017-01-15 17:36:32 +13:00
Shiny
ab332976da Merge branch 'dev' into bw/rubocop 2017-01-15 17:36:17 +13:00
pozorvlak
331c778350 Merge pull request #1152 from CloCkWeRX/upgrade-comfortable-mexican-sofa
Upgrade to current comfortable_mexican_sofa
2017-01-14 22:20:54 +00:00
Cesy
48b6a2297b Merge branch 'master' into dev 2017-01-14 20:21:46 +00:00
pozorvlak
27ea2e0432 Merge branch 'dev' into upgrade-comfortable-mexican-sofa 2017-01-14 19:53:06 +00:00
pozorvlak
4c0000b964 Merge pull request #1145 from Br3nda/bw/description-photo-links
Descriptive links from photo page
2017-01-14 19:51:20 +00:00
Daniel O'Connor
a3ee17bd4d #1054 Upgrade to current comfortable_mexican_sofa 2017-01-15 02:19:15 +10:30
Brenda Wallace
958e7eb955 Removed rubocop excludes that we have fixed 2017-01-14 21:13:59 +13:00
Brenda Wallace
39888d44e2 Rubocop compliance for the account model 2017-01-14 21:11:02 +13:00
Brenda Wallace
b603bae1a7 Rubocop compliance for the notification model 2017-01-14 21:09:47 +13:00
Brenda Wallace
05db5f3109 Rubocop compliance for the order_item model 2017-01-14 21:08:47 +13:00
Brenda Wallace
ad72ab0ba8 Rubocop compliance for the role model 2017-01-14 21:04:19 +13:00
Brenda Wallace
3beb3974fc Rubocop compliance for the product model 2017-01-14 21:03:01 +13:00
Brenda Wallace
fa15fd2912 Rubocop compliance for the photo model 2017-01-14 21:01:46 +13:00
Brenda Wallace
78ed7869c5 Rubocop compliance for the member model 2017-01-14 20:57:18 +13:00
Brenda Wallace
0fa9f54c9c Rename member.has_role? to role? 2017-01-14 20:54:43 +13:00
Brenda Wallace
f214f608ff Rename member.is_paid? to paid? 2017-01-14 20:51:22 +13:00
Brenda Wallace
eb70f6dc57 Rubocop compliance for the seed model 2017-01-14 20:48:19 +13:00
Brenda Wallace
43c4b154f9 Rubocop compliance for the follow model 2017-01-14 20:45:54 +13:00
Brenda Wallace
21a536bf86 Merge remote-tracking branch 'upstream/dev' into bw/rubocop 2017-01-14 20:43:02 +13:00
Brenda Wallace
832a20eac9 Rubocop compliance for order model 2017-01-14 20:42:32 +13:00
Brenda Wallace
f6cc0f3e13 rubocop compliance in post model 2017-01-14 20:34:08 +13:00
Brenda Wallace
5be5585084 Rubocop disable Rails/HasAndBelongsToMany 2017-01-14 20:31:34 +13:00
Brenda Wallace
989f176fb7 Crop model adhering to rubocop 2017-01-14 20:09:54 +13:00
Brenda Wallace
be07b5fd0e Only check values.zero? if they are present 2017-01-14 20:09:09 +13:00
Shiny
180505a1ca Merge branch 'dev' into bw/active-plantings 2017-01-14 18:27:18 +13:00
Shiny
e11603cb3e Merge branch 'dev' into bw/description-photo-links 2017-01-14 18:25:52 +13:00
Daniel O'Connor
97c5eb1c42 Merge pull request #1149 from Br3nda/bw/quotes-in-name
Removed unwanted quotes in member name in menu
2017-01-14 15:09:04 +10:30
Brenda Wallace
d07509f9e4 Rubocop compliance for comment model 2017-01-14 17:23:39 +13:00
Brenda Wallace
0c1220d11f Rubocop compliance for harvest model 2017-01-14 17:22:33 +13:00
Brenda Wallace
f889b112fe Rubocop compliance for garden model 2017-01-14 17:20:21 +13:00
Brenda Wallace
a1cfa826d9 Removed unwanted quotes in member name in menu
Fix for Issue #1144
2017-01-14 17:11:58 +13:00
Brenda Wallace
477f9669bd Added nav for plantings 2017-01-14 16:54:37 +13:00
Brenda Wallace
c1da5e4dc8 Split plantings#index into two methods to simplify 2017-01-14 16:47:29 +13:00
Brenda Wallace
6bdfe5a669 Moved plantings nav bar to own file and simplified 2017-01-14 16:32:03 +13:00
Shiny
8138aa8c09 Merge branch 'dev' into bw/active-plantings 2017-01-14 15:33:28 +13:00
Brenda Wallace
eba397117c Planting needs to calculate slugs before model is valid 2017-01-14 11:41:48 +13:00
Brenda Wallace
f9396248e6 Merge remote-tracking branch 'upstream/dev' into bw/description-photo-links 2017-01-11 12:12:36 +13:00
pozorvlak
f31342c6e0 Merge pull request #1147 from Br3nda/alpha-bundle
Bundle alphabetical order to comply with stricter rubocop.

Patch is semantically a no-op, and the static check failure is expected.
2017-01-09 12:11:45 +00:00
Brenda Wallace
87a091d694 Bundle alpha-order to comply with stricter rubocop 2017-01-08 20:50:52 +00:00
Brenda Wallace
2e04d56225 Merge remote-tracking branch 'origin/bw/description-photo-links' into bw/description-photo-links 2017-01-08 21:48:58 +13:00
Brenda Wallace
405dfe4bc9 Merge remote-tracking branch 'upstream/dev' into bw/description-photo-links 2017-01-08 21:35:59 +13:00
Shiny
15de4ac08c Merge branch 'dev' into bw/active-plantings 2017-01-08 11:16:19 +13:00
Shiny
c55208713b Merge branch 'dev' into bw/description-photo-links 2017-01-08 11:09:19 +13:00
Shiny
48c1b4d0f9 Merge pull request #1142 from Br3nda/bw/harvests-linkto-plantings
Link a harvest to a planting, and display
2017-01-08 11:08:42 +13:00
Brenda Wallace
2f38a8585b Revert "update spec for stringify"
This reverts commit 144823bd13.
2017-01-07 13:50:11 +13:00
Brenda Wallace
062ff16acf Put garden.to_s back to garden.name 2017-01-07 13:17:53 +13:00
Brenda Wallace
7f30ce04e0 Garden name (truncated) on front page link 2017-01-07 13:09:35 +13:00
Brenda Wallace
144823bd13 update spec for stringify 2017-01-07 12:52:47 +13:00
Brenda Wallace
90b19d52bb Don't rely on to_s for slug. Fragile with translations 2017-01-07 12:49:57 +13:00
Brenda Wallace
76be980163 Translate garden.location 2017-01-07 12:48:14 +13:00
Brenda Wallace
88b1f02574 Added require of photo model constants 2017-01-07 12:44:08 +13:00
Brenda Wallace
5b633b484b Fixes link to seeds, and spec for link to seeds 2017-01-07 12:22:28 +13:00
Brenda Wallace
3be379cee9 updated specs to match new links on photo page 2017-01-07 12:05:35 +13:00
Brenda Wallace
5319d23ee3 Using translations on links from photo page 2017-01-07 12:03:31 +13:00
Brenda Wallace
350c1d4c08 Descriptive links from photo page 2017-01-06 22:25:13 +13:00
Shiny
5ca8829727 Merge branch 'dev' into bw/active-plantings 2017-01-05 16:35:39 +13:00
Shiny
d40eccdb63 Merge branch 'dev' into bw/harvests-linkto-plantings 2017-01-05 16:31:22 +13:00
pozorvlak
478fae53ab Merge pull request #1136 from Br3nda/bw/garden-specs
Controller garden specs for member doing what they shouldn't
2017-01-04 12:06:10 +00:00
Shiny
fc71cba6ba Merge branch 'dev' into bw/harvests-linkto-plantings 2017-01-04 22:52:54 +13:00
Brenda Wallace
283bb76a9e Link a harvest to a planting, and display 2017-01-04 22:45:49 +13:00
Brenda Wallace
18e58809c3 Merge remote-tracking branch 'upstream/dev' into bw/active-plantings 2017-01-04 16:25:44 +13:00
Brenda Wallace
b27b361e2f Show active plantings by default 2017-01-04 16:25:19 +13:00
Shiny
3fafa87afd Merge branch 'dev' into bw/garden-specs 2017-01-04 16:18:54 +13:00
pozorvlak
de60dbb9b0 Merge pull request #1140 from Br3nda/bw/descriptive-spec
descriptive spec
2017-01-03 12:12:18 +00:00
Brenda Wallace
8047aef692 Merge remote-tracking branch 'upstream/dev' into bw/descriptive-spec
Conflicts:
	spec/features/signin_spec.rb
2017-01-03 22:16:24 +13:00
Brenda Wallace
b38728c5df Add login() to signin spec to reduce code duplication 2017-01-03 22:13:27 +13:00
Brenda Wallace
241c3cfdc0 Moves model name into spec description
so we can tell which failed.
2017-01-03 22:12:23 +13:00
Shiny
8b3b28b9d6 Merge branch 'dev' into bw/garden-specs 2017-01-03 20:50:20 +13:00
Daniel O'Connor
5f6fc37efd Merge pull request #1138 from Br3nda/bw/garden-name-in-link
Garden's name in link
2017-01-03 13:33:59 +10:30
Brenda Wallace
881acdccc9 Shortening long garden names on a user's page 2017-01-02 20:54:22 +13:00
Brenda Wallace
3b1753d3d5 Garden's name in link 2017-01-02 20:36:25 +13:00
Brenda Wallace
ab75f830fb Controller garden specs for member doing what they shouldn't 2016-12-25 10:38:07 +13:00
Cesy
ca553a4693 Merge pull request #1130 from Growstuff/dev
Release 17
2016-12-21 19:19:47 +00:00
Shiny
58ddeefaa3 Merge pull request #1127 from Br3nda/bw/guard-clauses
Guard clauses
2016-12-21 22:53:06 +13:00
Shiny
ee7fbb9ab9 Merge branch 'dev' into bw/guard-clauses 2016-12-21 20:53:47 +13:00
pozorvlak
cf31e53303 Merge pull request #1131 from pozorvlak/moar_tests
Improve unit test coverage for models
2016-12-20 14:22:36 +00:00
Miles Gould
4b1cdc5650 Test Model.newsletter_(un)subscribe
I'm not very happy with this change as-is. The tests are very shallow
(they wouldn't have caught the bug @tconquest and I found in this code,
for instance), and use the deprecated `receive_message_chain` method.
From the RSpec docs:

"Chains can be arbitrarily long, which makes it quite painless to
violate the Law of Demeter in violent ways, so you should consider any
use of receive_message_chain a code smell.  Even though not all code
smells indicate real problems (think fluent interfaces),
receive_message_chain still results in brittle examples. For example, if
you write allow(foo).to receive_message_chain(:bar, :baz => 37) in a
spec and then the implementation calls foo.baz.bar, the stub will not
work."

Further work needed.
2016-12-19 22:15:53 +00:00
Miles Gould
4f1c94bfb9 Fix warnings in member_spec 2016-12-19 20:44:18 +00:00
Miles Gould
70f589d59b Replace instance vars with locals in member_spec 2016-12-19 20:33:43 +00:00
Miles Gould
f5eede6072 Improve tests for Member.interesting 2016-12-19 20:29:05 +00:00
Miles Gould
3469d6d37f Feature test for signin via email address 2016-12-19 20:23:07 +00:00
Miles Gould
b8385afb2f Remove apparently-unused Geocodable.geocode method
We have unit tests for geocoding, but it's not being covered, so I
assume it's being shadowed by a method installed directly from Geocoder.
2016-12-19 20:14:05 +00:00
Miles Gould
abb9acd04a post_spec: fix warnings
Several "unused variable" warnings (due to replacing unused instance
variables with unused locals) and one warning about ambiguous
lack-of-brackets.
2016-12-19 16:40:05 +00:00
Miles Gould
67faa5554c post_spec: replace instance vars with local vars
The @ in front of a variable makes it an instance variable of the
surrounding object. There's no point doing that for variables that are
only used in a single function, so I've made such variables in the file
post_spec.rb into function-local variables. We should do this more
generally: there are a lot of instances of this (anti?)pattern in our
test suite.
2016-12-19 16:36:46 +00:00
Miles Gould
59b86c9b0c Replace << with string-interpolation in post_spec 2016-12-19 16:33:41 +00:00
Miles Gould
7239cf068b Test [member name](member) mention syntax 2016-12-19 16:31:32 +00:00
Miles Gould
c23e80b56d Test Post.recently_active 2016-12-19 16:26:17 +00:00
Miles Gould
b011fc9bae Test Post.comment_count 2016-12-19 16:17:31 +00:00
Miles Gould
b40974d4c3 Test Crop.create_from_csv with missing parent
I couldn't work out how to test that the error is logged.
2016-12-19 16:15:19 +00:00
Shiny
ed081e7286 Merge branch 'dev' into bw/guard-clauses 2016-12-18 19:29:05 +13:00
Cesy
1b9a5bc115 Merge pull request #1129 from Br3nda/bw/ruby-upgrade-2-3-3
Upgrade to ruby 2.3.3
2016-12-17 09:59:22 +00:00
Brenda Wallace
b0dd53eb63 Upgrade to ruby 2.3.3 2016-12-17 20:32:07 +13:00
Brenda Wallace
ebae0dfad3 Merge remote-tracking branch 'upstream/dev' into bw/guard-clauses 2016-12-14 21:37:12 +00:00
Brenda Wallace
ca7868b79a Use guard clauses 2016-12-14 21:28:35 +00:00
Daniel O'Connor
148dfa7f8b Merge pull request #1126 from CloCkWeRX/2016-12-gem-upgrades
2016 12 gem upgrades
2016-12-13 15:08:46 +10:30
Daniel O'Connor
feff2cdfd4 Upgrade rake only 2016-12-12 10:38:31 +10:30
Daniel O'Connor
74657abec0 Revert "Update rake and rubocop"
This reverts commit c9127dbf1e.
2016-12-12 10:37:45 +10:30
Daniel O'Connor
6ff3fa21e1 Revert "Disable Style/EmptyMethod for now"
This reverts commit 5235b11905.
2016-12-12 10:37:26 +10:30
Daniel O'Connor
be572b9a53 Upgrade 2016-12-09 11:25:03 +10:30
Daniel O'Connor
5235b11905 Disable Style/EmptyMethod for now 2016-12-09 11:17:54 +10:30
Daniel O'Connor
d3d3731fa3 Update minitest 2016-12-09 10:52:01 +10:30
Daniel O'Connor
1982dc76be Pin to elasticsearch API 2.0 for now 2016-12-09 10:51:13 +10:30
Daniel O'Connor
c9127dbf1e Update rake and rubocop 2016-12-09 10:46:22 +10:30
Daniel O'Connor
f7ca706e0b Update omniauth-facebook (not as scary as it sounds - https://github.com/mkdynamic/omniauth-facebook/blob/master/CHANGELOG.md) 2016-12-09 10:25:08 +10:30
Daniel O'Connor
817c1ec5ce Update will_paginate 2016-12-09 10:24:18 +10:30
Daniel O'Connor
18ab47eed3 Update thor 2016-12-09 10:23:24 +10:30
Daniel O'Connor
d99f24c02c Update coffee-script-source 2016-12-09 10:22:32 +10:30
Daniel O'Connor
aaaca81d49 Update hashie 2016-12-09 10:21:31 +10:30
Daniel O'Connor
59ec36320b Update codeclimate-test-reporter 2016-12-09 10:20:47 +10:30
Daniel O'Connor
303fd8c243 Update autoprefixer-rails 2016-12-09 10:20:09 +10:30
Daniel O'Connor
3e43a19e58 Update CONTRIBUTING.md
Dead link, no archived version of it
2016-12-09 10:09:04 +10:30
Shiny
46a0956f5f Merge pull request #1124 from Br3nda/bw/load-resource
Cancan already loads the resource
2016-12-09 07:29:28 +13:00
Brenda Wallace
4f465d808c We don't need to load the resource again 2016-12-07 23:54:03 +00:00
Shiny
aea935be4b Merge pull request #1122 from Br3nda/bw/duplicate-query
Gardens query was running twice in contoller
2016-12-08 12:32:20 +13:00
Brenda Wallace
e695d5646a FIX Gardens query was running twice in contoller 2016-12-07 22:27:17 +00:00
Daniel O'Connor
e799233fb7 Merge pull request #1119 from Br3nda/bw/ParenthesesAsGroupedExpression
Fixed parentheses that are interp-ed as grouped expression
2016-12-07 12:30:38 +10:30
Shiny
00e240c038 Merge branch 'dev' into bw/ParenthesesAsGroupedExpression 2016-12-07 10:06:50 +13:00
Brenda Wallace
05e7a27782 Call to verify options stays as a hash 2016-12-07 10:04:17 +13:00
Mackenzie
53477485ef Merge pull request #1117 from Br3nda/bw/AmbiguousOperator
Fixed AmbiguousOperator
2016-12-06 12:40:21 -05:00
Mackenzie
c760112e1b Merge pull request #1118 from Br3nda/bw/assignment-in-condition
Don't use assignments in conditions
2016-12-06 12:40:00 -05:00
Mackenzie
0e8146b7ee Merge pull request #1120 from Br3nda/bw/more-enwikipedia-chars
Yet another wikipedia url char added to regex
2016-12-06 12:39:33 -05:00
Brenda Wallace
a7bafafa06 Yet another wikipedia url char added to regex 2016-12-06 21:58:17 +13:00
Brenda Wallace
464c570d99 Fixed parentheses that are interp-ed as grouped expression 2016-12-06 21:23:55 +13:00
Brenda Wallace
abc5ac5f29 Don't use assignments in conditions 2016-12-06 21:18:13 +13:00
Brenda Wallace
4c6f0fc929 Fixed AmbiguousOperator 2016-12-06 21:09:39 +13:00
Daniel O'Connor
41e408b04a Merge pull request #1116 from Br3nda/bw/returns
Removed redundant returns
2016-12-06 11:20:45 +10:30
Brenda Wallace
8981a222ea Simplified display_weight 2016-12-06 00:32:20 +00:00
Brenda Wallace
91b0c1898e Simplifying display_harvest_description 2016-12-05 20:40:34 +00:00
Brenda Wallace
26e5a414cf Line no longer needs wrapping 2016-12-04 21:23:33 +00:00
Brenda Wallace
92195d51d2 Removed redundant returns 2016-12-04 21:21:35 +00:00
Shiny
0fcd8c8e8c Merge pull request #1094 from Br3nda/bw/useless-assignments
Useless assignments fixed, and rails 4 stuff.
2016-12-05 10:06:03 +13:00
Daniel O'Connor
c43ec3d256 Merge branch 'dev' into bw/useless-assignments 2016-12-04 10:30:41 +10:30
Daniel O'Connor
1ae9366076 Merge pull request #1109 from maco/seed_photos
add photos to seeds
2016-12-04 10:30:07 +10:30
Daniel O'Connor
8bb6df6ca7 Merge branch 'dev' into seed_photos 2016-12-03 16:47:13 +10:30
Daniel O'Connor
afbdd1194f Merge branch 'dev' into bw/useless-assignments 2016-12-03 16:43:11 +10:30
Mackenzie Morgan
c2de65e515 Merge branch 'seed_photos' of gitmaco:maco/growstuff into seed_photos 2016-12-02 23:18:05 -05:00
Mackenzie Morgan
c201200e9b correct schema and add index for photos_seeds 2016-12-02 23:17:01 -05:00
Mackenzie
04ba871949 Merge pull request #1108 from maco/fix_photo_requires
WIP: add require_relative to photo_capable concern for constants
2016-12-02 23:13:56 -05:00
Shiny
7785a9d797 Merge branch 'dev' into seed_photos 2016-12-03 09:31:20 +13:00
Shiny
1388aa3b06 Merge branch 'dev' into bw/useless-assignments 2016-12-03 08:23:19 +13:00
Mackenzie
519cf80200 Merge pull request #1111 from CloCkWeRX/658_automation
issue #658 i18n automation (updated)
2016-12-02 08:26:15 -05:00
pozorvlak
ce9e20b2f1 Merge branch 'dev' into 658_automation 2016-12-02 13:06:56 +00:00
Shiny
0c2a60ecc3 Reduce max AbcSize to 38 (#1112)
Reduce how complex methods are allowed to be, according to our code checker, so we're forced to write readable code
2016-12-02 08:06:53 -05:00
Mackenzie
fa1e46c2e7 Merge pull request #1110 from maco/codeclimate_ignores
ignore the minified bootstrap accessibility file for code climate checks
2016-12-02 08:02:47 -05:00
pozorvlak
7b0d17af59 Merge branch 'dev' into 658_automation 2016-12-02 12:05:05 +00:00
pozorvlak
4a8494ad06 Merge branch 'dev' into codeclimate_ignores 2016-12-02 12:04:07 +00:00
pozorvlak
3acaea2914 Merge branch 'dev' into fix_photo_requires 2016-12-02 12:03:53 +00:00
pozorvlak
0156795a29 Merge pull request #1114 from Br3nda/bw/phantom-403s
Revert "Changed phantomjs url to project official"
2016-12-02 11:05:12 +00:00
Brenda Wallace
7aaf6ea2ec Revert "Changed phantomjs url to project official"
This reverts commit 7fcd3cba8d.
2016-12-02 20:21:41 +13:00
Daniel O'Connor
fa65be40a4 lib/tasks/i18n.rake:8:37: W: Lint/UnusedBlockArgument: Unused block argument - t. If it's necessary, use _ or _t as an argument name to indicate that it won't be used. 2016-12-02 15:51:29 +10:30
Daniel O'Connor
aa638b8a68 Missed from merge 2016-12-02 15:41:35 +10:30
Daniel O'Connor
49639c6244 Merge branch '658_automation' of github.com:CloCkWeRX/growstuff into 658_automation 2016-12-02 15:37:55 +10:30
Jim Stallings
e939be05f8 Add myself to contributors 2016-12-02 15:35:13 +10:30
Jim Stallings
160c6efd04 Remove example file, add documentation 2016-12-02 15:34:38 +10:30
Jim Stallings
fe6e269c64 GS-658 - i18n automation POC 2016-12-02 15:34:38 +10:30
Jim Stallings
81f2fa5fa4 GS-658: sort locale keys, add rake task for it 2016-12-02 15:31:07 +10:30
Shiny
bb0eb25dd3 Merge branch 'dev' into bw/useless-assignments 2016-12-02 14:04:30 +13:00
Shiny
077c807958 Merge branch 'dev' into seed_photos 2016-12-02 14:04:12 +13:00
Daniel O'Connor
07ba39c117 Merge branch 'dev' into codeclimate_ignores 2016-12-02 11:33:04 +10:30
Daniel O'Connor
266455eda6 Merge pull request #1105 from maco/wikipedia_regex
expand wikipedia regex to include -, (, and )
2016-12-02 11:32:26 +10:30
Brenda Wallace
03cb4a8dee use find_or_initialize_by 2016-12-02 00:23:46 +00:00
Brenda Wallace
d87de13215 Merge remote-tracking branch 'origin/bw/find-by' into bw/useless-assignments 2016-12-01 23:46:50 +00:00
Mackenzie Morgan
ceac906a3f ignore the minified bootstrap accessibility file for code climate checks 2016-12-01 14:00:18 -05:00
Mackenzie Morgan
2fb34bea18 narrow the regex back down
hyphen must be the LAST thing in the character class
2016-12-01 13:39:43 -05:00
Mackenzie Morgan
a3c8bc0586 include the migration 2016-12-01 13:23:52 -05:00
Mackenzie Morgan
637b46ef10 add photos to seeds
Fixes #495
2016-12-01 12:54:55 -05:00
Mackenzie Morgan
b38945d62f add require_relative to photo_capable concern for constants
starts #1107
2016-12-01 12:53:45 -05:00
Mackenzie Morgan
54628e6d8c expand wikipedia regex to include punctuation, because some have - or () in name
(Fixes: #1104)
2016-12-01 12:25:48 -05:00
pozorvlak
5cb1e14d7b Merge pull request #1095 from maco/photo_concern
DRY up photo & model interaction
2016-12-01 15:16:21 +00:00
Daniel O'Connor
7032436f7b Merge branch 'dev' into bw/useless-assignments 2016-12-01 22:15:50 +10:30
Daniel O'Connor
83a3c3e72f Merge pull request #1102 from cesy/railsupdate
Update rails
2016-12-01 22:04:32 +10:30
Cesy Avon
3d845f47b9 Update rails 2016-12-01 09:42:55 +00:00
Brenda Wallace
d2fb96b3d7 change where.first -> find_by 2016-12-01 22:14:50 +13:00
Brenda Wallace
aba06c1faf Case insensitive crop look up 2016-12-01 21:29:28 +13:00
Brenda Wallace
dc504fe363 use Member.case_insensitive_login_name 2016-12-01 21:29:00 +13:00
Brenda Wallace
cba02ae05c Convert where.first to find_by 2016-12-01 20:25:28 +13:00
Brenda Wallace
37adbe5f48 Moved case-insensitve login look up to method 2016-12-01 20:25:19 +13:00
Brenda Wallace
ae26e3f936 Moved login_name_or_email query to own method 2016-12-01 20:25:10 +13:00
Mackenzie Morgan
7b2be73c88 code climate 2016-12-01 00:22:52 -05:00
Mackenzie Morgan
cd0fbc80d8 Merge remote-tracking branch 'origin/photo_concern' into photo_concern 2016-12-01 00:19:42 -05:00
Mackenzie Morgan
31bbf42ad0 define valid models for photos in a constants file
remove all hardcoded model names from photo.rb and photos_controller.rb
2016-12-01 00:19:33 -05:00
Brenda Wallace
e06d110861 Turn on rails:true in rubocop
so we don't need to pass --rails
2016-12-01 13:30:00 +13:00
Shiny
b454132cae Merge branch 'dev' into bw/useless-assignments 2016-12-01 12:51:13 +13:00
Brenda Wallace
cd0e287dba removed member look up that wasn't used in spec 2016-12-01 12:50:16 +13:00
Shiny
771e6b649c Merge branch 'dev' into photo_concern 2016-12-01 12:37:23 +13:00
Daniel O'Connor
547e6400f8 Merge pull request #1049 from maco/scopify
moving where clauses into scopes to keep that contained in models
2016-12-01 09:48:26 +10:30
Brenda Wallace
ce7cd5d96b Merge branch 'dev' into bw/useless-assignments 2016-12-01 11:17:56 +13:00
Mackenzie
ba4d85538c Merge branch 'dev' into scopify 2016-11-30 16:47:22 -05:00
Mackenzie
af3ca215a6 Merge branch 'dev' into photo_concern 2016-11-30 16:37:36 -05:00
Mackenzie Morgan
cef1bb1056 ignore has_and_belongs_to_many 2016-11-30 16:29:02 -05:00
Brenda Wallace
6321d1ac41 current order, use rails' findby 2016-12-01 10:17:22 +13:00
Mackenzie
57461f6e34 Merge pull request #1091 from pozorvlak/fix_display_days_before_maturity
Fix PlantingHelper.display_days_before_maturity
2016-11-30 10:09:36 -05:00
Mackenzie Morgan
aa7ca71e5d rubocop 2016-11-30 09:47:48 -05:00
Mackenzie Morgan
a5fcfb6277 Merge branch 'dev' of gitmaco:Growstuff/growstuff into photo_concern 2016-11-30 09:44:36 -05:00
Miles Gould
9400225f65 Return a string from display_days_before_maturity
Sometimes we were returning a string, and sometimes we were returning an
integer. We're only ever displaying the result, and this seems a little
more consistent.
2016-11-30 10:16:02 +00:00
Miles Gould
b0b864a5d4 Fix off-by-one bug in display_days_before_maturity
We were counting from DateTime.now rather than Date.current, causing us to
under-count by a day.
2016-11-30 10:16:02 +00:00
Miles Gould
77c64d5925 Test PlantingHelper.display_days_before_maturity
This ensures that #1079 is fixed.
2016-11-30 10:15:52 +00:00
Mackenzie Morgan
77b7969fc9 DRY up photo & model interaction
* move stuff in models into a concern
 * create combined collection for all models that have photos
2016-11-30 00:46:58 -05:00
Brenda Wallace
a2e86b3e5e Rails dynamic finds fixed 2016-11-30 12:21:27 +13:00
Brenda Wallace
b6136d6a20 Removed ignores for rails findby 2016-11-30 10:38:00 +13:00
Brenda Wallace
178c181cf5 Merge remote-tracking branch 'upstream/dev' into bw/useless-assignments
Conflicts:
	app/controllers/crops_controller.rb
	app/models/crop.rb
	spec/models/scientific_name_spec.rb
2016-11-30 10:32:02 +13:00
Mackenzie Morgan
72877aebaf update test for renamed scope 2016-11-29 13:41:05 -05:00
Mackenzie Morgan
4857fd8d2e return from conditional 2016-11-29 12:20:17 -05:00
Mackenzie Morgan
99c8db72d6 syntax 2016-11-29 12:14:16 -05:00
Mackenzie Morgan
53849a26e5 merge 2016-11-29 12:11:52 -05:00
Mackenzie Morgan
9dc02cd3d8 make changes from code review 2016-11-29 12:10:48 -05:00
Mackenzie Morgan
c93fd78aa8 Merge branch 'dev' of gitmaco:Growstuff/growstuff into scopify 2016-11-29 09:58:02 -05:00
Brenda Wallace
8c7fcd9d49 Fixed all useless assignments 2016-11-26 19:36:59 +13:00
Brenda Wallace
1fd7233012 Plualisation fixups 2016-11-26 17:27:13 +13:00
Brenda Wallace
d60dcfbddd Use request.referer instead of request.referrer 2016-11-26 17:26:44 +13:00
Brenda Wallace
b541fe8221 puts allowed in some files 2016-11-26 17:24:41 +13:00
Brenda Wallace
8196d94a73 Don't enforce http pos args until rails 5 2016-11-26 17:23:31 +13:00
Brenda Wallace
07c135eeb5 before_filter is now before_action 2016-11-26 17:20:13 +13:00
Brenda Wallace
bcdd2a9167 Changed called to rails dynamic find_by 2016-11-26 15:55:38 +13:00
Mackenzie Morgan
cee3d192e0 test the new order.by_member_id scope 2016-10-11 16:34:25 -04:00
Mackenzie Morgan
65bf4dae69 Merge branch 'dev' of gitmaco:Growstuff/growstuff into scopify 2016-10-11 15:42:18 -04:00
Mackenzie Morgan
494790bcd4 moving where clauses into scopes to keep that contained in models 2016-10-11 15:28:08 -04:00
Jim Stallings
2f561aaa47 Add myself to contributors 2015-09-26 11:54:51 -04:00
Jim Stallings
e02a6e569c Remove example file, add documentation 2015-09-26 11:54:02 -04:00
Jim Stallings
98581801c3 GS-658 - i18n automation POC 2015-09-19 17:45:31 -04:00
Jim Stallings
93f9435fb9 GS-658: sort locale keys, add rake task for it 2015-09-19 16:24:01 -04:00
140 changed files with 1533 additions and 1815 deletions

View File

@@ -38,3 +38,4 @@ exclude_paths:
- db/
- spec/
- public/
- app/assets/stylesheets/bootstrap-accessibility.css

View File

@@ -8,6 +8,9 @@ AllCops:
- 'db/schema.rb'
- 'vendor/**/*'
Rails:
Enabled: true
Style/FileName:
Exclude:
- 'Gemfile'
@@ -34,7 +37,7 @@ Metrics/MethodLength:
# Remove the following once the code style matches
# Offense count: 59
Metrics/AbcSize:
Max: 115
Max: 38
# Offense count: 5
# Configuration parameters: CountComments.
@@ -66,3 +69,10 @@ Style/Documentation:
Style/FrozenStringLiteralComment:
Enabled: false
# Configuration parameters: Include.
# Include: app/**/*.rb, config/**/*.rb, db/**/*.rb, lib/**/*.rb
Rails/Output:
Exclude:
- 'config/unicorn.rb'
- 'db/seeds.rb'

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1 +1 @@
2.3.1
2.3.3

View File

@@ -11,12 +11,12 @@ env:
global:
secure: "Z5TpM2jEX4UCvNePnk/LwltQX48U2u9BRc+Iypr1x9QW2o228QJhPIOH39a8RMUrepGnkQIq9q3ZRUn98RfrJz1yThtlNFL3NmzdQ57gKgjGwfpa0e4Dwj/ZJqV2D84tDGjvdVYLP7zzaYZxQcwk/cgNpzKf/jq97HLNP7CYuf4="
rvm:
- 2.3.1
- 2.3.3
before_install:
- export PATH=$PWD/travis_phantomjs/phantomjs-2.1.1-linux-x86_64/bin:$PATH
- >
if [ $(phantomjs --version) != '2.1.1' ]; then
PHANTOM_URL=https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2;
PHANTOM_URL=https://assets.membergetmember.co/software/phantomjs-2.1.1-linux-x86_64.tar.bz2;
rm -rf $PWD/travis_phantomjs;
mkdir -p $PWD/travis_phantomjs;
wget $PHANTOM_URL -O $PWD/travis_phantomjs/phantomjs-2.1.1-linux-x86_64.tar.bz2;

View File

@@ -3,7 +3,7 @@ Thanks for contributing to Growstuff!
When you create a pull request, please include the following:
* Mention the issue it solves (eg. #123)
* Your code should follow our [Coding style guide](http://wiki.growstuff.org/index.php/Coding_style_guide)
* Your code should follow our [Coding style guide](https://github.com/Growstuff/growstuff/wiki/Development-process-overview#coding-practices)
* 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).

View File

@@ -72,3 +72,4 @@ submit the change with your pull request.
- Charley Lewittes / [ctlewitt](https://github.com/ctlewitt)
- Kristine Nicole Polvoriza / [polveenomials](https://github.com/polveenomials)
- Brenda Wallace / [br3nda](https://github.com/br3nda)
- Jim Stallings / [jestallin](https://github.com/jestallin)

68
Gemfile
View File

@@ -1,15 +1,15 @@
# frozen_string_literal: true
source 'https://rubygems.org'
ruby '2.3.1'
ruby '2.3.3'
gem 'rails', '~> 4.2.1'
gem 'rails', '~> 4.2.7'
gem 'bundler', '>=1.1.5'
gem 'sass-rails', '~> 5.0.4'
gem 'coffee-rails', '~> 4.1.0'
gem 'haml'
gem 'sass-rails', '~> 5.0.4'
# CSS framework
gem 'bootstrap-sass', '~> 3.3.6'
@@ -17,28 +17,28 @@ gem 'font-awesome-sass'
gem 'uglifier', '~> 2.7.2' # JavaScript compressor
gem 'flickraw'
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 'pg'
gem 'figaro' # for handling config via ENV variables
gem 'cancancan', '~> 1.9' # for checking member privileges
gem 'gibbon', '~>1.2.0' # for Mailchimp newsletter subscriptions
gem 'csv_shaper' # CSV export
gem 'figaro' # for handling config via ENV variables
gem 'gibbon', '~>1.2.0' # for Mailchimp newsletter subscriptions
gem 'leaflet-markercluster-rails'
gem 'leaflet-rails'
gem 'pg'
gem 'ruby-units' # for unit conversion
gem 'unicorn' # http server
gem 'comfortable_mexican_sofa', '~> 1.12.0' # content management system
gem 'kaminari' # pagination
gem 'bootstrap-kaminari-views' # bootstrap views for kaminari
gem 'kaminari' # pagination
gem 'activemerchant'
gem 'active_utils'
gem 'activemerchant'
gem 'sidekiq'
# Markdown formatting for updates etc
@@ -64,24 +64,32 @@ gem 'bootstrap-datepicker-rails'
# For connecting to other services (eg Twitter)
gem 'omniauth'
gem 'omniauth-twitter'
gem 'omniauth-flickr', '>= 0.0.15'
gem 'omniauth-facebook'
gem 'omniauth-flickr', '>= 0.0.15'
gem 'omniauth-twitter'
# client for Elasticsearch. Elasticsearch is a flexible
# and powerful, distributed, real-time search and analytics engine.
# An example of the use in the project is fuzzy crop search.
# Project does not use semver, so we want to be in sync with the version of
# elasticsearch we use
# See https://github.com/elastic/elasticsearch-ruby#compatibility
gem "elasticsearch-api", "~> 2.0.0"
gem "elasticsearch-model"
gem "elasticsearch-rails"
gem 'rake', '>= 10.0.0'
# # CMS
# gem 'comfortable_mexican_sofa', '~> 1.12.0'
group :production, :staging do
gem 'newrelic_rpm'
gem 'bonsai-elasticsearch-rails' # Integration with Bonsa-Elasticsearch on heroku
gem 'dalli'
gem 'memcachier'
gem 'newrelic_rpm'
gem 'rails_12factor' # supresses heroku plugin injection
gem 'bonsai-elasticsearch-rails' # Integration with Bonsa-Elasticsearch on heroku
gem 'sparkpost_rails'
end
@@ -89,32 +97,34 @@ 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'
gem 'guard'
gem 'guard-rspec'
gem 'letter_opener'
gem 'pry'
gem 'quiet_assets'
end
group :development, :test do
gem 'haml-rails' # HTML templating language
gem 'rspec-rails' # unit testing framework
gem 'rspec-activemodel-mocks'
gem "active_merchant-paypal-bogus-gateway"
gem 'byebug' # debugging
gem 'database_cleaner', '~> 1.5.0'
gem 'webrat' # provides HTML matchers for view tests
gem 'factory_girl_rails' # for creating test data
gem 'coveralls', require: false # coverage analysis
gem 'capybara' # integration tests
gem 'capybara-email' # integration tests for email
gem 'capybara-screenshot' # for test debugging
gem 'poltergeist' # for headless JS testing
gem 'coveralls', require: false # coverage analysis
gem 'database_cleaner', '~> 1.5.0'
gem 'factory_girl_rails' # for creating test data
gem 'haml-i18n-extractor'
gem 'haml-rails' # HTML templating language
gem 'i18n-tasks' # adds tests for finding missing and unused translations
gem 'selenium-webdriver'
gem "active_merchant-paypal-bogus-gateway"
gem 'poltergeist' # for headless JS testing
gem 'rspec-activemodel-mocks'
gem 'rspec-rails' # unit testing framework
gem 'rubocop', require: false
gem 'rainbow', '< 2.2.0' # See https://github.com/sickill/rainbow/issues/44
gem 'selenium-webdriver'
gem 'webrat' # provides HTML matchers for view tests
end
group :test do

View File

@@ -50,9 +50,9 @@ GEM
tzinfo (~> 1.1)
addressable (2.5.0)
public_suffix (~> 2.0, >= 2.0.2)
arel (6.0.3)
arel (6.0.4)
ast (2.3.0)
autoprefixer-rails (6.4.0.2)
autoprefixer-rails (6.6.1)
execjs
bcrypt (3.1.11)
better_errors (2.1.1)
@@ -71,8 +71,8 @@ GEM
bootstrap-sass (3.3.7)
autoprefixer-rails (>= 5.2.1)
sass (>= 3.3.4)
bootstrap_form (2.5.2)
builder (3.2.2)
bootstrap_form (2.5.3)
builder (3.2.3)
byebug (9.0.6)
cancancan (1.15.0)
capybara (2.10.1)
@@ -90,13 +90,12 @@ GEM
launchy
childprocess (0.5.9)
ffi (~> 1.0, >= 1.0.11)
climate_control (0.0.3)
activesupport (>= 3.0)
climate_control (0.1.0)
cliver (0.3.2)
cocaine (0.5.8)
climate_control (>= 0.0.3, < 1.0)
codeclimate-test-reporter (0.6.0)
simplecov (>= 0.7.1, < 1.0.0)
codeclimate-test-reporter (1.0.3)
simplecov
codemirror-rails (5.16.0)
railties (>= 3.0, < 6.0)
coderay (1.1.1)
@@ -106,8 +105,8 @@ GEM
coffee-script (2.4.1)
coffee-script-source
execjs
coffee-script-source (1.10.0)
comfortable_mexican_sofa (1.12.9)
coffee-script-source (1.12.2)
comfortable_mexican_sofa (1.12.10)
active_link_to (>= 1.0.0)
bootstrap-sass (>= 3.2.0)
bootstrap_form (>= 2.2.0)
@@ -119,17 +118,17 @@ GEM
kramdown (>= 1.0.0)
paperclip (>= 4.0.0)
plupload-rails (>= 1.2.1)
rails (>= 4.0.0, < 5)
rails (>= 4.0.0, < 5.1)
rails-i18n (>= 4.0.0)
sass-rails (>= 4.0.3)
concurrent-ruby (1.0.2)
connection_pool (2.2.0)
coveralls (0.8.16)
concurrent-ruby (1.0.4)
connection_pool (2.2.1)
coveralls (0.8.19)
json (>= 1.8, < 3)
simplecov (~> 0.12.0)
term-ansicolor (~> 1.3.0)
term-ansicolor (~> 1.3)
thor (~> 0.19.1)
tins (>= 1.6.0, < 2)
tins (~> 1.6)
csv_shaper (1.3.0)
activesupport (>= 3.0.0)
dalli (2.7.6)
@@ -141,7 +140,7 @@ GEM
railties (>= 4.1.0, < 5.1)
responders
warden (~> 1.2.3)
diff-lcs (1.2.5)
diff-lcs (1.3)
docile (1.1.5)
easy_translate (0.5.0)
json
@@ -163,14 +162,14 @@ GEM
erubis (2.7.0)
excon (0.54.0)
execjs (2.7.0)
factory_girl (4.7.0)
factory_girl (4.8.0)
activesupport (>= 3.0.0)
factory_girl_rails (4.7.0)
factory_girl (~> 4.7.0)
factory_girl_rails (4.8.0)
factory_girl (~> 4.8.0)
railties (>= 3.0.0)
faraday (0.9.2)
multipart-post (>= 1.2, < 3)
ffi (1.9.14)
ffi (1.9.17)
figaro (1.1.1)
thor (~> 0.14)
flickraw (0.9.9)
@@ -179,7 +178,7 @@ GEM
formatador (0.2.5)
friendly_id (5.0.5)
activerecord (>= 4.0.0)
geocoder (1.3.7)
geocoder (1.4.1)
gibbon (1.2.1)
httparty
multi_json (>= 1.9.0)
@@ -204,13 +203,19 @@ GEM
rspec (>= 2.99.0, < 4.0)
haml (4.0.7)
tilt
haml-i18n-extractor (0.5.9)
activesupport
haml
highline
tilt
trollop (= 1.16.2)
haml-rails (0.9.0)
actionpack (>= 4.0.1)
activesupport (>= 4.0.1)
haml (>= 4.0.6, < 5.0)
html2haml (>= 1.0.1)
railties (>= 4.0.1)
hashie (3.4.4)
hashie (3.4.6)
heroku-api (0.4.2)
excon (~> 0.45)
multi_json (~> 1.8)
@@ -223,7 +228,7 @@ GEM
httparty (0.14.0)
multi_xml (>= 0.5.2)
i18n (0.7.0)
i18n-tasks (0.9.6)
i18n-tasks (0.9.9)
activesupport (>= 4.0.2)
ast (>= 2.1.0)
easy_translate (>= 0.5.0)
@@ -233,7 +238,7 @@ GEM
parser (>= 2.2.3.0)
term-ansicolor (>= 1.3.2)
terminal-table (>= 1.5.1)
jquery-rails (4.2.1)
jquery-rails (4.2.2)
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
@@ -242,13 +247,13 @@ GEM
js-routes (1.3.0)
railties (>= 3.2)
sprockets-rails
json (1.8.3)
json (1.8.6)
jwt (1.5.6)
kaminari (0.17.0)
actionpack (>= 3.0.0)
activesupport (>= 3.0.0)
kgio (2.10.0)
kramdown (1.13.1)
kramdown (1.13.2)
launchy (2.4.3)
addressable (~> 2.3)
leaflet-markercluster-rails (0.7.0)
@@ -262,7 +267,7 @@ GEM
ruby_dep (~> 1.2)
loofah (2.0.3)
nokogiri (>= 1.5.9)
lumberjack (1.0.10)
lumberjack (1.0.11)
mail (2.6.4)
mime-types (>= 1.16, < 4)
memcachier (0.0.2)
@@ -272,9 +277,9 @@ GEM
mime-types-data (3.2016.0521)
mimemagic (0.3.2)
mini_portile2 (2.1.0)
minitest (5.9.1)
minitest (5.10.1)
multi_json (1.11.3)
multi_xml (0.5.5)
multi_xml (0.6.0)
multipart-post (2.0.0)
nenv (0.3.0)
newrelic_rpm (3.17.1.326)
@@ -290,10 +295,10 @@ GEM
multi_json (~> 1.3)
multi_xml (~> 0.5)
rack (>= 1.2, < 3)
omniauth (1.3.1)
omniauth (1.3.2)
hashie (>= 1.2, < 4)
rack (>= 1.0, < 3)
omniauth-facebook (3.0.0)
omniauth-facebook (4.0.0)
omniauth-oauth2 (~> 1.2)
omniauth-flickr (0.0.19)
multi_json (~> 1.11.0)
@@ -314,7 +319,7 @@ GEM
cocaine (~> 0.5.5)
mime-types
mimemagic (~> 0.3.0)
parser (2.3.2.0)
parser (2.3.3.1)
ast (~> 2.2)
pg (0.19.0)
plupload-rails (1.2.1)
@@ -328,7 +333,7 @@ GEM
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
public_suffix (2.0.4)
public_suffix (2.0.5)
quiet_assets (1.1.0)
railties (>= 3.1, < 5.0)
rack (1.6.5)
@@ -349,9 +354,9 @@ GEM
sprockets-rails
rails-deprecated_sanitizer (1.0.3)
activesupport (>= 4.2.0.alpha)
rails-dom-testing (1.0.7)
rails-dom-testing (1.0.8)
activesupport (>= 4.2.0.beta, < 5.0)
nokogiri (~> 1.6.0)
nokogiri (~> 1.6)
rails-deprecated_sanitizer (>= 1.0.1)
rails-html-sanitizer (1.0.3)
loofah (~> 2.0)
@@ -370,7 +375,7 @@ GEM
thor (>= 0.18.1, < 2.0)
rainbow (2.1.0)
raindrops (0.17.0)
rake (11.3.0)
rake (12.0.0)
rb-fsevent (0.9.8)
rb-inotify (0.9.7)
ffi (>= 0.5.0)
@@ -402,26 +407,26 @@ GEM
rspec-mocks (~> 3.5.0)
rspec-support (~> 3.5.0)
rspec-support (3.5.0)
rubocop (0.45.0)
parser (>= 2.3.1.1, < 3.0)
rubocop (0.47.1)
parser (>= 2.3.3.1, < 3.0)
powerpack (~> 0.1)
rainbow (>= 1.99.1, < 3.0)
ruby-progressbar (~> 1.7)
unicode-display_width (~> 1.0, >= 1.0.1)
ruby-progressbar (1.8.1)
ruby-units (2.0.1)
ruby_dep (1.4.0)
ruby_parser (3.8.3)
ruby_dep (1.5.0)
ruby_parser (3.8.4)
sexp_processor (~> 4.1)
rubyzip (1.2.0)
sass (3.4.22)
sass (3.4.23)
sass-rails (5.0.6)
railties (>= 4.0.0, < 6)
sass (~> 3.1)
sprockets (>= 2.8, < 4.0)
sprockets-rails (>= 2.0, < 4.0)
tilt (>= 1.1, < 3)
selenium-webdriver (2.53.4)
selenium-webdriver (3.0.5)
childprocess (~> 0.5)
rubyzip (~> 1.0)
websocket (~> 1.0)
@@ -444,28 +449,29 @@ GEM
slop (3.6.0)
sparkpost_rails (1.4.0)
rails (>= 4.0, < 5.1)
sprockets (3.7.0)
sprockets (3.7.1)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-rails (3.1.1)
sprockets-rails (3.2.0)
actionpack (>= 4.0)
activesupport (>= 4.0)
sprockets (>= 3.0.0)
term-ansicolor (1.3.2)
term-ansicolor (1.4.0)
tins (~> 1.0)
terminal-table (1.7.3)
unicode-display_width (~> 1.1.1)
thor (0.19.3)
thor (0.19.4)
thread (0.2.2)
thread_safe (0.3.5)
tilt (2.0.5)
tins (1.13.0)
trollop (1.16.2)
tzinfo (1.2.2)
thread_safe (~> 0.1)
uglifier (2.7.2)
execjs (>= 0.3.0)
json (>= 1.8.0)
unicode-display_width (1.1.1)
unicode-display_width (1.1.3)
unicorn (5.1.0)
kgio (~> 2.6)
raindrops (~> 0.7)
@@ -479,7 +485,7 @@ GEM
websocket-driver (0.6.4)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.2)
will_paginate (3.1.0)
will_paginate (3.1.5)
xpath (2.0.0)
nokogiri (~> 1.3)
@@ -511,6 +517,7 @@ DEPENDENCIES
dalli
database_cleaner (~> 1.5.0)
devise (>= 4.0.0)
elasticsearch-api (~> 2.0.0)
elasticsearch-model
elasticsearch-rails
factory_girl_rails
@@ -524,6 +531,7 @@ DEPENDENCIES
guard
guard-rspec
haml
haml-i18n-extractor
haml-rails
heroku-api
i18n-tasks
@@ -544,8 +552,9 @@ DEPENDENCIES
poltergeist
pry
quiet_assets
rails (~> 4.2.1)
rails (~> 4.2.7)
rails_12factor
rainbow (< 2.2.0)
rake (>= 10.0.0)
rspec-activemodel-mocks
rspec-rails
@@ -561,7 +570,7 @@ DEPENDENCIES
will_paginate (~> 3.0)
RUBY VERSION
ruby 2.3.1p112
ruby 2.3.3p222
BUNDLED WITH
1.13.6
1.13.7

View File

@@ -0,0 +1,38 @@
module Growstuff
module Constants
class PhotoModels
PLANTING = { type: 'planting', class: 'Planting', relation: 'plantings' }.freeze
HARVEST = { type: 'harvest', class: 'Harvest', relation: 'harvests' }.freeze
GARDEN = { type: 'garden', class: 'Garden', relation: 'gardens' }.freeze
SEED = { type: 'seed', class: 'Seed', relation: 'seeds' }.freeze
ALL = [PLANTING, HARVEST, GARDEN, SEED].freeze
def self.types
ALL.map do |model|
model[:type]
end
end
def self.relations
ALL.map do |model|
model[:relation]
end
end
def self.get_relation(object, type)
relation = ALL.select do |model|
model[:type] == type
end[0][:relation]
object.send(relation)
end
def self.get_item(type)
class_name = ALL.select do |model|
model[:type] == type
end[0][:class]
class_name.constantize
end
end
end
end

View File

@@ -1,5 +1,5 @@
class AccountTypesController < ApplicationController
before_filter :authenticate_member!
before_action :authenticate_member!
load_and_authorize_resource
# GET /account_types
@@ -13,8 +13,6 @@ class AccountTypesController < ApplicationController
# GET /account_types/1
def show
@account_type = AccountType.find(params[:id])
respond_to do |format|
format.html # show.html.erb
end
@@ -31,7 +29,6 @@ class AccountTypesController < ApplicationController
# GET /account_types/1/edit
def edit
@account_type = AccountType.find(params[:id])
end
# POST /account_types
@@ -40,7 +37,7 @@ class AccountTypesController < ApplicationController
respond_to do |format|
if @account_type.save
format.html { redirect_to @account_type, notice: 'Account type was successfully created.' }
format.html { redirect_to @account_type, notice: I18n.t('account_types.created') }
else
format.html { render action: "new" }
end
@@ -49,11 +46,9 @@ class AccountTypesController < ApplicationController
# PUT /account_types/1
def update
@account_type = AccountType.find(params[:id])
respond_to do |format|
if @account_type.update(account_type_params)
format.html { redirect_to @account_type, notice: 'Account type was successfully updated.' }
format.html { redirect_to @account_type, notice: I18n.t('account_types.updated') }
else
format.html { render action: "edit" }
end
@@ -62,11 +57,10 @@ class AccountTypesController < ApplicationController
# DELETE /account_types/1
def destroy
@account_type = AccountType.find(params[:id])
@account_type.destroy
respond_to do |format|
format.html { redirect_to account_types_url, notice: 'Account type was successfully deleted.' }
format.html { redirect_to account_types_url, notice: I18n.t('account_types.deleted') }
end
end

View File

@@ -1,5 +1,5 @@
class AccountsController < ApplicationController
before_filter :authenticate_member!
before_action :authenticate_member!
load_and_authorize_resource
# GET /accounts
@@ -13,8 +13,6 @@ class AccountsController < ApplicationController
# GET /accounts/1
def show
@account = Account.find(params[:id])
respond_to do |format|
format.html # show.html.erb
end
@@ -22,16 +20,13 @@ class AccountsController < ApplicationController
# GET /accounts/1/edit
def edit
@account = Account.find(params[:id])
end
# PUT /accounts/1
def update
@account = Account.find(params[:id])
respond_to do |format|
if @account.update(params[:account])
format.html { redirect_to @account, notice: 'Account detail was successfully updated.' }
format.html { redirect_to @account, notice: I18n.t('account.update') }
else
format.html { render action: "edit" }
end

View File

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

View File

@@ -1,5 +1,5 @@
class AlternateNamesController < ApplicationController
before_filter :authenticate_member!, except: [:index, :show]
before_action :authenticate_member!, except: [:index, :show]
load_and_authorize_resource
# GET /alternate_names
@@ -17,7 +17,7 @@ class AlternateNamesController < ApplicationController
# GET /alternate_names/new.json
def new
@alternate_name = AlternateName.new
@crop = Crop.find_by_id(params[:crop_id]) || Crop.new
@crop = Crop.find_or_initialize_by(id: params[:crop_id])
respond_to do |format|
format.html # new.html.haml
@@ -27,7 +27,6 @@ class AlternateNamesController < ApplicationController
# GET /alternate_names/1/edit
def edit
@alternate_name = AlternateName.find(params[:id])
end
# POST /alternate_names
@@ -50,8 +49,6 @@ class AlternateNamesController < ApplicationController
# PUT /alternate_names/1
# PUT /alternate_names/1.json
def update
@alternate_name = AlternateName.find(params[:id])
respond_to do |format|
if @alternate_name.update(alternate_name_params)
format.html { redirect_to @alternate_name.crop, notice: 'Alternate name was successfully updated.' }
@@ -66,7 +63,6 @@ class AlternateNamesController < ApplicationController
# DELETE /alternate_names/1
# DELETE /alternate_names/1.json
def destroy
@alternate_name = AlternateName.find(params[:id])
@crop = @alternate_name.crop
@alternate_name.destroy

View File

@@ -3,8 +3,8 @@ class ApplicationController < ActionController::Base
include ApplicationHelper
after_filter :store_location
before_filter :set_locale
after_action :store_location
before_action :set_locale
def store_location
if (request.path != "/members/sign_in" &&
@@ -23,7 +23,7 @@ class ApplicationController < ActionController::Base
end
def after_sign_out_path_for(resource_or_scope)
request.referrer
request.referer
end
# tweak CanCan defaults because we don't have a "current_user" method

View File

@@ -1,5 +1,5 @@
class AuthenticationsController < ApplicationController
before_filter :authenticate_member!
before_action :authenticate_member!
load_and_authorize_resource
# POST /authentications

View File

@@ -1,5 +1,5 @@
class CommentsController < ApplicationController
before_filter :authenticate_member!, except: [:index, :show]
before_action :authenticate_member!, except: [:index, :show]
load_and_authorize_resource
# GET /comments
@@ -18,7 +18,7 @@ class CommentsController < ApplicationController
# GET /comments/new.json
def new
@comment = Comment.new
@post = Post.find_by_id(params[:post_id])
@post = Post.find_by(id: params[:post_id])
if @post
@comments = @post.comments
@@ -34,7 +34,6 @@ class CommentsController < ApplicationController
# GET /comments/1/edit
def edit
@comment = Comment.find(params[:id])
@comments = @comment.post.comments
end
@@ -58,8 +57,6 @@ class CommentsController < ApplicationController
# PUT /comments/1
# PUT /comments/1.json
def update
@comment = Comment.find(params[:id])
# you should never be able to change the author or post when
# updating
params[:comment].delete("post_id")
@@ -79,7 +76,6 @@ class CommentsController < ApplicationController
# DELETE /comments/1
# DELETE /comments/1.json
def destroy
@comment = Comment.find(params[:id])
@post = @comment.post
@comment.destroy

View File

@@ -1,7 +1,7 @@
require 'will_paginate/array'
class CropsController < ApplicationController
before_filter :authenticate_member!, except: [:index, :hierarchy, :search, :show]
before_action :authenticate_member!, except: [:index, :hierarchy, :search, :show]
load_and_authorize_resource
skip_authorize_resource only: [:hierarchy, :search]
@@ -9,15 +9,12 @@ class CropsController < ApplicationController
# GET /crops.json
def index
@sort = params[:sort]
if @sort == 'alpha'
# alphabetical order
@crops = Crop.includes(:scientific_names, { plantings: :photos })
@paginated_crops = @crops.approved.paginate(page: params[:page])
else
# default to sorting by popularity
@crops = Crop.popular.includes(:scientific_names, { plantings: :photos })
@paginated_crops = @crops.approved.paginate(page: params[:page])
end
@crops = if @sort == 'alpha'
Crop.includes(:scientific_names, plantings: :photos)
else
popular_crops
end
@paginated_crops = @crops.approved.paginate(page: params[:page])
respond_to do |format|
format.html
@@ -77,7 +74,7 @@ class CropsController < ApplicationController
# GET /crops/1
# GET /crops/1.json
def show
@crop = Crop.includes(:scientific_names, { plantings: :photos }).find(params[:id])
@crop = Crop.includes(:scientific_names, plantings: :photos).find(params[:id])
@posts = @crop.posts.paginate(page: params[:page])
respond_to do |format|
@@ -113,7 +110,6 @@ class CropsController < ApplicationController
# GET /crops/1/edit
def edit
@crop = Crop.find(params[:id])
@crop.alternate_names.build if @crop.alternate_names.blank?
@crop.scientific_names.build if @crop.scientific_names.blank?
end
@@ -123,7 +119,7 @@ class CropsController < ApplicationController
def create
@crop = Crop.new(crop_params)
if current_member.has_role? :crop_wrangler
if current_member.role? :crop_wrangler
@crop.creator = current_member
success_msg = "Crop was successfully created."
else
@@ -140,7 +136,7 @@ class CropsController < ApplicationController
params[:sci_name].each do |index, value|
create_name('scientific', value)
end
unless current_member.has_role? :crop_wrangler
unless current_member.role? :crop_wrangler
Role.crop_wranglers.each do |w|
Notifier.new_crop_request(w, @crop).deliver_later!
end
@@ -158,8 +154,6 @@ class CropsController < ApplicationController
# PUT /crops/1
# PUT /crops/1.json
def update
@crop = Crop.find(params[:id])
previous_status = @crop.approval_status
@crop.creator = current_member if previous_status == "pending"
@@ -187,7 +181,6 @@ class CropsController < ApplicationController
# DELETE /crops/1
# DELETE /crops/1.json
def destroy
@crop = Crop.find(params[:id])
@crop.destroy
respond_to do |format|
@@ -198,6 +191,10 @@ class CropsController < ApplicationController
private
def popular_crops
Crop.popular.includes(:scientific_names, plantings: :photos)
end
def recreate_names(param_name, name_type)
return unless params[param_name].present?
destroy_names(name_type)

View File

@@ -1,5 +1,5 @@
class FollowsController < ApplicationController
before_filter :authenticate_member!
before_action :authenticate_member!
load_and_authorize_resource
skip_load_resource only: :create

View File

@@ -1,15 +1,16 @@
class GardensController < ApplicationController
before_filter :authenticate_member!, except: [:index, :show]
before_action :authenticate_member!, except: [:index, :show]
load_and_authorize_resource
# GET /gardens
# GET /gardens.json
def index
@gardens = Garden.paginate(page: params[:page])
@owner = Member.find_by_slug(params[:owner])
if @owner
@gardens = @owner.gardens.paginate(page: params[:page])
end
@owner = Member.find_by(slug: params[:owner])
@gardens = if @owner
@owner.gardens.paginate(page: params[:page])
else
Garden.paginate(page: params[:page])
end
respond_to do |format|
format.html # index.html.erb
@@ -20,8 +21,6 @@ class GardensController < ApplicationController
# GET /gardens/1
# GET /gardens/1.json
def show
@garden = Garden.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: @garden }
@@ -41,18 +40,16 @@ class GardensController < ApplicationController
# GET /gardens/1/edit
def edit
@garden = Garden.find(params[:id])
end
# POST /gardens
# POST /gardens.json
def create
params[:garden][:owner_id] = current_member.id
@garden = Garden.new(garden_params)
@garden.owner_id = current_member.id
respond_to do |format|
if @garden.save
format.html { redirect_to @garden, notice: 'Garden was successfully created.' }
format.html { redirect_to @garden, notice: I18n.t('gardens.created') }
format.json { render json: @garden, status: :created, location: @garden }
expire_fragment("homepage_stats")
else
@@ -65,11 +62,9 @@ class GardensController < ApplicationController
# PUT /gardens/1
# PUT /gardens/1.json
def update
@garden = Garden.find(params[:id])
respond_to do |format|
if @garden.update(garden_params)
format.html { redirect_to @garden, notice: 'Garden was successfully updated.' }
format.html { redirect_to @garden, notice: I18n.t('gardens.updated') }
format.json { head :no_content }
else
format.html { render action: "edit" }
@@ -81,13 +76,12 @@ class GardensController < ApplicationController
# DELETE /gardens/1
# DELETE /gardens/1.json
def destroy
@garden = Garden.find(params[:id])
@garden.destroy
expire_fragment("homepage_stats")
respond_to do |format|
format.html do
redirect_to gardens_by_owner_path(owner: @garden.owner), notice: 'Garden was successfully deleted.'
redirect_to gardens_by_owner_path(owner: @garden.owner), notice: I18n.t('gardens.deleted')
end
format.json { head :no_content }
end

View File

@@ -1,12 +1,12 @@
class HarvestsController < ApplicationController
before_filter :authenticate_member!, except: [:index, :show]
before_action :authenticate_member!, except: [:index, :show]
load_and_authorize_resource
# GET /harvests
# GET /harvests.json
def index
@owner = Member.find_by_slug(params[:owner])
@crop = Crop.find_by_slug(params[:crop])
@owner = Member.find_by(slug: params[:owner])
@crop = Crop.find_by(slug: params[:crop])
@harvests = if @owner
@owner.harvests.includes(:owner, :crop)
elsif @crop
@@ -26,13 +26,18 @@ class HarvestsController < ApplicationController
end
end
def show
@planting = @harvest.planting if @harvest.planting_id
end
# GET /harvests/new
# GET /harvests/new.json
def new
@harvest = Harvest.new('harvested_at' => Date.today)
@planting = Planting.find_by(slug: params[:planting_id]) if params[:planting_id]
# using find_by_id here because it returns nil, unlike find
@crop = Crop.find_by_id(params[:crop_id]) || Crop.new
@crop = Crop.find_or_initialize_by(id: params[:crop_id])
respond_to do |format|
format.html # new.html.erb
@@ -42,19 +47,17 @@ class HarvestsController < ApplicationController
# GET /harvests/1/edit
def edit
@harvest = Harvest.find(params[:id])
@planting = @harvest.planting if @harvest.planting_id
end
# POST /harvests
# POST /harvests.json
def create
params[:harvest][:owner_id] = current_member.id
params[:harvested_at] = parse_date(params[:harvested_at])
@harvest = Harvest.new(harvest_params)
@harvest.crop_id = @harvest.planting.crop_id if @harvest.planting_id
respond_to do |format|
if @harvest.save
format.html { redirect_to @harvest, notice: 'Harvest was successfully created.' }
format.html { redirect_to @harvest, notice: I18n.t('harvests.created') }
format.json { render json: @harvest, status: :created, location: @harvest }
else
format.html { render action: "new" }
@@ -66,11 +69,9 @@ class HarvestsController < ApplicationController
# PUT /harvests/1
# PUT /harvests/1.json
def update
@harvest = Harvest.find(params[:id])
respond_to do |format|
if @harvest.update(harvest_params)
format.html { redirect_to @harvest, notice: 'Harvest was successfully updated.' }
format.html { redirect_to @harvest, notice: I18n.t('harvests.updated') }
format.json { head :no_content }
else
format.html { render action: "edit" }
@@ -82,7 +83,6 @@ class HarvestsController < ApplicationController
# DELETE /harvests/1
# DELETE /harvests/1.json
def destroy
@harvest = Harvest.find(params[:id])
@harvest.destroy
respond_to do |format|
@@ -94,7 +94,10 @@ class HarvestsController < ApplicationController
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, :si_weight)
params.require(:harvest)
.permit(:planting_id, :crop_id, :harvested_at, :description,
:quantity, :unit, :weight_quantity, :weight_unit,
:plant_part_id, :slug, :si_weight)
.merge(owner_id: current_member.id)
end
end

View File

@@ -1,6 +1,5 @@
class MembersController < ApplicationController
load_and_authorize_resource
load_and_authorize_resource except: [:finish_signup, :unsubscribe, :view_follows, :view_followers, :show]
skip_authorize_resource only: [:nearby, :unsubscribe, :finish_signup]
after_action :expire_cache_fragments, only: :create
@@ -17,7 +16,9 @@ class MembersController < ApplicationController
format.html # index.html.haml
format.json {
render json: @members.to_json(only: [
:id, :login_name, :slug, :bio, :created_at, :location, :latitude, :longitude
:id, :login_name,
:slug, :bio, :created_at,
:location, :latitude, :longitude
])
}
end
@@ -38,7 +39,9 @@ class MembersController < ApplicationController
format.html # show.html.haml
format.json {
render json: @member.to_json(only: [
:id, :login_name, :bio, :created_at, :slug, :location, :latitude, :longitude
:id, :login_name, :bio,
:created_at, :slug, :location,
:latitude, :longitude
])
}
format.rss { render(
@@ -64,32 +67,30 @@ class MembersController < ApplicationController
}
def unsubscribe
begin
verifier = ActiveSupport::MessageVerifier.new(ENV['RAILS_SECRET_TOKEN'])
decrypted_message = verifier.verify(params[:message])
verifier = ActiveSupport::MessageVerifier.new(ENV['RAILS_SECRET_TOKEN'])
decrypted_message = verifier.verify(params[:message])
@member = Member.find(decrypted_message[:member_id])
@type = decrypted_message[:type]
@member.update(@type => false)
@member = Member.find(decrypted_message[:member_id])
@type = decrypted_message[:type]
@member.update(@type => false)
flash.now[:notice] = "You have been unsubscribed from #{EMAIL_TYPE_STRING[@type]} emails."
flash.now[:notice] = I18n.t('members.unsubscribed', email_type: EMAIL_TYPE_STRING[@type])
rescue ActiveSupport::MessageVerifier::InvalidSignature
flash.now[:alert] = "We're sorry, there was an error updating your settings."
end
rescue ActiveSupport::MessageVerifier::InvalidSignature
flash.now[:alert] = I18n.t('members.unsubscribe.error')
end
def finish_signup
@member = current_member
if request.patch? && params[:member]
if @member.update(member_params)
@member.skip_reconfirmation!
bypass_sign_in(@member)
redirect_to root_path, notice: 'Welcome.'
else
flash[:alert] = 'Failed to complete signup'
@show_errors = true
end
return unless request.patch? && params[:member]
if @member.update(member_params)
@member.skip_reconfirmation!
bypass_sign_in(@member)
redirect_to root_path, notice: I18n.t('members.welcome')
else
flash[:alert] = I18n.t('members.signup.error')
@show_errors = true
end
end

View File

@@ -1,11 +1,11 @@
class NotificationsController < ApplicationController
include NotificationsHelper
before_filter :authenticate_member!
before_action :authenticate_member!
load_and_authorize_resource
# GET /notifications
def index
@notifications = Notification.where(recipient_id: current_member).page(params[:page])
@notifications = Notification.by_recipient(current_member).page(params[:page])
respond_to do |format|
format.html # index.html.erb
@@ -14,7 +14,6 @@ class NotificationsController < ApplicationController
# GET /notifications/1
def show
@notification = Notification.find(params[:id])
@notification.read = true
@notification.save
@reply_link = reply_link(@notification)
@@ -28,7 +27,7 @@ class NotificationsController < ApplicationController
def new
@notification = Notification.new
@recipient = Member.find_by_id(params[:recipient_id])
@recipient = Member.find_by(id: params[:recipient_id])
@subject = params[:subject] || ""
respond_to do |format|
@@ -54,7 +53,6 @@ class NotificationsController < ApplicationController
# DELETE /notifications/1
def destroy
@notification = Notification.find(params[:id])
@notification.destroy
respond_to do |format|
@@ -66,7 +64,7 @@ class NotificationsController < ApplicationController
def create
params[:notification][:sender_id] = current_member.id
@notification = Notification.new(notification_params)
@recipient = Member.find_by_id(params[:notification][:recipient_id])
@recipient = Member.find_by(id: params[:notification][:recipient_id])
respond_to do |format|
if @notification.save

View File

@@ -1,5 +1,5 @@
class OrderItemsController < ApplicationController
before_filter :authenticate_member!
before_action :authenticate_member!
load_and_authorize_resource
# POST /order_items

View File

@@ -1,10 +1,10 @@
class OrdersController < ApplicationController
before_filter :authenticate_member!
before_action :authenticate_member!
load_and_authorize_resource
# GET /orders
def index
@orders = Order.where(member_id: current_member.id)
@orders = Order.by_member(current_member)
respond_to do |format|
format.html # index.html.erb
@@ -13,8 +13,6 @@ class OrdersController < ApplicationController
# GET /orders/1
def show
@order = Order.find(params[:id])
respond_to do |format|
format.html # show.html.erb
end
@@ -31,8 +29,6 @@ class OrdersController < ApplicationController
# checkout with PayPal
def checkout
@order = Order.find(params[:id])
respond_to do |format|
if @order.update_attributes(referral_code: params[:referral_code])
response = EXPRESS_GATEWAY.setup_purchase(
@@ -52,8 +48,6 @@ class OrdersController < ApplicationController
end
def complete
@order = Order.find(params[:id])
if (params[:token] && params['PayerID'])
purchase = EXPRESS_GATEWAY.purchase(
@order.total,
@@ -80,7 +74,6 @@ class OrdersController < ApplicationController
end
def cancel
@order = Order.find(params[:id])
respond_to do |format|
format.html { redirect_to shop_url, notice: 'Order was cancelled.' }
end
@@ -88,7 +81,6 @@ class OrdersController < ApplicationController
# DELETE /orders/1
def destroy
@order = Order.find(params[:id])
@order.destroy
respond_to do |format|

View File

@@ -41,7 +41,6 @@ class PhotosController < ApplicationController
# GET /photos/1/edit
def edit
@photo = Photo.find(params[:id])
end
# POST /photos
@@ -64,8 +63,6 @@ class PhotosController < ApplicationController
# PUT /photos/1
# PUT /photos/1.json
def update
@photo = Photo.find(params[:id])
respond_to do |format|
if @photo.update(photo_params)
format.html { redirect_to @photo, notice: 'Photo was successfully updated.' }
@@ -80,7 +77,6 @@ class PhotosController < ApplicationController
# DELETE /photos/1
# DELETE /photos/1.json
def destroy
@photo = Photo.find(params[:id])
@photo.destroy
flash[:alert] = "Photo successfully deleted."
@@ -113,36 +109,17 @@ class PhotosController < ApplicationController
@photo
end
def which_collection?
case params[:type]
when "garden" then @photo.gardens
when "harvest" then @photo.harvests
when "planting" then @photo.plantings
else raise "Invalid type"
end
end
def add_photo_to_collection
collection = which_collection?
raise "Missing or invalid type provided" unless Growstuff::Constants::PhotoModels.types.include?(params[:type])
raise "No item id provided" unless item_id?
collection = Growstuff::Constants::PhotoModels.get_relation(@photo, params[:type])
unless collection && item_id?
flash[:alert] = "Missing or invalid type or id parameter"
return
end
item_class = Growstuff::Constants::PhotoModels.get_item(params[:type])
item = item_class.find_by!(id: params[:id], owner_id: current_member.id)
raise "Could not find this item owned by you" unless item
item = find_item_for_photo!
collection << item unless collection.include?(item)
rescue
flash[:alert] = "Could not find this item owned by you"
end
def find_item_for_photo!
item_class = case params[:type]
when "garden" then Garden
when "harvest" then Harvest
when "planting" then Planting
else raise "Invalid type"
end
item_class.find_by!(id: params[:id], owner_id: current_member.id)
rescue => e
flash[:alert] = e.message
end
end

View File

@@ -15,8 +15,6 @@ class PlantPartsController < ApplicationController
# GET /plant_parts/1
# GET /plant_parts/1.json
def show
@plant_part = PlantPart.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: @plant_part }
@@ -36,7 +34,6 @@ class PlantPartsController < ApplicationController
# GET /plant_parts/1/edit
def edit
@plant_part = PlantPart.find(params[:id])
end
# POST /plant_parts
@@ -58,8 +55,6 @@ class PlantPartsController < ApplicationController
# PUT /plant_parts/1
# PUT /plant_parts/1.json
def update
@plant_part = PlantPart.find(params[:id])
respond_to do |format|
if @plant_part.update(plant_part_params)
format.html { redirect_to @plant_part, notice: 'Plant part was successfully updated.' }
@@ -74,7 +69,6 @@ class PlantPartsController < ApplicationController
# DELETE /plant_parts/1
# DELETE /plant_parts/1.json
def destroy
@plant_part = PlantPart.find(params[:id])
@plant_part.destroy
respond_to do |format|

View File

@@ -1,19 +1,14 @@
class PlantingsController < ApplicationController
before_filter :authenticate_member!, except: [:index, :show]
before_action :authenticate_member!, except: [:index, :show]
load_and_authorize_resource
# GET /plantings
# GET /plantings.json
def index
@owner = Member.find_by_slug(params[:owner])
@crop = Crop.find_by_slug(params[:crop])
@plantings = if @owner
@owner.plantings.includes(:owner, :crop, :garden).paginate(page: params[:page])
elsif @crop
@crop.plantings.includes(:owner, :crop, :garden).paginate(page: params[:page])
else
Planting.includes(:owner, :crop, :garden).paginate(page: params[:page])
end
@owner = Member.find_by(slug: params[:owner]) if params[:owner]
@crop = Crop.find_by(slug: params[:crop]) if params[:crop]
@show_all = params[:all] == '1'
@plantings = plantings
respond_to do |format|
format.html { @plantings = @plantings.paginate(page: params[:page]) }
@@ -41,11 +36,11 @@ class PlantingsController < ApplicationController
# GET /plantings/new
# GET /plantings/new.json
def new
@planting = Planting.new('planted_at' => Date.today)
@planting = Planting.new('planted_at' => Time.zone.today)
# using find_by_id here because it returns nil, unlike find
@crop = Crop.find_by_id(params[:crop_id]) || Crop.new
@garden = Garden.find_by_id(params[:garden_id]) || Garden.new
@crop = Crop.find_by(id: params[:crop_id]) || Crop.new
@garden = Garden.find_by(id: params[:garden_id]) || Garden.new
respond_to do |format|
format.html # new.html.erb
@@ -55,8 +50,6 @@ class PlantingsController < ApplicationController
# GET /plantings/1/edit
def edit
@planting = Planting.find(params[:id])
# the following are needed to display the form but aren't used
@crop = Crop.new
@garden = Garden.new
@@ -86,7 +79,6 @@ class PlantingsController < ApplicationController
# PUT /plantings/1
# PUT /plantings/1.json
def update
@planting = Planting.find(params[:id])
params[:planted_at] = parse_date(params[:planted_at])
respond_to do |format|
@@ -105,7 +97,6 @@ class PlantingsController < ApplicationController
# DELETE /plantings/1
# DELETE /plantings/1.json
def destroy
@planting = Planting.find(params[:id])
@garden = @planting.garden
@planting.destroy
expire_fragment("homepage_stats")
@@ -131,4 +122,18 @@ class PlantingsController < ApplicationController
(planting.finished_at - planting.planted_at).to_i
end
end
def plantings
@plantings = if @owner
@owner.plantings
elsif @crop
@crop.plantings
else
Planting
end
@plantings = @plantings.current unless @show_all
@plantings = @plantings.includes(:owner, :crop, :garden).order(:created_at).paginate(page: params[:page])
@plantings
end
end

View File

@@ -1,16 +1,16 @@
class PostsController < ApplicationController
before_filter :authenticate_member!, except: [:index, :show]
before_action :authenticate_member!, except: [:index, :show]
load_and_authorize_resource
# GET /posts
# GET /posts.json
def index
@author = Member.find_by_slug(params[:author])
@author = Member.find_by(slug: params[:author])
@posts = if @author
@author.posts.includes(:author, { comments: :author }).paginate(page: params[:page])
@author.posts.includes(:author, comments: :author).paginate(page: params[:page])
else
Post.includes(:author, { comments: :author }).paginate(page: params[:page])
Post.includes(:author, comments: :author).paginate(page: params[:page])
end
respond_to do |format|
@@ -23,7 +23,7 @@ class PostsController < ApplicationController
# GET /posts/1
# GET /posts/1.json
def show
@post = Post.includes(:author, { comments: :author }).find(params[:id])
@post = Post.includes(:author, comments: :author).find(params[:id])
respond_to do |format|
format.html # show.html.haml
@@ -39,7 +39,7 @@ class PostsController < ApplicationController
# GET /posts/new.json
def new
@post = Post.new
@forum = Forum.find_by_id(params[:forum_id])
@forum = Forum.find_by(id: params[:forum_id])
respond_to do |format|
format.html # new.html.haml
@@ -49,7 +49,6 @@ class PostsController < ApplicationController
# GET /posts/1/edit
def edit
@post = Post.find(params[:id])
end
# POST /posts
@@ -72,8 +71,6 @@ class PostsController < ApplicationController
# PUT /posts/1
# PUT /posts/1.json
def update
@post = Post.find(params[:id])
respond_to do |format|
if @post.update(post_params)
format.html { redirect_to @post, notice: 'Post was successfully updated.' }
@@ -88,7 +85,6 @@ class PostsController < ApplicationController
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
@post = Post.find(params[:id])
@post.destroy
respond_to do |format|

View File

@@ -1,5 +1,5 @@
class ProductsController < ApplicationController
before_filter :authenticate_member!
before_action :authenticate_member!
load_and_authorize_resource
# GET /products
@@ -13,8 +13,6 @@ class ProductsController < ApplicationController
# GET /products/1
def show
@product = Product.find(params[:id])
respond_to do |format|
format.html # show.html.erb
end
@@ -31,7 +29,6 @@ class ProductsController < ApplicationController
# GET /products/1/edit
def edit
@product = Product.find(params[:id])
end
# POST /products
@@ -49,8 +46,6 @@ class ProductsController < ApplicationController
# PUT /products/1
def update
@product = Product.find(params[:id])
respond_to do |format|
if @product.update(product_params)
format.html { redirect_to @product, notice: 'Product was successfully updated.' }
@@ -62,7 +57,6 @@ class ProductsController < ApplicationController
# DELETE /products/1
def destroy
@product = Product.find(params[:id])
@product.destroy
respond_to do |format|

View File

@@ -1,5 +1,5 @@
class RolesController < ApplicationController
before_filter :authenticate_member!
before_action :authenticate_member!
load_and_authorize_resource
# GET /roles
@@ -13,8 +13,6 @@ class RolesController < ApplicationController
# GET /roles/1
def show
@role = Role.find(params[:id])
respond_to do |format|
format.html # show.html.erb
end
@@ -31,7 +29,6 @@ class RolesController < ApplicationController
# GET /roles/1/edit
def edit
@role = Role.find(params[:id])
end
# POST /roles
@@ -49,8 +46,6 @@ class RolesController < ApplicationController
# PUT /roles/1
def update
@role = Role.find(params[:id])
respond_to do |format|
if @role.update(role_params)
format.html { redirect_to @role, notice: 'Role was successfully updated.' }
@@ -62,7 +57,6 @@ class RolesController < ApplicationController
# DELETE /roles/1
def destroy
@role = Role.find(params[:id])
@role.destroy
respond_to do |format|

View File

@@ -1,5 +1,5 @@
class ScientificNamesController < ApplicationController
before_filter :authenticate_member!, except: [:index, :show]
before_action :authenticate_member!, except: [:index, :show]
load_and_authorize_resource
# GET /scientific_names
@@ -16,8 +16,6 @@ class ScientificNamesController < ApplicationController
# GET /scientific_names/1
# GET /scientific_names/1.json
def show
@scientific_name = ScientificName.find(params[:id])
respond_to do |format|
format.html # show.html.haml
format.json { render json: @scientific_name }
@@ -28,7 +26,7 @@ class ScientificNamesController < ApplicationController
# GET /scientific_names/new.json
def new
@scientific_name = ScientificName.new
@crop = Crop.find_by_id(params[:crop_id]) || Crop.new
@crop = Crop.find_or_initialize_by(id: params[:crop_id])
respond_to do |format|
format.html # new.html.haml
@@ -38,7 +36,6 @@ class ScientificNamesController < ApplicationController
# GET /scientific_names/1/edit
def edit
@scientific_name = ScientificName.find(params[:id])
end
# POST /scientific_names
@@ -61,8 +58,6 @@ class ScientificNamesController < ApplicationController
# PUT /scientific_names/1
# PUT /scientific_names/1.json
def update
@scientific_name = ScientificName.find(params[:id])
respond_to do |format|
if @scientific_name.update(scientific_name_params)
format.html { redirect_to @scientific_name.crop, notice: 'Scientific name was successfully updated.' }
@@ -77,7 +72,6 @@ class ScientificNamesController < ApplicationController
# DELETE /scientific_names/1
# DELETE /scientific_names/1.json
def destroy
@scientific_name = ScientificName.find(params[:id])
@crop = @scientific_name.crop
@scientific_name.destroy

View File

@@ -1,12 +1,12 @@
class SeedsController < ApplicationController
before_filter :authenticate_member!, except: [:index, :show]
before_action :authenticate_member!, except: [:index, :show]
load_and_authorize_resource
# GET /seeds
# GET /seeds.json
def index
@owner = Member.find_by_slug(params[:owner])
@crop = Crop.find_by_slug(params[:crop])
@owner = Member.find_by(slug: params[:owner])
@crop = Crop.find_by(slug: params[:crop])
@seeds = if @owner
@owner.seeds.includes(:owner, :crop).paginate(page: params[:page])
elsif @crop
@@ -35,8 +35,6 @@ class SeedsController < ApplicationController
# GET /seeds/1
# GET /seeds/1.json
def show
@seed = Seed.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: @seed }
@@ -49,7 +47,7 @@ class SeedsController < ApplicationController
@seed = Seed.new
# using find_by_id here because it returns nil, unlike find
@crop = Crop.find_by_id(params[:crop_id]) || Crop.new
@crop = Crop.find_or_initialize_by(id: params[:crop_id])
respond_to do |format|
format.html # new.html.erb
@@ -59,7 +57,6 @@ class SeedsController < ApplicationController
# GET /seeds/1/edit
def edit
@seed = Seed.find(params[:id])
end
# POST /seeds
@@ -82,8 +79,6 @@ class SeedsController < ApplicationController
# PUT /seeds/1
# PUT /seeds/1.json
def update
@seed = Seed.find(params[:id])
respond_to do |format|
if @seed.update(seed_params)
format.html { redirect_to @seed, notice: 'Seed was successfully updated.' }
@@ -98,7 +93,6 @@ class SeedsController < ApplicationController
# DELETE /seeds/1
# DELETE /seeds/1.json
def destroy
@seed = Seed.find(params[:id])
@seed.destroy
respond_to do |format|

View File

@@ -3,7 +3,7 @@ class SessionsController < Devise::SessionsController
def create
super do |resource|
if Crop.pending_approval.present? && current_member.has_role?(:crop_wrangler)
if Crop.pending_approval.present? && current_member.role?(:crop_wrangler)
flash[:alert] = "There are crops waiting to be wrangled."
end
end

View File

@@ -1,17 +1,16 @@
module ApplicationHelper
def price_in_dollars(price)
return sprintf('%.2f', price / 100.0)
sprintf('%.2f', price / 100.0)
end
# 999 cents becomes 9.99 AUD -- for products/orders/etc
def price_with_currency(price)
return sprintf('%.2f %s', price / 100.0,
Growstuff::Application.config.currency)
sprintf('%.2f %s', price / 100.0, Growstuff::Application.config.currency)
end
def parse_date(str)
str ||= '' # Date.parse barfs on nil
return str == '' ? nil : Date.parse(str)
str == '' ? nil : Date.parse(str)
end
def forex_link(price)
@@ -71,10 +70,8 @@ module ApplicationHelper
return uri.to_s
end
Gravatar.new(member.email).image_url({
size: size,
default: :identicon
})
Gravatar.new(member.email).image_url(size: size,
default: :identicon)
end
# Returns a string with the quantity and the right pluralization for a

View File

@@ -9,6 +9,10 @@ module GardensHelper
end
end
def display_garden_name(garden)
truncate(garden.name, length: 50, separator: ' ', omission: '... ')
end
def display_garden_plantings(plantings)
if plantings.blank?
"None"

View File

@@ -3,44 +3,32 @@ module HarvestsHelper
human_quantity = display_human_quantity(harvest)
weight = display_weight(harvest)
if human_quantity && weight
return "#{human_quantity}, weighing #{weight}"
elsif human_quantity
return human_quantity
elsif weight
return weight
else
return 'not specified'
end
return "#{human_quantity}, weighing #{weight}" if human_quantity && weight
return human_quantity if human_quantity
return weight if weight
'not specified'
end
def display_human_quantity(harvest)
if !harvest.quantity.blank? && harvest.quantity > 0
if harvest.unit == 'individual' # just the number
number_to_human(harvest.quantity, strip_insignificant_zeros: true)
elsif !harvest.unit.blank? # pluralize anything else
return pluralize(number_to_human(harvest.quantity, strip_insignificant_zeros: true), harvest.unit)
else
return "#{number_to_human(harvest.quantity, strip_insignificant_zeros: true)} #{harvest.unit}"
end
return unless harvest.quantity.present? && harvest.quantity > 0
if harvest.unit == 'individual' # just the number
number_to_human(harvest.quantity, strip_insignificant_zeros: true)
elsif !harvest.unit.blank? # pluralize anything else
pluralize(number_to_human(harvest.quantity, strip_insignificant_zeros: true), harvest.unit)
else
return nil
"#{number_to_human(harvest.quantity, strip_insignificant_zeros: true)} #{harvest.unit}"
end
end
def display_weight(harvest)
if !harvest.weight_quantity.blank? && harvest.weight_quantity > 0
return "#{number_to_human(harvest.weight_quantity, strip_insignificant_zeros: true)} #{harvest.weight_unit}"
else
return nil
end
return if harvest.weight_quantity.blank? || harvest.weight_quantity <= 0
"#{number_to_human(harvest.weight_quantity, strip_insignificant_zeros: true)} #{harvest.weight_unit}"
end
def display_harvest_description(harvest)
if harvest.description.empty?
"No description provided."
else
harvest.description
end
return "No description provided." if harvest.description.empty?
harvest.description
end
end

View File

@@ -1,13 +1,13 @@
module PlantingsHelper
def display_days_before_maturity(planting)
if planting.finished?
0
"0"
elsif !planting.finished_at.nil?
((p = planting.finished_at - DateTime.now).to_i) <= 0 ? 0 : p.to_i
((p = planting.finished_at - Date.current).to_i) <= 0 ? "0" : p.to_i.to_s
elsif planting.planted_at.nil? || planting.days_before_maturity.nil?
"unknown"
else
((p = (planting.planted_at + planting.days_before_maturity) - DateTime.now).to_i <= 0) ? 0 : p.to_i
((p = (planting.planted_at + planting.days_before_maturity) - Date.current).to_i <= 0) ? "0" : p.to_i.to_s
end
end
@@ -31,13 +31,13 @@ module PlantingsHelper
def display_planting(planting)
if planting.quantity.to_i > 0 && planting.planted_from.present?
return "#{planting.owner} planted #{pluralize(planting.quantity, planting.planted_from)}."
"#{planting.owner} planted #{pluralize(planting.quantity, planting.planted_from)}."
elsif planting.quantity.to_i > 0
return "#{planting.owner} planted #{pluralize(planting.quantity, 'unit')}."
"#{planting.owner} planted #{pluralize(planting.quantity, 'unit')}."
elsif planting.planted_from.present?
return "#{planting.owner} planted #{planting.planted_from.pluralize}."
"#{planting.owner} planted #{planting.planted_from.pluralize}."
else
return "#{planting.owner}."
"#{planting.owner}."
end
end
end

View File

@@ -8,7 +8,7 @@ class Notifier < ActionMailer::Base
"not set - have you created config/application.yml?"
end
return ActiveSupport::MessageVerifier.new(ENV['RAILS_SECRET_TOKEN'])
ActiveSupport::MessageVerifier.new(ENV['RAILS_SECRET_TOKEN'])
end
def notify(notification)
@@ -16,7 +16,8 @@ class Notifier < ActionMailer::Base
@reply_link = reply_link(@notification)
# Encrypting
@signed_message = verifier.generate ({ member_id: @notification.recipient.id, type: :send_notification_email })
message = { member_id: @notification.recipient.id, type: :send_notification_email }
@signed_message = verifier.generate(message)
mail(to: @notification.recipient.email,
subject: @notification.subject)
@@ -29,12 +30,10 @@ class Notifier < ActionMailer::Base
@harvests = @member.harvests.first(5)
# Encrypting
@signed_message = verifier.generate ({ member_id: @member.id, type: :send_planting_reminder })
message = { member_id: @member.id, type: :send_planting_reminder }
@signed_message = verifier.generate(message)
if @member.send_planting_reminder
mail(to: @member.email,
subject: "What have you planted lately?")
end
mail(to: @member.email, subject: "What have you planted lately?") if @member.send_planting_reminder
end
def new_crop_request(member, request)

View File

@@ -1,7 +1,7 @@
class Ability
include CanCan::Ability
def initialize(member)
def initialize(member) # rubocop:disable Metrics/AbcSize
# See the wiki for details: https://github.com/ryanb/cancan/wiki/Defining-Abilities
# everyone can do these things, even non-logged in
@@ -36,110 +36,109 @@ class Ability
an.crop.approved?
end
if member
# members can see even rejected or pending crops if they requested it
can :read, Crop, requester_id: member.id
return unless member
# managing your own user settings
can :update, Member, id: member.id
# members can see even rejected or pending crops if they requested it
can :read, Crop, requester_id: member.id
# can read/delete notifications that were sent to them
can :read, Notification, recipient_id: member.id
can :destroy, Notification, recipient_id: member.id
can :reply, Notification, recipient_id: member.id
# can send a private message to anyone but themselves
# note: sadly, we can't test for this from the view, but it works
# for the model/controller
can :create, Notification do |n|
n.recipient_id != member.id
end
# note we don't support update for notifications
# managing your own user settings
can :update, Member, id: member.id
# only crop wranglers can create/edit/destroy crops
if member.has_role? :crop_wrangler
can :wrangle, Crop
can :manage, Crop
can :manage, ScientificName
can :manage, AlternateName
end
# can read/delete notifications that were sent to them
can :read, Notification, recipient_id: member.id
can :destroy, Notification, recipient_id: member.id
can :reply, Notification, recipient_id: member.id
# can send a private message to anyone but themselves
# note: sadly, we can't test for this from the view, but it works
# for the model/controller
can :create, Notification do |n|
n.recipient_id != member.id
end
# note we don't support update for notifications
# any member can create a crop provisionally
can :create, Crop
# only crop wranglers can create/edit/destroy crops
if member.role? :crop_wrangler
can :wrangle, Crop
can :manage, Crop
can :manage, ScientificName
can :manage, AlternateName
end
# can create & destroy their own authentications against other sites.
can :create, Authentication
can :destroy, Authentication, member_id: member.id
# any member can create a crop provisionally
can :create, Crop
# anyone can create a post, or comment on a post,
# but only the author can edit/destroy it.
can :create, Post
can :update, Post, author_id: member.id
can :destroy, Post, author_id: member.id
can :create, Comment
can :update, Comment, author_id: member.id
can :destroy, Comment, author_id: member.id
# can create & destroy their own authentications against other sites.
can :create, Authentication
can :destroy, Authentication, member_id: member.id
# same deal for gardens and plantings
can :create, Garden
can :update, Garden, owner_id: member.id
can :destroy, Garden, owner_id: member.id
# anyone can create a post, or comment on a post,
# but only the author can edit/destroy it.
can :create, Post
can :update, Post, author_id: member.id
can :destroy, Post, author_id: member.id
can :create, Comment
can :update, Comment, author_id: member.id
can :destroy, Comment, author_id: member.id
can :create, Planting
can :update, Planting, garden: { owner_id: member.id }
can :destroy, Planting, garden: { owner_id: member.id }
# same deal for gardens and plantings
can :create, Garden
can :update, Garden, owner_id: member.id
can :destroy, Garden, owner_id: member.id
can :create, Harvest
can :update, Harvest, owner_id: member.id
can :destroy, Harvest, owner_id: member.id
can :create, Planting
can :update, Planting, garden: { owner_id: member.id }
can :destroy, Planting, garden: { owner_id: member.id }
can :create, Photo
can :update, Photo, owner_id: member.id
can :destroy, Photo, owner_id: member.id
can :create, Harvest
can :update, Harvest, owner_id: member.id
can :destroy, Harvest, owner_id: member.id
can :update, Harvest, owner_id: member.id, planting: { owner_id: member.id }
can :destroy, Harvest, owner_id: member.id, planting: { owner_id: member.id }
can :create, Seed
can :update, Seed, owner_id: member.id
can :destroy, Seed, owner_id: member.id
can :create, Photo
can :update, Photo, owner_id: member.id
can :destroy, Photo, owner_id: member.id
# orders/shop/etc
can :create, Order
can :read, Order, member_id: member.id
can :complete, Order, member_id: member.id, completed_at: nil
can :checkout, Order, member_id: member.id, completed_at: nil
can :cancel, Order, member_id: member.id, completed_at: nil
can :destroy, Order, member_id: member.id, completed_at: nil
can :create, Seed
can :update, Seed, owner_id: member.id
can :destroy, Seed, owner_id: member.id
can :create, OrderItem
# for now, let's not let people mess with individual order items
cannot :read, OrderItem, order: { member_id: member.id }
cannot :update, OrderItem, order: { member_id: member.id, completed_at: nil }
cannot :destroy, OrderItem, order: { member_id: member.id, completed_at: nil }
# orders/shop/etc
can :create, Order
can :read, Order, member_id: member.id
can :complete, Order, member_id: member.id, completed_at: nil
can :checkout, Order, member_id: member.id, completed_at: nil
can :cancel, Order, member_id: member.id, completed_at: nil
can :destroy, Order, member_id: member.id, completed_at: nil
# following/unfollowing permissions
can :create, Follow
cannot :create, Follow, followed_id: member.id # can't follow yourself
can :create, OrderItem
# for now, let's not let people mess with individual order items
cannot :read, OrderItem, order: { member_id: member.id }
cannot :update, OrderItem, order: { member_id: member.id, completed_at: nil }
cannot :destroy, OrderItem, order: { member_id: member.id, completed_at: nil }
can :destroy, Follow
cannot :destroy, Follow, followed_id: member.id # can't unfollow yourself
# following/unfollowing permissions
can :create, Follow
cannot :create, Follow, followed_id: member.id # can't follow yourself
if member.has_role? :admin
can :destroy, Follow
cannot :destroy, Follow, followed_id: member.id # can't unfollow yourself
can :read, :all
can :manage, :all
return unless member.role? :admin
# can't change order history, because it's *history*
cannot :create, Order
cannot :complete, Order
cannot :destroy, Order
cannot :manage, OrderItem
can :read, :all
can :manage, :all
# can't delete plant parts if they have harvests associated with them
cannot :destroy, PlantPart
can :destroy, PlantPart do |pp|
pp.harvests.empty?
end
end
# can't change order history, because it's *history*
cannot :create, Order
cannot :complete, Order
cannot :destroy, Order
cannot :manage, OrderItem
# can't delete plant parts if they have harvests associated with them
cannot :destroy, PlantPart
can :destroy, PlantPart do |pp|
pp.harvests.empty?
end
end
end

View File

@@ -9,16 +9,15 @@ class Account < ActiveRecord::Base
before_create do |account|
unless account.account_type
account.account_type = AccountType.find_or_create_by(name:
Growstuff::Application.config.default_account_type
)
Growstuff::Application.config.default_account_type)
end
end
def paid_until_string
if account_type.is_permanent_paid
return "forever"
"forever"
elsif account_type.is_paid
return paid_until.to_s
paid_until.to_s
end
end
end

View File

@@ -6,16 +6,16 @@ class Comment < ActiveRecord::Base
scope :post_order, -> { reorder("created_at ASC") } # for display on post page
after_create do
recipient = self.post.author.id
sender = self.author.id
recipient = post.author.id
sender = author.id
# don't send notifications to yourself
if recipient != sender
Notification.create(
recipient_id: recipient,
sender_id: sender,
subject: "#{self.author} commented on #{self.post.subject}",
body: self.body,
post_id: self.post.id
subject: "#{author} commented on #{post.subject}",
body: body,
post_id: post.id
)
end
end

View File

@@ -0,0 +1,17 @@
require_relative '../../constants/photo_models.rb'
module PhotoCapable
extend ActiveSupport::Concern
included do
has_and_belongs_to_many :photos # rubocop:disable Rails/HasAndBelongsToMany
before_destroy :remove_from_list
end
def remove_from_list
photolist = photos.to_a # save a temp copy of the photo list
photos.clear # clear relationship b/w object and photo
photolist.each(&:destroy_if_unused)
end
end

View File

@@ -1,4 +1,4 @@
class Crop < ActiveRecord::Base # rubocop:disable Metrics/ClassLength
class Crop < ActiveRecord::Base
extend FriendlyId
friendly_id :name, use: [:slugged, :finders]
@@ -18,7 +18,7 @@ class Crop < ActiveRecord::Base # rubocop:disable Metrics/ClassLength
belongs_to :parent, class_name: 'Crop'
has_many :varieties, class_name: 'Crop', foreign_key: 'parent_id'
has_and_belongs_to_many :posts
has_and_belongs_to_many :posts # rubocop:disable Rails/HasAndBelongsToMany
before_destroy { |crop| crop.posts.clear }
default_scope { order("lower(name) asc") }
@@ -42,7 +42,7 @@ class Crop < ActiveRecord::Base # rubocop:disable Metrics/ClassLength
## Wikipedia urls are only necessary when approving a crop
validates :en_wikipedia_url,
format: {
with: /\Ahttps?:\/\/en\.wikipedia\.org\/wiki\/[[:alnum:]%_]+\z/,
with: %r{\Ahttps?:\/\/en\.wikipedia\.org\/wiki\/[[:alnum:]%_\.()-]+\z},
message: 'is not a valid English Wikipedia URL'
},
if: :approved?
@@ -73,8 +73,8 @@ class Crop < ActiveRecord::Base # rubocop:disable Metrics/ClassLength
min_gram: 3,
max_gram: 10,
# token_chars: Elasticsearch will split on characters
# that dont belong to any of these classes
token_chars: ["letter", "digit"]
# that don't belong to any of these classes
token_chars: %w(letter digit)
}
},
analyzer: {
@@ -82,7 +82,7 @@ class Crop < ActiveRecord::Base # rubocop:disable Metrics/ClassLength
tokenizer: "gs_edgeNGram_tokenizer",
filter: ["lowercase"]
}
},
}
} do
mappings dynamic: 'false' do
indexes :id, type: 'long'
@@ -103,21 +103,20 @@ class Crop < ActiveRecord::Base # rubocop:disable Metrics/ClassLength
end
end
def as_indexed_json(options = {})
self.as_json(
def as_indexed_json(_options = {})
as_json(
only: [:id, :name, :approval_status],
include: {
scientific_names: { only: :name },
alternate_names: { only: :name }
})
}
)
end
# update the Elasticsearch index (only if we're using it in this
# environment)
def update_index(name_obj)
if ENV["GROWSTUFF_ELASTICSEARCH"] == "true"
__elasticsearch__.index_document
end
def update_index(_name_obj)
__elasticsearch__.index_document if ENV["GROWSTUFF_ELASTICSEARCH"] == "true"
end
# End Elasticsearch section
@@ -127,9 +126,7 @@ class Crop < ActiveRecord::Base # rubocop:disable Metrics/ClassLength
end
def default_scientific_name
if scientific_names.size > 0
scientific_names.first.name
end
scientific_names.first.name unless scientific_names.empty?
end
# crop.default_photo
@@ -168,11 +165,9 @@ class Crop < ActiveRecord::Base # rubocop:disable Metrics/ClassLength
def popular_plant_parts
popular_plant_parts = Hash.new(0)
harvests.each do |h|
if h.plant_part
popular_plant_parts[h.plant_part] += 1
end
popular_plant_parts[h.plant_part] += 1 if h.plant_part
end
return popular_plant_parts
popular_plant_parts
end
def interesting?
@@ -180,7 +175,7 @@ class Crop < ActiveRecord::Base # rubocop:disable Metrics/ClassLength
min_photos = 3 # needs this many photos to be interesting
return false unless photos.size >= min_photos
return false unless plantings_count >= min_plantings
return true
true
end
def pending?
@@ -196,7 +191,7 @@ class Crop < ActiveRecord::Base # rubocop:disable Metrics/ClassLength
end
def approval_statuses
['rejected', 'pending', 'approved']
%w(rejected pending approved)
end
def reasons_for_rejection
@@ -205,7 +200,7 @@ class Crop < ActiveRecord::Base # rubocop:disable Metrics/ClassLength
# Crop.interesting
# returns a list of interesting crops, for use on the homepage etc
def Crop.interesting
def self.interesting
howmany = 12 # max number to find
interesting_crops = []
Crop.includes(:photos).randomized.each do |c|
@@ -213,7 +208,7 @@ class Crop < ActiveRecord::Base # rubocop:disable Metrics/ClassLength
next unless c.interesting?
interesting_crops.push(c)
end
return interesting_crops
interesting_crops
end
# Crop.create_from_csv(row)
@@ -224,10 +219,10 @@ class Crop < ActiveRecord::Base # rubocop:disable Metrics/ClassLength
# - parent (name, optional)
# - scientific name (optional, can be picked up from parent if it has one)
def Crop.create_from_csv(row)
def self.create_from_csv(row)
name, en_wikipedia_url, parent, scientific_names, alternate_names = row
cropbot = Member.find_by_login_name('cropbot')
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)
@@ -237,7 +232,7 @@ class Crop < ActiveRecord::Base # rubocop:disable Metrics/ClassLength
)
if parent
parent = Crop.find_by_name(parent)
parent = Crop.find_by(name: parent)
if parent
crop.update_attributes(parent_id: parent.id)
else
@@ -252,66 +247,58 @@ class Crop < ActiveRecord::Base # rubocop:disable Metrics/ClassLength
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.name }
names_to_add = scientific_names.split(/,\s*/)
elsif parent && !parent.scientific_names.empty? # pick up from parent
names_to_add = parent.scientific_names.map(&:name)
else
logger.warn("Warning: no scientific name (not even on parent crop) for #{self}")
end
cropbot = Member.find_by_login_name('cropbot')
cropbot = Member.find_by(login_name: 'cropbot')
if names_to_add.size > 0
raise "cropbot account not found: run rake db:seed" unless cropbot
return if names_to_add.empty?
raise "cropbot account not found: run rake db:seed" unless cropbot
add_names_to_list(names_to_add, 'scientific')
end
add_names_to_list(names_to_add, 'scientific')
end
def add_alternate_names_from_csv(alternate_names)
cropbot = Member.find_by_login_name('cropbot')
# i.e. we actually passed something in, which isn't a given
return if alternate_names.blank?
names_to_add = []
if !alternate_names.blank? # i.e. we actually passed something in, which isn't a given
raise "cropbot account not found: run rake db:seed" unless cropbot
names_to_add = alternate_names.split(%r{,\s*})
add_names_to_list(names_to_add, 'alternate')
end
cropbot = Member.find_by!(login_name: 'cropbot')
names_to_add = alternate_names.split(/,\s*/)
add_names_to_list(names_to_add, 'alternate')
rescue
raise "cropbot account not found: run rake db:seed" unless cropbot
end
def rejection_explanation
if reason_for_rejection == "other"
return rejection_notes
else
return reason_for_rejection
end
return rejection_notes if reason_for_rejection == "other"
reason_for_rejection
end
# Crop.search(string)
def self.search(query)
if ENV['GROWSTUFF_ELASTICSEARCH'] == "true"
search_str = query.nil? ? "" : query.downcase
response = __elasticsearch__.search({
# Finds documents which match any field, but uses the _score from
# the best field insead of adding up _score from each field.
query: {
multi_match: {
query: "#{search_str}",
analyzer: "standard",
fields: ["name",
"scientific_names.scientific_name",
"alternate_names.name"]
}
},
filter: {
term: { approval_status: "approved" }
},
size: 50
}
response = __elasticsearch__.search( # Finds documents which match any field, but uses the _score from
# the best field insead of adding up _score from each field.
query: {
multi_match: {
query: search_str.to_s,
analyzer: "standard",
fields: ["name",
"scientific_names.scientific_name",
"alternate_names.name"]
}
},
filter: {
term: { approval_status: "approved" }
},
size: 50
)
return response.records.to_a
response.records.to_a
else
# if we don't have elasticsearch, just do a basic SQL query.
# also, make sure it's an actual array not an activerecord
@@ -322,16 +309,20 @@ class Crop < ActiveRecord::Base # rubocop:disable Metrics/ClassLength
# we want to make sure that exact matches come first, even if not
# using elasticsearch (eg. in development)
exact_match = Crop.approved.find_by_name(query)
exact_match = Crop.approved.find_by(name: query)
if exact_match
matches.delete(exact_match)
matches.unshift(exact_match)
end
return matches
matches
end
end
def self.case_insensitive_name(name)
where(["lower(name) = :value", { value: name.downcase }])
end
private
def add_names_to_list(names_to_add, list_name)
@@ -345,24 +336,22 @@ class Crop < ActiveRecord::Base # rubocop:disable Metrics/ClassLength
end
def create_crop_in_list(list_name, name)
cropbot = Member.find_by_login_name('cropbot')
cropbot = Member.find_by(login_name: 'cropbot')
create_hash = {
creator_id: "#{cropbot.id}",
creator_id: cropbot.id.to_s,
name: name
}
self.send("#{list_name}_names").create(create_hash)
send("#{list_name}_names").create(create_hash)
end
def name_already_exists(list_name, name)
self.send("#{list_name}_names").exists?(name: name)
send("#{list_name}_names").exists?(name: name)
end
def count_uses_of_property(col_name)
data = Hash.new(0)
plantings.each do |p|
if !p.send("#{col_name}").blank?
data[p.send("#{col_name}")] += 1
end
data[p.send(col_name.to_s)] += 1 unless p.send(col_name.to_s).blank?
end
data
end
@@ -371,22 +360,18 @@ class Crop < ActiveRecord::Base # rubocop:disable Metrics/ClassLength
def approval_status_cannot_be_changed_again
previous = previous_changes.include?(:approval_status) ? previous_changes.approval_status : {}
if previous.include?(:rejected) || previous.include?(:approved)
errors.add(:approval_status, "has already been set to #{approval_status}")
end
return unless previous.include?(:rejected) || previous.include?(:approved)
errors.add(:approval_status, "has already been set to #{approval_status}")
end
def must_be_rejected_if_rejected_reasons_present
unless rejected?
if reason_for_rejection.present? || rejection_notes.present?
errors.add(:approval_status, "must be rejected if a reason for rejection is present")
end
end
return if rejected?
return unless reason_for_rejection.present? || rejection_notes.present?
errors.add(:approval_status, "must be rejected if a reason for rejection is present")
end
def must_have_meaningful_reason_for_rejection
if reason_for_rejection == "other" && rejection_notes.blank?
errors.add(:rejection_notes, "must be added if the reason for rejection is \"other\"")
end
return unless reason_for_rejection == "other" && rejection_notes.blank?
errors.add(:rejection_notes, "must be added if the reason for rejection is \"other\"")
end
end

View File

@@ -5,10 +5,10 @@ class Follow < ActiveRecord::Base
after_create do
Notification.create(
recipient_id: self.followed_id,
sender_id: self.follower_id,
subject: "#{self.follower.login_name} is now following you",
body: "#{self.follower.login_name} just followed you on #{ENV["GROWSTUFF_SITE_NAME"]}. "
recipient_id: followed_id,
sender_id: follower_id,
subject: "#{follower.login_name} is now following you",
body: "#{follower.login_name} just followed you on #{ENV['GROWSTUFF_SITE_NAME']}. "
)
end
end

View File

@@ -6,6 +6,6 @@ class Forum < ActiveRecord::Base
belongs_to :owner, class_name: "Member"
def to_s
return name
name
end
end

View File

@@ -1,23 +1,13 @@
class Garden < ActiveRecord::Base
include Geocodable
extend FriendlyId
include Geocodable
include PhotoCapable
friendly_id :garden_slug, use: [:slugged, :finders]
belongs_to :owner, class_name: 'Member', foreign_key: 'owner_id'
has_many :plantings, -> { order(created_at: :desc) }, dependent: :destroy
has_many :crops, through: :plantings
has_and_belongs_to_many :photos
before_destroy do |garden|
photolist = garden.photos.to_a # save a temp copy of the photo list
garden.photos.clear # clear relationship b/w garden and photo
photolist.each do |photo|
photo.destroy_if_unused
end
end
# set up geocoding
geocoded_by :location
after_validation :geocode
@@ -40,7 +30,8 @@ class Garden < ActiveRecord::Base
validates :area,
numericality: {
only_integer: false,
greater_than_or_equal_to: 0 },
greater_than_or_equal_to: 0
},
allow_nil: true
AREA_UNITS_VALUES = {
@@ -48,7 +39,7 @@ class Garden < ActiveRecord::Base
"square feet" => "square foot",
"hectares" => "hectare",
"acres" => "acre"
}
}.freeze
validates :area_unit, inclusion: { in: AREA_UNITS_VALUES.values,
message: "%{value} is not a valid area unit" },
allow_nil: true,
@@ -57,16 +48,12 @@ class Garden < ActiveRecord::Base
after_validation :cleanup_area
def cleanup_area
if area == 0
self.area = nil
end
if area.blank?
self.area_unit = nil
end
self.area = nil if area && area.zero?
self.area_unit = nil if area.blank?
end
def garden_slug
"#{owner.login_name}-#{name}".downcase.gsub(' ', '-')
"#{owner.login_name}-#{name}".downcase.tr(' ', '-')
end
# featured plantings returns the most recent 4 plantings for a garden,
@@ -76,13 +63,13 @@ class Garden < ActiveRecord::Base
seen_crops = []
plantings.each do |p|
if (!seen_crops.include?(p.crop))
unless seen_crops.include?(p.crop)
unique_plantings.push(p)
seen_crops.push(p.crop)
end
end
return unique_plantings[0..3]
unique_plantings[0..3]
end
def to_s
@@ -92,15 +79,15 @@ class Garden < ActiveRecord::Base
# When you mark a garden as inactive, all the plantings in it should be
# marked as finished. This automates that.
def mark_inactive_garden_plantings_as_finished
if (active == false)
plantings.current.each do |p|
p.finished = true
p.save
end
return unless active == false
plantings.current.each do |p|
p.finished = true
p.save
end
end
def default_photo
return photos.first
photos.first
end
end

View File

@@ -1,22 +1,13 @@
class Harvest < ActiveRecord::Base
include ActionView::Helpers::NumberHelper
extend FriendlyId
include ActionView::Helpers::NumberHelper
include PhotoCapable
friendly_id :harvest_slug, use: [:slugged, :finders]
belongs_to :crop
belongs_to :owner, class_name: 'Member'
belongs_to :plant_part
has_and_belongs_to_many :photos
before_destroy do |harvest|
photolist = harvest.photos.to_a # save a temp copy of the photo list
harvest.photos.clear # clear relationship b/w harvest and photo
photolist.each do |photo|
photo.destroy_if_unused
end
end
belongs_to :planting
default_scope { order('created_at DESC') }
@@ -29,7 +20,8 @@ class Harvest < ActiveRecord::Base
validates :quantity,
numericality: {
only_integer: false,
greater_than_or_equal_to: 0 },
greater_than_or_equal_to: 0
},
allow_nil: true
UNITS_VALUES = {
@@ -43,7 +35,7 @@ class Harvest < ActiveRecord::Base
"buckets" => "bucket",
"baskets" => "basket",
"bushels" => "bushel"
}
}.freeze
validates :unit, inclusion: { in: UNITS_VALUES.values,
message: "%{value} is not a valid unit" },
allow_nil: true,
@@ -57,7 +49,7 @@ class Harvest < ActiveRecord::Base
"kg" => "kg",
"lb" => "lb",
"oz" => "oz"
}
}.freeze
validates :weight_unit, inclusion: { in: WEIGHT_UNITS_VALUES.values,
message: "%{value} is not a valid unit" },
allow_nil: true,
@@ -70,32 +62,20 @@ class Harvest < ActiveRecord::Base
# we're storing the harvest weight in kilograms in the db too
# to make data manipulation easier
def set_si_weight
if self.weight_unit != nil
weight_string = "#{self.weight_quantity} #{self.weight_unit}"
self.si_weight = Unit.new(weight_string).convert_to("kg").to_s("%0.3f").delete(" kg").to_f
end
return if weight_unit.nil?
weight_string = "#{weight_quantity} #{weight_unit}"
self.si_weight = Unit.new(weight_string).convert_to("kg").to_s("%0.3f").delete(" kg").to_f
end
def cleanup_quantities
if quantity == 0
self.quantity = nil
end
if quantity.blank?
self.unit = nil
end
if weight_quantity == 0
self.weight_quantity = nil
end
if weight_quantity.blank?
self.weight_unit = nil
end
self.quantity = nil if quantity && quantity.zero?
self.unit = nil if quantity.blank?
self.weight_quantity = nil if weight_quantity && weight_quantity.zero?
self.weight_unit = nil if weight_quantity.blank?
end
def harvest_slug
"#{owner.login_name}-#{crop}".downcase.gsub(' ', '-')
"#{owner.login_name}-#{crop}".downcase.tr(' ', '-')
end
# stringify as "beet in Skud's backyard" or similar
@@ -103,34 +83,34 @@ class Harvest < ActiveRecord::Base
# 50 individual apples, weighing 3lb
# 2 buckets of apricots, weighing 10kg
string = ''
if self.quantity
string += "#{number_to_human(self.quantity.to_s, strip_insignificant_zeros: true)} "
string += if self.unit == 'individual'
if quantity
string += "#{number_to_human(quantity.to_s, strip_insignificant_zeros: true)} "
string += if unit == 'individual'
'individual '
elsif self.quantity == 1
"#{self.unit} of "
elsif quantity == 1
"#{unit} of "
else
"#{self.unit.pluralize} of "
"#{unit.pluralize} of "
end
end
string += if self.unit != 'individual' # buckets of apricot*s*
"#{self.crop.name.pluralize}"
elsif self.quantity == 1
"#{self.crop.name}"
string += if unit != 'individual' # buckets of apricot*s*
crop.name.pluralize.to_s
elsif quantity == 1
crop.name.to_s
else
"#{self.crop.name.pluralize}"
crop.name.pluralize.to_s
end
if self.weight_quantity
string += " weighing #{number_to_human(self.weight_quantity, strip_insignificant_zeros: true)}"\
" #{self.weight_unit}"
if weight_quantity
string += " weighing #{number_to_human(weight_quantity, strip_insignificant_zeros: true)}"\
" #{weight_unit}"
end
return string
string
end
def default_photo
return photos.first || crop.default_photo
photos.first || crop.default_photo
end
end

View File

@@ -14,7 +14,7 @@ class Member < ActiveRecord::Base
has_many :seeds, foreign_key: 'owner_id'
has_many :harvests, foreign_key: 'owner_id'
has_and_belongs_to_many :roles
has_and_belongs_to_many :roles # rubocop:disable Rails/HasAndBelongsToMany
has_many :notifications, foreign_key: 'recipient_id'
has_many :sent_notifications, foreign_key: 'sender_id'
@@ -57,8 +57,8 @@ class Member < ActiveRecord::Base
attr_accessor :login
# Requires acceptance of the Terms of Service
validates_acceptance_of :tos_agreement, allow_nil: true,
accept: true
validates :tos_agreement, acceptance: { allow_nil: true,
accept: true }
validates :login_name,
length: {
@@ -91,23 +91,21 @@ class Member < ActiveRecord::Base
# allow login via either login_name or email address
def self.find_first_by_auth_conditions(warden_conditions)
conditions = warden_conditions.dup
if login = conditions.delete(:login)
where(conditions).where(["lower(login_name) = :value OR lower(email) = :value", { value: login.downcase }]).first
else
where(conditions).first
end
login = conditions.delete(:login)
return where(conditions).login_name_or_email(login).first if login
find_by(conditions)
end
def to_s
return login_name
login_name
end
def has_role?(role_sym)
def role?(role_sym)
roles.any? { |r| r.name.gsub(/\s+/, "_").underscore.to_sym == role_sym }
end
def current_order
orders.where(completed_at: nil).first
orders.find_by(completed_at: nil)
end
# when purchasing a product that gives you a paid account, this method
@@ -116,9 +114,7 @@ class Member < ActiveRecord::Base
# called by order.update_account, which loops through all order items
# and does this for each one.
def update_account_after_purchase(product)
if product.account_type
account.account_type = product.account_type
end
account.account_type = product.account_type if product.account_type
if product.paid_months
start_date = account.paid_until || Time.zone.now
account.paid_until = start_date + product.paid_months.months
@@ -126,18 +122,18 @@ class Member < ActiveRecord::Base
account.save
end
def is_paid?
def paid?
if account.account_type.is_permanent_paid
return true
true
elsif account.account_type.is_paid && account.paid_until >= Time.zone.now
return true
true
else
return false
false
end
end
def auth(provider)
return authentications.find_by_provider(provider)
authentications.find_by(provider: provider)
end
# Authenticates against Flickr and returns an object we can use for subsequent api calls
@@ -152,14 +148,13 @@ class Member < ActiveRecord::Base
@flickr.access_secret = flickr_auth.secret
end
end
return @flickr
@flickr
end
# Fetches a collection of photos from Flickr
# Returns a [[page of photos], total] pair.
# Total is needed for pagination.
def flickr_photos(page_num = 1, set = nil)
result = false
result = if set
flickr.photosets.getPhotos(
photoset_id: set,
@@ -173,20 +168,17 @@ class Member < ActiveRecord::Base
per_page: 30
)
end
if result
return [result.photo, result.total]
else
return [[], 0]
end
return [result.photo, result.total] if result
[[], 0]
end
# Returns a hash of Flickr photosets' ids and titles
def flickr_sets
sets = Hash.new
sets = {}
flickr.photosets.getList.each do |p|
sets[p.title] = p.id
end
return sets
sets
end
def interesting?
@@ -194,22 +186,28 @@ class Member < ActiveRecord::Base
# Member.confirmed.located as those are required for
# interestingness, as well.
return true if plantings.present?
return false
false
end
def Member.interesting
def self.login_name_or_email(login)
where(["lower(login_name) = :value OR lower(email) = :value", { value: login.downcase }])
end
def self.case_insensitive_login_name(login)
where(["lower(login_name) = :value", { value: login.downcase }])
end
def self.interesting
howmany = 12 # max number to find
interesting_members = []
Member.confirmed.located.recently_signed_in.each do |m|
break if interesting_members.size == howmany
if m.interesting?
interesting_members.push(m)
end
interesting_members.push(m) if m.interesting?
end
return interesting_members
interesting_members
end
def Member.nearest_to(place)
def self.nearest_to(place)
nearby_members = []
if place
latitude, longitude = Geocoder.coordinates(place, params: { limit: 1 })
@@ -217,7 +215,7 @@ class Member < ActiveRecord::Base
nearby_members = Member.located.sort_by { |x| x.distance_from([latitude, longitude]) }
end
end
return nearby_members
nearby_members
end
def update_newsletter_subscription
@@ -234,31 +232,27 @@ class Member < ActiveRecord::Base
end
end
def newsletter_subscribe(testing = false)
return true if (Rails.env.test? && !testing)
gb = Gibbon::API.new
res = gb.lists.subscribe({
id: Growstuff::Application.config.newsletter_list_id,
email: { email: email },
merge_vars: { login_name: login_name },
double_optin: false # they already confirmed their email with us
})
def newsletter_subscribe(gb = Gibbon::API.new, testing = false)
return true if Rails.env.test? && !testing
gb.lists.subscribe(
id: Growstuff::Application.config.newsletter_list_id,
email: { email: email },
merge_vars: { login_name: login_name },
double_optin: false # they already confirmed their email with us
)
end
def newsletter_unsubscribe(testing = false)
return true if (Rails.env.test? && !testing)
gb = Gibbon::API.new
res = gb.lists.unsubscribe({
id: Growstuff::Application.config.newsletter_list_id,
email: { email: email }
})
def newsletter_unsubscribe(gb = Gibbon::API.new, testing = false)
return true if Rails.env.test? && !testing
gb.lists.unsubscribe(id: Growstuff::Application.config.newsletter_list_id,
email: { email: email })
end
def already_following?(member)
self.follows.exists?(followed_id: member.id)
follows.exists?(followed_id: member.id)
end
def get_follow(member)
self.follows.where(followed_id: member.id).first if already_following?(member)
follows.find_by(followed_id: member.id) if already_following?(member)
end
end

View File

@@ -7,23 +7,20 @@ class Notification < ActiveRecord::Base
default_scope { order('created_at DESC') }
scope :unread, -> { where(read: false) }
scope :by_recipient, ->(recipient) { where(recipient_id: recipient) }
before_create :replace_blank_subject
after_create :send_email
def self.unread_count
self.unread.size
unread.size
end
def replace_blank_subject
if self.subject.nil? or self.subject =~ /^\s*$/
self.subject = "(no subject)"
end
self.subject = "(no subject)" if subject.nil? || subject =~ /^\s*$/
end
def send_email
if self.recipient.send_notification_email
Notifier.notify(self).deliver_later
end
Notifier.notify(self).deliver_later if recipient.send_notification_email
end
end

View File

@@ -12,27 +12,27 @@ class Order < ActiveRecord::Base
before_save :standardize_referral_code
scope :by_member, ->(member) { where(member: member) }
# total price of an order
def total
sum = 0
for i in order_items do
order_items.each do |i|
subtotal = i.price * i.quantity
sum += subtotal
end
return sum
sum
end
# return items in the format ActiveMerchant/PayPal want them
def activemerchant_items
items = []
order_items.each do |i|
items.push({
name: i.product.name,
quantity: i.quantity,
amount: i.price
})
items.push(name: i.product.name,
quantity: i.quantity,
amount: i.price)
end
return items
items
end
# record the paypal details for reference
@@ -40,7 +40,7 @@ class Order < ActiveRecord::Base
self.paypal_express_token = token
details = EXPRESS_GATEWAY.details_for(token)
self.paypal_express_payer_id = details.payer_id
self.save
save
end
# when an order is completed, we update the member's account to mark
@@ -54,42 +54,32 @@ class Order < ActiveRecord::Base
# removes whitespace and forces to uppercase (we're somewhat liberal
# in what we accept, but we clean it up anyway.)
def standardize_referral_code
if referral_code
self.referral_code = referral_code.upcase.gsub /\s/, ''
end
self.referral_code = referral_code.upcase.gsub(/\s/, '') if referral_code
end
# search orders (used by admin/orders)
# usage: Order.search({ :by => 'member', :for => 'Skud' })
# can search by: member, order_id, paypal_token, paypal_payer_id,
def Order.search(args = {})
def self.search(args = {})
if args[:for]
case args[:by]
when "member"
member = Member.find_by_login_name(args[:for])
if member
return member.orders
end
member = Member.find_by(login_name: args[:for])
return member.orders if member
when "order_id"
order = Order.find_by_id(args[:for])
if order
return [order]
end
order = Order.find_by(id: args[:for])
return [order] if order
when "paypal_token"
order = Order.find_by_paypal_express_token(args[:for])
if order
return [order]
end
order = Order.find_by(paypal_express_token: args[:for])
return [order] if order
when "paypal_payer_id"
order = Order.find_by_paypal_express_payer_id(args[:for])
if order
return [order]
end
order = Order.find_by(paypal_express_payer_id: args[:for])
return [order] if order
when "referral_code"
# coerce to uppercase
return Order.where(referral_code: args[:for].upcase)
end
end
return []
[]
end
end

View File

@@ -3,13 +3,10 @@ class OrderItem < ActiveRecord::Base
belongs_to :product
validate :price_must_be_greater_than_minimum
validates_uniqueness_of :order_id, message: "may only have one item."
validates :order_id, uniqueness: { message: "may only have one item." }
def price_must_be_greater_than_minimum
@product = Product.find(product_id)
if price < @product.min_price
errors.add(:price, "must be greater than the product's minimum value")
end
errors.add(:price, "must be greater than the product's minimum value") if price < @product.min_price
end
end

View File

@@ -1,22 +1,25 @@
require_relative '../constants/photo_models.rb'
class Photo < ActiveRecord::Base
belongs_to :owner, class_name: 'Member'
has_and_belongs_to_many :plantings
has_and_belongs_to_many :harvests
has_and_belongs_to_many :gardens
before_destroy do |photo|
photo.plantings.clear
photo.harvests.clear
photo.gardens.clear
Growstuff::Constants::PhotoModels.relations.each do |relation|
has_and_belongs_to_many relation.to_sym # rubocop:disable Rails/HasAndBelongsToMany
end
before_destroy { all_associations.clear }
default_scope { order("created_at desc") }
# remove photos that aren't used by anything
def destroy_if_unused
unless plantings.size > 0 or harvests.size > 0 or gardens.size > 0
self.destroy
def all_associations
associations = []
Growstuff::Constants::PhotoModels.relations.each do |association_name|
associations << send(association_name.to_s).to_a
end
associations.flatten!
end
def destroy_if_unused
destroy if all_associations.empty?
end
# This is split into a side-effect free method and a side-effecting method
@@ -24,9 +27,9 @@ class Photo < ActiveRecord::Base
def flickr_metadata
flickr = owner.flickr
info = flickr.photos.getInfo(photo_id: flickr_photo_id)
licenses = flickr.photos.licenses.getInfo()
licenses = flickr.photos.licenses.getInfo
license = licenses.find { |l| l.id == info.license }
return {
{
title: info.title || "Untitled",
license_name: license.name,
license_url: license.url,
@@ -37,6 +40,6 @@ class Photo < ActiveRecord::Base
end
def set_flickr_metadata
self.update_attributes(flickr_metadata)
update_attributes(flickr_metadata)
end
end

View File

@@ -6,7 +6,7 @@ class PlantPart < ActiveRecord::Base
has_many :crops, -> { uniq }, through: :harvests
def to_s
return name
name
end
# Postgres complains if the ORDER BY clause of a SELECT DISTINCT query is
@@ -18,6 +18,6 @@ class PlantPart < ActiveRecord::Base
# associated to plant parts will not be sorted in the same order as crops
# on the rest of the site.
def crops
return super.reorder('name')
super.reorder('name')
end
end

View File

@@ -1,21 +1,12 @@
class Planting < ActiveRecord::Base
extend FriendlyId
include PhotoCapable
friendly_id :planting_slug, use: [:slugged, :finders]
belongs_to :garden
belongs_to :owner, class_name: 'Member', counter_cache: true
belongs_to :crop, counter_cache: true
has_and_belongs_to_many :photos
before_destroy do |planting|
photolist = planting.photos.to_a # save a temp copy of the photo list
planting.photos.clear # clear relationship b/w planting and photo
photolist.each do |photo|
photo.destroy_if_unused
end
end
has_many :harvests, -> { order(harvested_at: :desc) }, dependent: :destroy
default_scope { order("created_at desc") }
scope :finished, -> { where(finished: true) }
@@ -73,25 +64,33 @@ class Planting < ActiveRecord::Base
end
def planting_slug
"#{owner.login_name}-#{garden}-#{crop}".downcase.gsub(' ', '-')
if garden.present? && crop.present?
"#{owner.login_name}-#{garden.name}-#{crop.name}"
elsif garden.present?
"#{owner.login_name}-#{garden.name}-null"
elsif crop.present?
"#{owner.login_name}-null-#{crop.name}"
else
"#{owner.login_name}-null-null"
end.downcase.gsub(' ', '-')
end
# location = garden owner + garden name, i.e. "Skud's backyard"
def location
return "#{garden.owner.login_name}'s #{garden}"
I18n.t("gardens.location", garden: garden.name, owner: garden.owner.login_name)
end
# stringify as "beet in Skud's backyard" or similar
def to_s
self.crop_name + " in " + self.location
I18n.t('plantings.string', crop: crop.name, garden: garden.name, owner: owner)
end
def default_photo
return photos.first
photos.first
end
def interesting?
return photos.present?
photos.present?
end
def calculate_days_before_maturity(planting, crop)
@@ -146,6 +145,6 @@ class Planting < ActiveRecord::Base
interesting_plantings.push(p)
end
return interesting_plantings
interesting_plantings
end
end

View File

@@ -4,7 +4,7 @@ class Post < ActiveRecord::Base
belongs_to :author, class_name: 'Member'
belongs_to :forum
has_many :comments, dependent: :destroy
has_and_belongs_to_many :crops
has_and_belongs_to_many :crops # rubocop:disable Rails/HasAndBelongsToMany
before_destroy { |post| post.crops.clear }
after_save :update_crops_posts_association
# also has_many notifications, but kinda meaningless to get at them
@@ -12,27 +12,26 @@ class Post < ActiveRecord::Base
after_create do
recipients = []
sender = self.author.id
self.body.scan(Haml::Filters::GrowstuffMarkdown::MEMBER_REGEX) do |m|
sender = author.id
body.scan(Haml::Filters::GrowstuffMarkdown::MEMBER_REGEX) do |_m|
# find member case-insensitively and add to list of recipients
member = Member.where('lower(login_name) = ?', $1.downcase).first
member = Member.case_insensitive_login_name(Regexp.last_match(1)).first
recipients << member if member && !recipients.include?(member)
end
self.body.scan(Haml::Filters::GrowstuffMarkdown::MEMBER_AT_REGEX) do |m|
body.scan(Haml::Filters::GrowstuffMarkdown::MEMBER_AT_REGEX) do |_m|
# find member case-insensitively and add to list of recipients
member = Member.where('lower(login_name) = ?', $1[1..-1].downcase).first
member = Member.case_insensitive_login_name(Regexp.last_match(1)[1..-1]).first
recipients << member if member && !recipients.include?(member)
end
# don't send notifications to yourself
recipients.map { |r| r.id }.each do |recipient|
if recipient != sender
Notification.create(
recipient_id: recipient,
sender_id: sender,
subject: "#{self.author} mentioned you in their post #{self.subject}",
body: self.body,
)
end
recipients.map(&:id).each do |recipient|
next unless recipient != sender
Notification.create(
recipient_id: recipient,
sender_id: sender,
subject: "#{author} mentioned you in their post #{subject}",
body: body
)
end
end
@@ -47,22 +46,22 @@ class Post < ActiveRecord::Base
def author_date_subject
# slugs are created before created_at is set
time = created_at || Time.zone.now
"#{author.login_name} #{time.strftime("%Y%m%d")} #{subject}"
"#{author.login_name} #{time.strftime('%Y%m%d')} #{subject}"
end
def comment_count
self.comments.size
comments.size
end
# return the timestamp of the most recent activity on this post
# i.e. the time of the most recent comment, or of the post itself if
# there are no comments.
def recent_activity
self.comments.present? ? self.comments.reorder('created_at DESC').first.created_at : self.created_at
comments.present? ? comments.reorder('created_at DESC').first.created_at : created_at
end
# return posts sorted by recent activity
def Post.recently_active
def self.recently_active
Post.all.sort do |a, b|
b.recent_activity <=> a.recent_activity
end
@@ -71,13 +70,13 @@ class Post < ActiveRecord::Base
private
def update_crops_posts_association
self.crops.destroy_all
crops.destroy_all
# look for crops mentioned in the post. eg. [tomato](crop)
self.body.scan(Haml::Filters::GrowstuffMarkdown::CROP_REGEX) do |m|
body.scan(Haml::Filters::GrowstuffMarkdown::CROP_REGEX) do |_m|
# find crop case-insensitively
crop = Crop.where('lower(name) = ?', $1.downcase).first
crop = Crop.case_insensitive_name(Regexp.last_match(1)).first
# create association
self.crops << crop if crop && !self.crops.include?(crop)
crops << crop if crop && !crops.include?(crop)
end
end
end

View File

@@ -1,11 +1,12 @@
class Product < ActiveRecord::Base
has_and_belongs_to_many :orders
has_and_belongs_to_many :orders # rubocop:disable Rails/HasAndBelongsToMany
belongs_to :account_type
validates :paid_months,
numericality: {
only_integer: true,
greater_than_or_equal_to: 0 },
greater_than_or_equal_to: 0
},
allow_nil: true
def to_s

View File

@@ -2,7 +2,7 @@ class Role < ActiveRecord::Base
extend FriendlyId
friendly_id :name, use: [:slugged, :finders]
has_and_belongs_to_many :members
has_and_belongs_to_many :members # rubocop:disable Rails/HasAndBelongsToMany
class << self
[:crop_wranglers, :admins].each do |method|

View File

@@ -1,5 +1,6 @@
class Seed < ActiveRecord::Base
extend FriendlyId
include PhotoCapable
friendly_id :seed_slug, use: [:slugged, :finders]
belongs_to :crop
@@ -13,22 +14,25 @@ class Seed < ActiveRecord::Base
validates :quantity,
numericality: {
only_integer: true,
greater_than_or_equal_to: 0 },
greater_than_or_equal_to: 0
},
allow_nil: true
validates :days_until_maturity_min,
numericality: {
only_integer: true,
greater_than_or_equal_to: 0 },
greater_than_or_equal_to: 0
},
allow_nil: true
validates :days_until_maturity_max,
numericality: {
only_integer: true,
greater_than_or_equal_to: 0 },
greater_than_or_equal_to: 0
},
allow_nil: true
scope :tradable, -> { where("tradable_to != 'nowhere'") }
TRADABLE_TO_VALUES = %w(nowhere locally nationally internationally)
TRADABLE_TO_VALUES = %w(nowhere locally nationally internationally).freeze
validates :tradable_to, inclusion: { in: TRADABLE_TO_VALUES,
message: "You may only trade seed nowhere, "\
"locally, nationally, or internationally" },
@@ -39,7 +43,8 @@ class Seed < ActiveRecord::Base
'certified organic',
'non-certified organic',
'conventional/non-organic',
'unknown']
'unknown'
].freeze
validates :organic, inclusion: { in: ORGANIC_VALUES,
message: "You must say whether the seeds "\
"are organic or not, or that you don't know" },
@@ -50,24 +55,25 @@ class Seed < ActiveRecord::Base
'certified GMO-free',
'non-certified GMO-free',
'GMO',
'unknown']
'unknown'
].freeze
validates :gmo, inclusion: { in: GMO_VALUES,
message: "You must say whether the seeds are "\
"genetically modified or not, or that you don't know" },
allow_nil: false,
allow_blank: false
HEIRLOOM_VALUES = %w(heirloom hybrid unknown)
HEIRLOOM_VALUES = %w(heirloom hybrid unknown).freeze
validates :heirloom, inclusion: { in: HEIRLOOM_VALUES,
message: "You must say whether the seeds are heirloom, hybrid, or unknown" },
allow_nil: false,
allow_blank: false
def tradable?
if self.tradable_to == 'nowhere'
return false
if tradable_to == 'nowhere'
false
else
return true
true
end
end
@@ -75,26 +81,28 @@ class Seed < ActiveRecord::Base
# assuming we're passed something that's already known to be tradable
# eg. from Seed.tradable scope
return false if owner.location.blank? # don't want unspecified locations
return true
true
end
# Seed.interesting
# returns a list of interesting seeds, for use on the homepage etc
def Seed.interesting
def self.interesting
howmany = 12 # max number to find
interesting_seeds = []
Seed.tradable.each do |s|
break if interesting_seeds.size == howmany
if s.interesting?
interesting_seeds.push(s)
end
interesting_seeds.push(s) if s.interesting?
end
return interesting_seeds
interesting_seeds
end
def seed_slug
"#{owner.login_name}-#{crop}".downcase.gsub(' ', '-')
"#{owner.login_name}-#{crop}".downcase.tr(' ', '-')
end
def to_s
I18n.t('seeds.string', crop: crop.name, owner: owner)
end
end

View File

@@ -1,7 +1,5 @@
class ApprovedValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
unless record.crop.try(:approved?)
record.errors[attribute] << (options[:message] || 'must be approved')
end
record.errors[attribute] << (options[:message] || 'must be approved') unless record.crop.try(:approved?)
end
end

View File

@@ -1,7 +1,7 @@
.panel.panel-success
.panel-heading
%h3.panel-title
= link_to "#{garden.owner.login_name}'s garden", garden
= link_to display_garden_name(garden), garden
- if can? :edit, garden
%a.pull-right{:href => edit_garden_path(garden), :role => "button", :id => "edit_garden_glyphicon"}
%span.glyphicon.glyphicon-pencil{:title => "Edit"}
@@ -12,7 +12,7 @@
.col-md-8
%dl.dl-horizontal
%dt Name :
%dd= link_to garden.name, garden
%dd= link_to display_garden_name(garden), garden
%dt Location :
%dd
- if garden.location.blank?

View File

@@ -10,13 +10,22 @@
.form-group.required
= f.label :crop, 'What did you harvest?', :class => 'control-label col-md-2'
.col-md-4
= auto_suggest @harvest, :crop, :class => 'form-control col-md-2', :default => @crop
- if @planting
.col-md-8
= link_to @planting.crop.name, planting_path(@planting)
from
= link_to @planting.garden.name, garden_path(@planting.garden)
= f.hidden_field :planting_id, value: @planting.id
- else
.col-md-4
= auto_suggest @harvest, :crop, :class => 'form-control col-md-2', :default => @crop
.col-md-4
= collection_select(:harvest, :plant_part_id, PlantPart.all, :id, :name, { :selected => @harvest.plant_part_id }, { :class => 'form-control', :prompt => 'e.g. fruit', :required => "required" })
%span.help-block.col-md-8
Can't find what you're looking for?
= link_to "Request new crops.", new_crop_path
- unless @planting
%span.help-block.col-md-8
Can't find what you're looking for?
= link_to "Request new crops.", new_crop_path
.form-group
= f.label :harvested_at, 'When?', :class => 'control-label col-md-2'

View File

@@ -24,6 +24,11 @@
%p
%b Harvested:
= @harvest.harvested_at ? @harvest.harvested_at : "not specified"
- if @planting
%p
%b Garden:
= link_to @planting.garden, garden_path(@planting.garden)
%p
%b Quantity:
= display_quantity(@harvest)

View File

@@ -4,7 +4,7 @@
.container
.navbar-header
%button.navbar-toggle(data-target="#navbar-collapse" data-toggle="collapse")
%span.sr-only Toggle Navigation
%span.sr-only= t('.toggle_navigation')
%span.icon-bar
%span.icon-bar
%span.icon-bar
@@ -28,7 +28,7 @@
%ul.nav.navbar-nav.navbar-right
%li.dropdown<
%a.dropdown-toggle{'data-toggle' => 'dropdown', :href => crops_path}
Crops
= t('.crops')
%b.caret
%ul.dropdown-menu
%li= link_to t('.browse_crops'), crops_path
@@ -37,7 +37,7 @@
%li= link_to t('.harvests'), harvests_path
%li.dropdown<
%a.dropdown-toggle{'data-toggle' => 'dropdown', :href => members_path}
Community
= t('.community')
%b.caret
%ul.dropdown-menu
%li= link_to t('.community_map'), places_path
@@ -52,7 +52,7 @@
- if current_member.notifications.unread_count > 0
= t('.your_stuff', unread_count: current_member.notifications.unread_count)
- else
#{current_member.login_name}
= t('.current_memberlogin_name', :current_memberlogin_name => (current_member.login_name))
%b.caret
%ul.dropdown-menu
%li= link_to t('.profile'), member_path(current_member)
@@ -67,19 +67,19 @@
= link_to(t('.inbox_unread', unread_count: current_member.notifications.unread_count), notifications_path)
- else
= link_to(t('.inbox'), notifications_path)
- if current_member.has_role?(:crop_wrangler) || current_member.has_role?(:admin)
- if current_member.role?(:crop_wrangler) || current_member.role?(:admin)
%li{:class => 'divider', :role => 'presentation'}
- if current_member.has_role?(:crop_wrangler)
- if current_member.role?(:crop_wrangler)
%li= link_to t('.crop_wrangling'), wrangle_crops_path
- if current_member.has_role?(:admin)
- if current_member.role?(:admin)
%li= link_to t('.admin'), admin_path
%li= link_to "Sign out", destroy_member_session_path, :method => :delete
%li= link_to t('.sign_out'), destroy_member_session_path, :method => :delete
- else
%li= link_to 'Sign in', new_member_session_path, :id => 'navbar-signin'
%li= link_to 'Sign up', new_member_registration_path, :id => 'navbar-signup'
%li= link_to t('.sign_in'), new_member_session_path, :id => 'navbar-signin'
%li= link_to t('.sign_up'), new_member_registration_path, :id => 'navbar-signup'
- # anchor tag for accessibility link to skip the navigation menu

View File

@@ -16,9 +16,9 @@
%p
%strong Member Roles:
%br
- if member.has_role? :admin
- if member.role? :admin
Administrator
- if member.has_role? :crop_wrangler
- if member.role? :crop_wrangler
Crop Wrangler
- else
Member

View File

@@ -5,7 +5,7 @@
- member.gardens.each do |g|
%li{:class => first_garden ? 'active' : '' }
- first_garden = false
= link_to g.name, "#garden#{g.id}", 'data-toggle' => 'tab'
= link_to display_garden_name(g), "#garden#{g.id}", 'data-toggle' => 'tab'
- if current_member == member
%li.navbar-right
= link_to new_garden_path, class: 'btn' do

View File

@@ -10,7 +10,7 @@
- content_for :buttonbar do
- if can? :update, @member
= link_to 'Edit profile', edit_member_registration_path, :class => 'btn btn-default'
- if @member == current_member && !@member.is_paid?
- if @member == current_member && !@member.paid?
= link_to "Upgrade account", shop_path, :class => 'btn btn-default'
- if can? :create, Notification and current_member != @member
= link_to 'Send message', new_notification_path(:recipient_id => @member.id), :class => 'btn btn-default'

View File

@@ -22,7 +22,7 @@
%strong Referral code:
= @order.referral_code
- if current_member.has_role? :admin
- if current_member.role? :admin
%p
%strong Paypal Express token:
= @order.paypal_express_token

View File

@@ -26,19 +26,17 @@
%p= link_to 'Delete Photo', @photo, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'
.col-md-6
- if @photo.plantings.size > 0 or @photo.harvests.size > 0 or @photo.gardens.size > 0
- unless @photo.plantings.empty? && @photo.harvests.empty? && @photo.gardens.empty? && @photo.seeds.empty?
%p This photo depicts:
%ul
- if @photo.plantings.size > 0
- @photo.plantings.each do |p|
%li= link_to t('.thing_by', thing: Planting.model_name.singular, owner: p.owner), p
- if @photo.harvests.size > 0
- @photo.harvests.each do |h|
%li= link_to t('.thing_by', thing: Harvest.model_name.singular, owner: h.owner), h
- if @photo.gardens.size > 0
- @photo.gardens.each do |g|
%li= link_to t('.thing_by', thing: Garden.model_name.singular, owner: g.owner), g
- @photo.plantings.each do |p|
%li= link_to t('.planting', planting: p.to_s, owner: p.owner.to_s), planting_path(p)
- @photo.harvests.each do |h|
%li= link_to t('.harvest', crop: h.crop.name, owner: h.owner.to_s), harvest_path(h)
- @photo.gardens.each do |g|
%li= link_to t('.garden', garden: g.to_s, owner: g.owner.to_s), garden_path(g)
- @photo.seeds.each do |s|
%li= link_to t('.seed', seed: s.to_s, owner: s.owner.to_s), seed_path(s)
.row
.col-md-12

View File

@@ -8,7 +8,7 @@
in
= succeed "'s" do
= link_to p.garden.owner, p.garden.owner
= link_to p.garden, p.garden
= link_to display_garden_name(p.garden), p.garden
%br/
%small
%i

View File

@@ -0,0 +1,22 @@
- content_for :buttonbar do
- if current_member
= link_to 'My Plantings', plantings_by_owner_path(owner: current_member.slug), class: 'btn btn-default'
- if owner && owner != current_member
= link_to "#{owner.login_name}'s Plantings", plantings_by_owner_path(owner: owner.slug), class: 'btn btn-default'
= link_to "Everyone's plantings", plantings_path, :class => 'btn btn-default'
- if owner
- path = plantings_by_owner_path(owner: @owner.slug, all: show_all ? '' : 1)
- else
- path = plantings_path(all: show_all ? '' : 1)
= link_to path do
= check_box_tag 'active', 'all', show_all
include in-active
- if current_member
- if can? :create, Planting
= link_to 'Plant something', new_planting_path, :class => 'btn btn-primary'
- else
= render :partial => 'shared/signin_signup', :locals => { :to => "track what you've planted" }

View File

@@ -0,0 +1,9 @@
Harvests:
- if planting.harvests
%ul
- planting.harvests.each do |harvest|
%li
= harvest.harvested_at ? harvest.harvested_at : "undated"
= link_to harvest, harvest_path(harvest)
- else
= "none"

View File

@@ -29,6 +29,8 @@
%li= link_to 'Details', planting, :class => 'btn btn-default btn-xs'
- if can? :edit, planting
%li= link_to 'Edit', edit_planting_path(planting), :class => 'btn btn-default btn-xs'
- if can? :create, Harvest
%li= link_to 'Harvest', new_planting_harvest_path(planting), :class => 'btn btn-default btn-xs'
- if ! planting.finished
%li= link_to "Mark as finished", planting_path(planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs append-date'
- if can? :destroy, planting
@@ -42,3 +44,5 @@
.col-xs-12.col-md-8
= render partial: 'plantings/planting_progress', locals: {planting: planting}
.col-xs-12.col-md-8
= render partial: 'plantings/planting_harvest', locals: {planting: planting}

View File

@@ -1,21 +1,10 @@
- content_for :title, @owner ? t('.title.owner_plantings', owner: @owner) : @crop ? t('.title.crop_plantings', crop: @crop.name) : t('.title.default')
= render 'nav', owner: @owner, show_all: @show_all
- if @owner
= link_to "View #{@owner}'s profile >>", member_path(@owner)
%p
- if can? :create, Planting
- if @owner
%p
- if @owner == current_member
= link_to 'Plant something', new_planting_path, :class => 'btn btn-primary'
= link_to "View everyone's plantings", plantings_path, :class => 'btn btn-default'
- else # everyone's plantings
= link_to 'Plant something', new_planting_path, :class => 'btn btn-primary'
- if current_member
= link_to 'View your plantings', plantings_by_owner_path(:owner => current_member.slug), :class => 'btn btn-default'
- else
= render :partial => 'shared/signin_signup', :locals => { :to => "track what you've planted" }
%div.pagination
= page_entries_info @plantings
= will_paginate @plantings

View File

@@ -48,8 +48,8 @@
%dt Finished:
%dd= "#{display_finished(@planting)}"
%p
= render 'planting_progress', planting: @planting
%p= render 'plantings/planting_harvest', planting: @planting
%p= render 'planting_progress', planting: @planting
- if can? :edit, @planting or can? :destroy, @planting
%p
@@ -57,6 +57,8 @@
=link_to 'Edit', edit_planting_path(@planting), :class => 'btn btn-default btn-xs'
- if ! @planting.finished
= link_to "Mark as finished", planting_path(@planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs append-date'
- if can? :create, Harvest
= link_to 'Harvest', new_planting_harvest_path(@planting), :class => 'btn btn-default btn-xs'
- if can? :destroy, @planting
=link_to 'Delete', @planting, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'

View File

@@ -9,5 +9,5 @@
%strong Paid until:
= current_member.account.paid_until_string
- if !current_member.is_paid?
- if !current_member.paid?
= link_to "Upgrade and support #{ENV['GROWSTUFF_SITE_NAME']}", shop_path, :class => 'btn btn-primary'

View File

@@ -19,7 +19,7 @@
source, open data platform supporting home food growers and promoting
sustainable food systems!
- if current_member && current_member.is_paid?
- if current_member && current_member.paid?
%h2 Thank you for supporting Growstuff
%p You currently have a paid membership, and can't buy another one at this time.

View File

@@ -1,5 +1,5 @@
# Require any additional compass plugins here.
# rubocop:disable Lint/UselessAssignment
# Set this to the root of your project when deployed:
http_path = "/"
css_dir = "app/assets/stylesheets"

View File

@@ -1,2 +1,3 @@
# Require any additional compass plugins here.
# rubocop:disable Lint/UselessAssignment
project_type = :rails

View File

@@ -112,17 +112,15 @@ end
OmniAuth.config.test_mode = true
# Fake the omniauth
OmniAuth.config.mock_auth[:facebook] = OmniAuth::AuthHash.new({
provider: 'facebook',
uid: '123545',
info: {
name: "John Testerson",
nickname: 'JohnnyT',
email: 'example.oauth.facebook@example.com',
image: 'http://findicons.com/files/icons/1072/face_avatars/300/i04.png'
},
credentials: {
token: "token",
secret: "donttell"
}
OmniAuth.config.mock_auth[:facebook] = OmniAuth::AuthHash.new(provider: 'facebook',
uid: '123545',
info: {
name: "John Testerson",
nickname: 'JohnnyT',
email: 'example.oauth.facebook@example.com',
image: 'http://findicons.com/files/icons/1072/face_avatars/300/i04.png'
},
credentials: {
token: "token",
secret: "donttell"
})

View File

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

15
config/locales/README.md Normal file
View File

@@ -0,0 +1,15 @@
i18n Documentation
===================
i18n Automation
-------------
Automate string extraction from haml into locale files using [haml-i18n-extractor](https://github.com/shaiguitar/haml-i18n-extractor)
```rake i18n:extractor[relative_path_to_view]```
####Example
```rake i18n:extractor[app/views/layouts/_header.html.haml]```
* Creates app/views/layouts/_header.html.i18n-extractor.haml with the expected haml changes to localize app/views/layouts/_header.html.haml. After reviewing the changes, copy app/views/layouts/_header.html.i18n-extractor.haml to app/views/layouts/_header.html.haml
* Adds new keys to locales/en.yml

View File

@@ -1,5 +1,11 @@
---
en:
account:
update: Account detail was successfully updated.
account_types:
created: Account type was successfully created.
deleted: Account type was successfully deleted.
updated: Account type was successfully updated.
activerecord:
models:
comment:
@@ -42,14 +48,20 @@ en:
index:
title: Forums
gardens:
created: Garden was successfully created.
deleted: Garden was successfully deleted.
form:
location_helper: If you have a location set in your profile, it will be used when you create a new garden.
location: "%{owner}'s %{garden}"
updated: Garden was successfully updated.
harvests:
created: Harvest was successfully created.
index:
title:
crop_harvests: Everyone's %{crop} harvests
default: Everyone's harvests
owner_harvests: "%{owner} harvests"
updated: Harvest was successfully updated.
home:
blurb:
already_html: Or %{sign_in} if you already have an account
@@ -115,10 +127,14 @@ en:
admin: Admin
browse_crops: Browse Crops
browse_members: Browse Members
community: Community
community_map: Community Map
crop_wrangling: Crop Wrangling
crops: Crops
current_memberlogin_name: '%{current_memberlogin_name}'
forums: Forums
gardens: Gardens
harvest: Harvest
harvests: Harvests
inbox: Inbox
inbox_unread: Inbox (%{unread_count})
@@ -126,19 +142,34 @@ en:
posts: Posts
profile: Profile
seeds: Seeds
sign_in: Sign in
sign_out: Sign out
sign_up: Sign up
skip: Skip navigation menu
support_growstuff: Support Growstuff
toggle_navigation: Toggle Navigation
your_stuff: Your Stuff (%{unread_count})
members:
index:
title: "%{site_name} members"
signup:
error: Failed to complete signup
unsubscribe:
error: We're sorry, there was an error updating your settings.
unsubscribed: You have been unsubscribed from %{email_type} emails.
welcome: Welcome
photos:
show:
thing_by: A %{thing} by %{owner}
garden: "garden named \"%{garden}\" by %{owner}"
harvest: "%{crop} harvest by %{owner}"
planting: "%{planting}"
seed: "%{seed}"
places:
index:
title: "%{site_name} Community Map"
plantings:
string: "%{crop} planting in %{garden} by %{owner}"
form:
finish_helper: A planting is finished when you've harvested all of the crop, or it dies, or it's otherwise no longer growing in your garden.
index:
@@ -152,6 +183,7 @@ en:
author_posts: "%{author} posts"
default: Everyone's posts
seeds:
string: "%{crop} seeds belonging to %{owner}"
form:
trade_help: Are you interested in trading or swapping seeds with other %{site_name} members? If you list your seeds as available for trade, other members can contact you to request seeds. You can list any conditions or other information in the description, above.
index:

View File

@@ -1,3 +1,4 @@
---
ja:
home:
blurb:

View File

@@ -1,4 +1,4 @@
Growstuff::Application.routes.draw do # rubocop:disable Metrics/BlockLength
Growstuff::Application.routes.draw do
get '/robots.txt' => 'robots#robots'
resources :plant_parts
@@ -20,7 +20,9 @@ Growstuff::Application.routes.draw do # rubocop:disable Metrics/BlockLength
resources :authentications, only: [:create, :destroy]
resources :plantings
resources :plantings do
resources :harvests
end
get '/plantings/owner/:owner' => 'plantings#index', :as => 'plantings_by_owner'
get '/plantings/crop/:crop' => 'plantings#index', :as => 'plantings_by_crop'

View File

@@ -1,7 +1,5 @@
if ENV['MY_RUBY_HOME'] && ENV['MY_RUBY_HOME'].include?('rvm')
begin
rvm_path = File.dirname(File.dirname(ENV['MY_RUBY_HOME']))
rvm_lib_path = File.join(rvm_path, 'lib')
require 'rvm'
RVM.use_from_path! File.dirname(File.dirname(__FILE__))
rescue LoadError

View File

@@ -1,5 +1,5 @@
class CreateCms < ActiveRecord::Migration
def self.up # rubocop:disable Metrics/MethodLength
def self.up # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
text_limit = case ActiveRecord::Base.connection.adapter_name
when 'PostgreSQL'
{}

View File

@@ -0,0 +1,9 @@
class AddPhotosSeedsTable < ActiveRecord::Migration
def change
create_table :photos_seeds, id: false do |t|
t.integer :photo_id
t.integer :seed_id
end
add_index(:photos_seeds, [:seed_id, :photo_id])
end
end

View File

@@ -0,0 +1,5 @@
class AddPlantingRefToHarvests < ActiveRecord::Migration
def change
add_reference :harvests, :planting, index: true, foreign_key: true
end
end

View File

@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20161129021533) do
ActiveRecord::Schema.define(version: 20170104035248) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -265,8 +265,11 @@ ActiveRecord::Schema.define(version: 20161129021533) do
t.string "weight_unit"
t.integer "plant_part_id"
t.float "si_weight"
t.integer "planting_id"
end
add_index "harvests", ["planting_id"], name: "index_harvests_on_planting_id", using: :btree
create_table "harvests_photos", id: false, force: :cascade do |t|
t.integer "photo_id"
t.integer "harvest_id"
@@ -373,6 +376,13 @@ ActiveRecord::Schema.define(version: 20161129021533) do
t.integer "planting_id"
end
create_table "photos_seeds", id: false, force: :cascade do |t|
t.integer "photo_id"
t.integer "seed_id"
end
add_index "photos_seeds", ["seed_id", "photo_id"], name: "index_photos_seeds_on_seed_id_and_photo_id", using: :btree
create_table "plant_parts", force: :cascade do |t|
t.string "name"
t.datetime "created_at"
@@ -460,4 +470,5 @@ ActiveRecord::Schema.define(version: 20161129021533) do
add_index "seeds", ["slug"], name: "index_seeds_on_slug", unique: true, using: :btree
add_foreign_key "harvests", "plantings"
end

View File

@@ -87,7 +87,7 @@ def load_test_users
suburb_file.pos = 0 if suburb_file.eof?
row = CSV.parse(suburb_file.readline)
suburb, country, state, latitude, longitude = row[0]
suburb, _country, _state, latitude, longitude = row[0]
# Using 'update_column' method instead of 'update' so that
# it avoids accessing Geocoding service for faster processing
@user.gardens.first.update_columns(location: suburb, latitude: latitude, longitude: longitude)
@@ -141,7 +141,7 @@ def create_cropbot
@cropbot_user.skip_confirmation!
@cropbot_user.roles << @wrangler
@cropbot_user.save!
@cropbot_user.account.account_type = AccountType.find_by_name("Staff")
@cropbot_user.account.account_type = AccountType.find_by(name: "Staff")
@cropbot_user.account.save
end

View File

@@ -5,17 +5,9 @@ module Geocodable
private
def geocode
unless self.location.blank?
self.latitude, self.longitude =
Geocoder.coordinates(location, params: { limit: 1 })
end
end
def empty_unwanted_geocodes
if self.location.blank?
self.latitude = nil
self.longitude = nil
end
return unless self.location.blank?
self.latitude = nil
self.longitude = nil
end
end

View File

@@ -5,7 +5,7 @@ module Haml::Filters
module EscapedMarkdown
include Haml::Filters::Base
def render(text)
return Haml::Helpers.html_escape Haml::Filters::GrowstuffMarkdown.render(text)
Haml::Helpers.html_escape Haml::Filters::GrowstuffMarkdown.render(text)
end
end

View File

@@ -26,7 +26,7 @@ module Haml::Filters
expanded = expanded.gsub(MEMBER_REGEX) do |m|
member_str = $1
# find member case-insensitively
member = Member.where('lower(login_name) = ?', member_str.downcase).first
member = Member.case_insensitive_login_name(member_str).first
if member
url = Rails.application.routes.url_helpers.member_url(member, only_path: true)
"[#{member_str}](#{url})"
@@ -39,7 +39,7 @@ module Haml::Filters
expanded = expanded.gsub(MEMBER_AT_REGEX) do |m|
member_str = $1
# find member case-insensitively
member = Member.where('lower(login_name) = ?', member_str[1..-1].downcase).first
member = Member.case_insensitive_login_name(member_str[1..-1]).first
if member
url = Rails.application.routes.url_helpers.member_url(member, only_path: true)
"[#{member_str}](#{url})"
@@ -50,7 +50,7 @@ module Haml::Filters
expanded = expanded.gsub(MEMBER_ESCAPE_AT_REGEX, "")
return BlueCloth.new(expanded).to_html
BlueCloth.new(expanded).to_html
end
end

View File

@@ -146,7 +146,7 @@ namespace :growstuff do
end
puts "Making Skud a staff account..."
@skud = Member.find_by_login_name('Skud')
@skud = Member.find_by(login_name: 'Skud')
if @skud
@skud.account.account_type = @staff_account
@skud.account.save
@@ -157,7 +157,7 @@ namespace :growstuff do
desc "June 2013: replace nil account_types with free accounts"
task nil_account_type: :environment do
free = AccountType.find_by_name("Free")
free = AccountType.find_by(name: "Free")
raise "Free account type not found: run rake growstuff:oneoff:setup_shop"\
unless free
Account.all.each do |a|
@@ -187,9 +187,9 @@ namespace :growstuff do
desc "August 2013: set default creator on existing crops"
task set_default_crop_creator: :environment do
cropbot = Member.find_by_login_name("cropbot")
cropbot = Member.find_by(login_name: "cropbot")
raise "cropbot not found: create cropbot member on site or run rake db:seed" unless cropbot
cropbot.account.account_type = AccountType.find_by_name("Staff") # set this just because it's nice
cropbot.account.account_type = AccountType.find_by(name: "Staff") # set this just because it's nice
cropbot.account.save
Crop.find_each do |crop|
unless crop.creator
@@ -294,13 +294,11 @@ namespace :growstuff do
require 'csv'
file = "db/seeds/alternate_names_201410.csv"
puts "Loading alternate names from #{file}..."
cropbot = Member.find_by_login_name("cropbot")
cropbot = Member.find_by(login_name: "cropbot")
CSV.foreach(file) do |row|
crop_id, crop_name, alternate_names = row
if alternate_names.blank? then
next
end
crop = Crop.find_by_name(crop_name)
_crop_id, crop_name, alternate_names = row
next if alternate_names.blank?
crop = Crop.find_by(name: crop_name)
if crop
alternate_names.split(/,\s*/).each do |an|
AlternateName.where(

18
lib/tasks/i18n.rake Normal file
View File

@@ -0,0 +1,18 @@
namespace :i18n do
desc "sort all i18n locale keys"
task :normalize do
`i18n-tasks normalize`
end
desc "translate haml strings into i18 en locale using haml-i18n-extractor"
task :extractor, [:haml_path] do |_t, args|
require 'haml-i18n-extractor'
haml_path = args[:haml_path]
begin
translate = Haml::I18n::Extractor.new(haml_path)
translate.run
rescue Haml::I18n::Extractor::InvalidSyntax
puts "There was an error with #{haml_path}"
end
end
end

View File

@@ -25,6 +25,6 @@ describe AccountsController do
# allowed. This method has been left here in case it's useful in
# future.
member = FactoryGirl.create(:member)
return member.account
member.account
end
end

View File

@@ -18,13 +18,12 @@ describe Admin::OrdersController do
describe "GET search" do
it "assigns @orders" do
order = FactoryGirl.create(:order)
get :search, { search_by: 'order_id', search_text: order.id }
get :search, search_by: 'order_id', search_text: order.id
assigns(:orders).should eq([order])
end
it "sets an error message if nothing found" do
order = FactoryGirl.create(:order)
get :search, { search_by: 'order_id', search_text: 'foo' }
get :search, search_by: 'order_id', search_text: 'foo'
flash[:alert].should match /Couldn't find order with/
end
end

View File

@@ -36,14 +36,14 @@ describe CommentsController do
describe "GET new" do
it "picks up post from params" do
post = FactoryGirl.create(:post)
get :new, { post_id: post.id }
get :new, post_id: post.id
assigns(:post).should eq(post)
end
it "assigns the old comments as @comments" do
post = FactoryGirl.create(:post)
old_comment = FactoryGirl.create(:comment, post: post)
get :new, { post_id: post.id }
get :new, post_id: post.id
assigns(:comments).should eq [old_comment]
end
@@ -58,7 +58,7 @@ describe CommentsController do
post = FactoryGirl.create(:post)
old_comment = FactoryGirl.create(:comment, post: post)
comment = FactoryGirl.create(:comment, post: post, author: @member)
get :edit, { id: comment.to_param }
get :edit, id: comment.to_param
assigns(:comments).should eq([comment, old_comment])
end
end
@@ -67,7 +67,7 @@ describe CommentsController do
describe "with valid params" do
it "redirects to the comment's post" do
comment = Comment.create! valid_attributes
put :update, { id: comment.to_param, comment: valid_attributes }
put :update, id: comment.to_param, comment: valid_attributes
response.should redirect_to(comment.post)
end
end
@@ -77,7 +77,7 @@ describe CommentsController do
it "redirects to the post the comment was on" do
comment = Comment.create! valid_attributes
post = comment.post
delete :destroy, { id: comment.to_param }
delete :destroy, id: comment.to_param
response.should redirect_to(post)
end
end

View File

@@ -12,11 +12,72 @@
require 'rails_helper'
describe GardensController do
login_member
RSpec.describe GardensController, type: :controller do
include Devise::Test::ControllerHelpers
let(:valid_params) { { name: 'My second Garden' } }
def valid_attributes
member = FactoryGirl.create(:member)
{ name: 'My Garden', owner_id: member.id }
context "when not signed in" do
let(:garden) { double('garden') }
describe 'GET new' do
before { get :new, id: garden.to_param }
it { expect(response).to redirect_to(new_member_session_path) }
end
describe 'PUT create' do
before { put :create, garden: valid_params }
it { expect(response).to redirect_to(new_member_session_path) }
end
describe 'changing existing records' do
before do
allow(Garden).to receive(:find).and_return(:garden)
expect(garden).not_to receive(:save)
expect(garden).not_to receive(:save!)
expect(garden).not_to receive(:update)
expect(garden).not_to receive(:update!)
expect(garden).not_to receive(:destroy)
end
describe 'GET edit' do
before { get :edit, id: garden.to_param }
it { expect(response).to redirect_to(new_member_session_path) }
end
describe 'POST update' do
before { post :update, id: garden.to_param, garden: valid_params }
it { expect(response).to redirect_to(new_member_session_path) }
end
describe 'DELETE' do
before { delete :destroy, id: garden.to_param, params: { garden: valid_params } }
it { expect(response).to redirect_to(new_member_session_path) }
end
end
end
context "when signed in" do
before(:each) { sign_in member }
let!(:member) { FactoryGirl.create(:member) }
describe "for another member's garden" do
let(:not_my_garden) { double('garden') }
before do
expect(Garden).to receive(:find).and_return(:not_my_garden)
expect(not_my_garden).not_to receive(:save)
expect(not_my_garden).not_to receive(:save!)
expect(not_my_garden).not_to receive(:update)
expect(not_my_garden).not_to receive(:update!)
expect(not_my_garden).not_to receive(:destroy)
end
describe 'GET edit' do
before { get :edit, id: not_my_garden.to_param }
it { expect(response).to redirect_to(root_path) }
end
describe 'POST update' do
before { post :update, id: not_my_garden.to_param, garden: valid_params }
it { expect(response).to redirect_to(root_path) }
end
describe 'DELETE' do
before { delete :destroy, id: not_my_garden.to_param, params: { garden: valid_params } }
it { expect(response).to redirect_to(root_path) }
end
end
end
end

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