mirror of
https://github.com/Growstuff/growstuff.git
synced 2026-05-25 09:19:15 -04:00
Compare commits
302 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ca314c2f2 | ||
|
|
36768cf384 | ||
|
|
e35d0455bd | ||
|
|
c8405830c7 | ||
|
|
6bc9f775c2 | ||
|
|
a43526776b | ||
|
|
6f74566d47 | ||
|
|
82ce6c8222 | ||
|
|
f96f459595 | ||
|
|
096146cb84 | ||
|
|
ba1c40702b | ||
|
|
e6254da3f1 | ||
|
|
acbb610e05 | ||
|
|
338265d9e9 | ||
|
|
706922cacf | ||
|
|
08f2877f8e | ||
|
|
8275f5be96 | ||
|
|
2c3d1848d5 | ||
|
|
17e88778c8 | ||
|
|
bafb0123da | ||
|
|
e1e9c32652 | ||
|
|
48c3cbb3d1 | ||
|
|
740b8587f2 | ||
|
|
b113146aaa | ||
|
|
900de8a615 | ||
|
|
d73aa98309 | ||
|
|
ac7d44cb72 | ||
|
|
bba057ec76 | ||
|
|
1dc44c9edc | ||
|
|
92c1515381 | ||
|
|
43f905ea25 | ||
|
|
1db30d98ce | ||
|
|
2b92f013fc | ||
|
|
23f8c24ef4 | ||
|
|
fba2306a4d | ||
|
|
c8fa54591a | ||
|
|
67b496fe44 | ||
|
|
b24514fa82 | ||
|
|
f0a81d4100 | ||
|
|
64f11793c9 | ||
|
|
05a9d498a7 | ||
|
|
16145599ce | ||
|
|
af8527aa5b | ||
|
|
f9eb70e2eb | ||
|
|
8408fdc845 | ||
|
|
f37c9152af | ||
|
|
4ee789ca06 | ||
|
|
43e4ed43cd | ||
|
|
80371c835c | ||
|
|
6478d9cb1b | ||
|
|
f8b84f390d | ||
|
|
755b9b339f | ||
|
|
9deed09d36 | ||
|
|
43de722faf | ||
|
|
e145bb59f7 | ||
|
|
911c7b7bc1 | ||
|
|
2b7144c1fd | ||
|
|
8ddf36fed9 | ||
|
|
785ae33a42 | ||
|
|
c43c1686a3 | ||
|
|
65a8bde467 | ||
|
|
3647f67538 | ||
|
|
6c4f7eff92 | ||
|
|
9b57a44f6c | ||
|
|
8a69ed4013 | ||
|
|
e5d826e8c3 | ||
|
|
77c01d4f66 | ||
|
|
33b7952ed3 | ||
|
|
1217ba5b48 | ||
|
|
ffee6ada83 | ||
|
|
63b71a9265 | ||
|
|
3ecc7ba99b | ||
|
|
3e81419e78 | ||
|
|
7cd8dfa0c7 | ||
|
|
9182c8ceb1 | ||
|
|
ec8096233c | ||
|
|
19aa3a1ca4 | ||
|
|
e574ee166c | ||
|
|
93e9428bb6 | ||
|
|
fcf453b9d9 | ||
|
|
909164ea70 | ||
|
|
b5a5aca67b | ||
|
|
2424e7de87 | ||
|
|
d367b44da1 | ||
|
|
fe999d7170 | ||
|
|
3267fd7d1f | ||
|
|
355419b6cb | ||
|
|
dfa23a6564 | ||
|
|
9099ee5779 | ||
|
|
7ba9049908 | ||
|
|
c82127f1fb | ||
|
|
666394906b | ||
|
|
150393b1c3 | ||
|
|
e8e1e33a07 | ||
|
|
18e6e8510c | ||
|
|
64d7c2535b | ||
|
|
15106a051c | ||
|
|
62fe72c9f4 | ||
|
|
43519809f5 | ||
|
|
7731623397 | ||
|
|
3b3e14fadb | ||
|
|
271242eca9 | ||
|
|
a607fdc6ec | ||
|
|
6d1bdf9ae1 | ||
|
|
25058d02fc | ||
|
|
b80e7f677c | ||
|
|
576426c30d | ||
|
|
c9b464771d | ||
|
|
76af02f2a5 | ||
|
|
346970b471 | ||
|
|
e6d3c257e8 | ||
|
|
7224ef8848 | ||
|
|
dd9a0071d2 | ||
|
|
65b4b2d23e | ||
|
|
4fedc7f23f | ||
|
|
26b3e28171 | ||
|
|
29765c7bab | ||
|
|
370938c9f9 | ||
|
|
e578ca2c77 | ||
|
|
08d407f041 | ||
|
|
d6de147661 | ||
|
|
9cadbdec2b | ||
|
|
5e61be9853 | ||
|
|
ff50ec65d0 | ||
|
|
c4c50a4174 | ||
|
|
a1c74bfdfb | ||
|
|
2f9453780e | ||
|
|
725ae817d4 | ||
|
|
eab9bcb37d | ||
|
|
40a981c94d | ||
|
|
dd2af6a0e3 | ||
|
|
9192ccf52b | ||
|
|
4e79fd201c | ||
|
|
d266d7ed1a | ||
|
|
f7f1907b74 | ||
|
|
c42e9ca410 | ||
|
|
f97c465a92 | ||
|
|
a5b566a207 | ||
|
|
c6d16c92f5 | ||
|
|
c5b2e37730 | ||
|
|
5c642dfef9 | ||
|
|
a9b8253dfa | ||
|
|
58a3cbf569 | ||
|
|
8b4c8fef3b | ||
|
|
36c0de4504 | ||
|
|
3208bf9fb6 | ||
|
|
4eebf5c867 | ||
|
|
61f7bdfdd2 | ||
|
|
06838d7ad1 | ||
|
|
676f246e85 | ||
|
|
6121a9bc6e | ||
|
|
c2804f1725 | ||
|
|
b198305d36 | ||
|
|
7d7f5bfda3 | ||
|
|
d97af8e76e | ||
|
|
91adc5f59e | ||
|
|
714b2580a3 | ||
|
|
a8d5b14d46 | ||
|
|
cc59c4f49b | ||
|
|
8a7b7e75ef | ||
|
|
f8dda12de6 | ||
|
|
ab332976da | ||
|
|
331c778350 | ||
|
|
48b6a2297b | ||
|
|
27ea2e0432 | ||
|
|
4c0000b964 | ||
|
|
a3ee17bd4d | ||
|
|
958e7eb955 | ||
|
|
39888d44e2 | ||
|
|
b603bae1a7 | ||
|
|
05db5f3109 | ||
|
|
ad72ab0ba8 | ||
|
|
3beb3974fc | ||
|
|
fa15fd2912 | ||
|
|
78ed7869c5 | ||
|
|
0fa9f54c9c | ||
|
|
f214f608ff | ||
|
|
eb70f6dc57 | ||
|
|
43c4b154f9 | ||
|
|
21a536bf86 | ||
|
|
832a20eac9 | ||
|
|
f6cc0f3e13 | ||
|
|
5be5585084 | ||
|
|
989f176fb7 | ||
|
|
be07b5fd0e | ||
|
|
180505a1ca | ||
|
|
22343385f6 | ||
|
|
e11603cb3e | ||
|
|
97c5eb1c42 | ||
|
|
d07509f9e4 | ||
|
|
0c1220d11f | ||
|
|
f889b112fe | ||
|
|
a1cfa826d9 | ||
|
|
477f9669bd | ||
|
|
c1da5e4dc8 | ||
|
|
6bdfe5a669 | ||
|
|
8138aa8c09 | ||
|
|
eba397117c | ||
|
|
f9396248e6 | ||
|
|
d0351bad70 | ||
|
|
7ca371ae43 | ||
|
|
7fa0d22583 | ||
|
|
f31342c6e0 | ||
|
|
87a091d694 | ||
|
|
2e04d56225 | ||
|
|
405dfe4bc9 | ||
|
|
15de4ac08c | ||
|
|
6e535f2403 | ||
|
|
c55208713b | ||
|
|
48c1b4d0f9 | ||
|
|
2f38a8585b | ||
|
|
062ff16acf | ||
|
|
7f30ce04e0 | ||
|
|
144823bd13 | ||
|
|
90b19d52bb | ||
|
|
76be980163 | ||
|
|
88b1f02574 | ||
|
|
5b633b484b | ||
|
|
3be379cee9 | ||
|
|
5319d23ee3 | ||
|
|
350c1d4c08 | ||
|
|
885c9433ce | ||
|
|
b0c132c28f | ||
|
|
8765770071 | ||
|
|
8083ae9052 | ||
|
|
5ca8829727 | ||
|
|
d40eccdb63 | ||
|
|
478fae53ab | ||
|
|
fc71cba6ba | ||
|
|
283bb76a9e | ||
|
|
18e58809c3 | ||
|
|
b27b361e2f | ||
|
|
3fafa87afd | ||
|
|
de60dbb9b0 | ||
|
|
a95fca3682 | ||
|
|
8047aef692 | ||
|
|
b38728c5df | ||
|
|
241c3cfdc0 | ||
|
|
8b3b28b9d6 | ||
|
|
5f6fc37efd | ||
|
|
881acdccc9 | ||
|
|
3b1753d3d5 | ||
|
|
ab75f830fb | ||
|
|
0c8345d1e2 | ||
|
|
27520e9aa6 | ||
|
|
3cdaa03e5d | ||
|
|
fe5a93160f | ||
|
|
88ba4f9198 | ||
|
|
2594e5d334 | ||
|
|
ce9fc85d0b | ||
|
|
2499db77f1 | ||
|
|
8edbef3965 | ||
|
|
2e23675425 | ||
|
|
fef272e30f | ||
|
|
391d5bed5f | ||
|
|
8161e90fbd | ||
|
|
a074e72b9b | ||
|
|
d4a496eb1c | ||
|
|
a23e241480 | ||
|
|
af424103f4 | ||
|
|
d68cfe0486 | ||
|
|
0f15095129 | ||
|
|
6e0e7e4de1 | ||
|
|
07f7bd24d5 | ||
|
|
04074ff372 | ||
|
|
d3dac756d6 | ||
|
|
6f9ae13757 | ||
|
|
0a33ae8d37 | ||
|
|
ac33816675 | ||
|
|
77e95ad344 | ||
|
|
bb25cbe5e2 | ||
|
|
71c0bff3e0 | ||
|
|
c7a71381b7 | ||
|
|
5a1fd19abc | ||
|
|
a48a6da494 | ||
|
|
b0a803a7a5 | ||
|
|
6e4bb58dfd | ||
|
|
66b0f139a9 | ||
|
|
567562f132 | ||
|
|
39feeb94d0 | ||
|
|
75ac2081b0 | ||
|
|
36a94156c1 | ||
|
|
e3db003bbc | ||
|
|
33a66dce1f | ||
|
|
a013385d35 | ||
|
|
ba7ef3c85d | ||
|
|
73e144278e | ||
|
|
e3d2a90af8 | ||
|
|
1d5466fdfd | ||
|
|
a749a9ca63 | ||
|
|
6d8817d1fe | ||
|
|
1a845fdabc | ||
|
|
e52c4f7d4b | ||
|
|
5f435b1e82 | ||
|
|
f608685ac8 | ||
|
|
dbbd37e59e | ||
|
|
482650dec6 | ||
|
|
cc22b87cf1 | ||
|
|
8826b0137a | ||
|
|
d4d76b2e8d | ||
|
|
994ee18f13 | ||
|
|
80532e94f1 |
@@ -19,6 +19,9 @@ engines:
|
||||
languages:
|
||||
- ruby
|
||||
- javascript
|
||||
exclude_fingerprints:
|
||||
- 16dbcb58d6caa7ccfe241417831ecfa6
|
||||
- 7d7dca4f27f50e3084f203280073cc74
|
||||
fixme:
|
||||
enabled: true
|
||||
exclude_fingerprints: # rubocop_todo filename
|
||||
|
||||
4
.haml-lint.yml
Normal file
4
.haml-lint.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
linters:
|
||||
LineLength:
|
||||
max: 120
|
||||
|
||||
@@ -37,7 +37,7 @@ Metrics/MethodLength:
|
||||
# Remove the following once the code style matches
|
||||
# Offense count: 59
|
||||
Metrics/AbcSize:
|
||||
Max: 38
|
||||
Max: 32
|
||||
|
||||
# Offense count: 5
|
||||
# Configuration parameters: CountComments.
|
||||
@@ -47,7 +47,7 @@ Metrics/BlockLength:
|
||||
# Offense count: 6
|
||||
# Configuration parameters: CountComments.
|
||||
Metrics/ClassLength:
|
||||
Max: 275
|
||||
Max: 269
|
||||
|
||||
# Offense count: 6
|
||||
Metrics/CyclomaticComplexity:
|
||||
@@ -58,7 +58,7 @@ Metrics/LineLength:
|
||||
|
||||
# Offense count: 8
|
||||
Metrics/PerceivedComplexity:
|
||||
Max: 10
|
||||
Max: 9
|
||||
|
||||
# See https://github.com/bbatsov/rubocop/issues/3629
|
||||
Rails/HttpPositionalArguments:
|
||||
@@ -75,4 +75,4 @@ Style/FrozenStringLiteralComment:
|
||||
Rails/Output:
|
||||
Exclude:
|
||||
- 'config/unicorn.rb'
|
||||
- 'db/seeds.rb'
|
||||
- 'db/seeds.rb'
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
# This configuration was generated by
|
||||
# `rubocop --auto-gen-config --exclude-limit 500`
|
||||
# on 2016-11-13 10:16:38 +1300 using RuboCop version 0.45.0.
|
||||
# on 2017-01-21 15:58:02 +1030 using RuboCop version 0.47.1.
|
||||
# The point is for the user to remove these configuration records
|
||||
# one by one as the offenses are removed from the code base.
|
||||
# Note that changes in the inspected code, or installation of new
|
||||
# versions of RuboCop, may require this file to be generated again.
|
||||
|
||||
# Offense count: 24
|
||||
# Offense count: 22
|
||||
Lint/AmbiguousRegexpLiteral:
|
||||
Exclude:
|
||||
- 'app/models/order.rb'
|
||||
- 'spec/controllers/admin/orders_controller_spec.rb'
|
||||
- 'spec/controllers/orders_controller_spec.rb'
|
||||
- 'spec/features/cms_spec.rb'
|
||||
@@ -17,7 +16,6 @@ Lint/AmbiguousRegexpLiteral:
|
||||
- 'spec/lib/haml/filters/growstuff_markdown_spec.rb'
|
||||
- 'spec/models/comment_spec.rb'
|
||||
- 'spec/models/planting_spec.rb'
|
||||
- 'spec/models/post_spec.rb'
|
||||
- 'spec/views/members/show.rss.haml_spec.rb'
|
||||
- 'spec/views/posts/show.html.haml_spec.rb'
|
||||
|
||||
@@ -26,18 +24,17 @@ Lint/HandleExceptions:
|
||||
Exclude:
|
||||
- 'lib/tasks/testing.rake'
|
||||
|
||||
# Offense count: 15
|
||||
# Offense count: 11
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments.
|
||||
Lint/UnusedBlockArgument:
|
||||
Exclude:
|
||||
- 'app/controllers/crops_controller.rb'
|
||||
- 'app/controllers/sessions_controller.rb'
|
||||
- 'app/models/post.rb'
|
||||
- 'config/unicorn.rb'
|
||||
- 'lib/haml/filters/growstuff_markdown.rb'
|
||||
|
||||
# Offense count: 8
|
||||
# Offense count: 6
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods.
|
||||
Lint/UnusedMethodArgument:
|
||||
@@ -45,7 +42,6 @@ Lint/UnusedMethodArgument:
|
||||
- 'app/controllers/application_controller.rb'
|
||||
- 'app/controllers/passwords_controller.rb'
|
||||
- 'app/controllers/registrations_controller.rb'
|
||||
- 'app/models/crop.rb'
|
||||
- 'app/validators/approved_validator.rb'
|
||||
- 'spec/views/plantings/show.html.haml_spec.rb'
|
||||
|
||||
@@ -56,23 +52,25 @@ Lint/Void:
|
||||
- 'spec/models/garden_spec.rb'
|
||||
- 'spec/models/post_spec.rb'
|
||||
|
||||
# Offense count: 5
|
||||
# Offense count: 55
|
||||
# Configuration parameters: CountComments, ExcludedMethods.
|
||||
Metrics/BlockLength:
|
||||
Exclude:
|
||||
- '**/*'
|
||||
|
||||
# Offense count: 2
|
||||
# Cop supports --auto-correct.
|
||||
Performance/StringReplacement:
|
||||
Exclude:
|
||||
- 'app/models/garden.rb'
|
||||
- 'app/models/harvest.rb'
|
||||
- 'app/models/planting.rb'
|
||||
- 'app/models/seed.rb'
|
||||
- 'spec/rails_helper.rb'
|
||||
|
||||
# Offense count: 10
|
||||
# Offense count: 9
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: strict, flexible
|
||||
Rails/Date:
|
||||
Exclude:
|
||||
- 'app/controllers/harvests_controller.rb'
|
||||
- 'app/controllers/plantings_controller.rb'
|
||||
- 'db/seeds.rb'
|
||||
- 'lib/tasks/growstuff.rake'
|
||||
- 'spec/controllers/plantings_controller_spec.rb'
|
||||
@@ -80,20 +78,10 @@ Rails/Date:
|
||||
- 'spec/features/plantings/planting_a_crop_spec.rb'
|
||||
- 'spec/features/shared_examples/append_date.rb'
|
||||
|
||||
# Offense count: 11
|
||||
# Configuration parameters: Include.
|
||||
# Include: app/models/**/*.rb
|
||||
Rails/HasAndBelongsToMany:
|
||||
# Offense count: 4
|
||||
Rails/FilePath:
|
||||
Exclude:
|
||||
- 'app/models/crop.rb'
|
||||
- 'app/models/garden.rb'
|
||||
- 'app/models/harvest.rb'
|
||||
- 'app/models/member.rb'
|
||||
- 'app/models/photo.rb'
|
||||
- 'app/models/planting.rb'
|
||||
- 'app/models/post.rb'
|
||||
- 'app/models/product.rb'
|
||||
- 'app/models/role.rb'
|
||||
- 'spec/rails_helper.rb'
|
||||
|
||||
# Offense count: 3
|
||||
Rails/OutputSafety:
|
||||
@@ -102,42 +90,44 @@ Rails/OutputSafety:
|
||||
- 'app/helpers/auto_suggest_helper.rb'
|
||||
- 'app/helpers/gardens_helper.rb'
|
||||
|
||||
# Offense count: 9
|
||||
# Offense count: 1
|
||||
# Configuration parameters: Include.
|
||||
# Include: db/migrate/*.rb
|
||||
Rails/ReversibleMigration:
|
||||
Exclude:
|
||||
- 'db/migrate/20130215131921_rename_notification_fields.rb'
|
||||
|
||||
# Offense count: 4
|
||||
# Configuration parameters: Blacklist.
|
||||
# Blacklist: decrement!, decrement_counter, increment!, increment_counter, toggle!, touch, update_all, update_attribute, update_column, update_columns, update_counters
|
||||
Rails/SkipsModelValidations:
|
||||
Exclude:
|
||||
- 'app/controllers/plantings_controller.rb'
|
||||
- 'db/seeds.rb'
|
||||
|
||||
# Offense count: 7
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: strict, flexible
|
||||
Rails/TimeZone:
|
||||
Exclude:
|
||||
- 'app/helpers/plantings_helper.rb'
|
||||
- 'spec/controllers/accounts_controller_spec.rb'
|
||||
- 'spec/factories/member.rb'
|
||||
- 'spec/factories/post.rb'
|
||||
- 'spec/models/post_spec.rb'
|
||||
- 'spec/views/plantings/index.html.haml_spec.rb'
|
||||
|
||||
# Offense count: 2
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: Include.
|
||||
# Include: app/models/**/*.rb
|
||||
Rails/Validation:
|
||||
Exclude:
|
||||
- 'app/models/member.rb'
|
||||
- 'app/models/order_item.rb'
|
||||
|
||||
# Offense count: 12
|
||||
# Offense count: 7
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: always, conditionals
|
||||
Style/AndOr:
|
||||
Exclude:
|
||||
- 'app/models/notification.rb'
|
||||
- 'app/models/photo.rb'
|
||||
- 'config/unicorn.rb'
|
||||
- 'lib/tasks/growstuff.rake'
|
||||
|
||||
# Offense count: 2
|
||||
# Offense count: 1
|
||||
Style/AsciiComments:
|
||||
Exclude:
|
||||
- 'app/models/crop.rb'
|
||||
- 'config/initializers/comfortable_mexican_sofa.rb'
|
||||
|
||||
# Offense count: 5
|
||||
@@ -149,7 +139,7 @@ Style/BarePercentLiterals:
|
||||
- 'app/helpers/auto_suggest_helper.rb'
|
||||
- 'spec/support/feature_helpers.rb'
|
||||
|
||||
# Offense count: 25
|
||||
# Offense count: 26
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles, ProceduralMethods, FunctionalMethods, IgnoredMethods.
|
||||
# SupportedStyles: line_count_based, semantic, braces_for_chaining
|
||||
@@ -183,36 +173,6 @@ Style/BlockEndNewline:
|
||||
- 'spec/models/member_spec.rb'
|
||||
- 'spec/models/planting_spec.rb'
|
||||
|
||||
# Offense count: 93
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: braces, no_braces, context_dependent
|
||||
Style/BracesAroundHashParameters:
|
||||
Exclude:
|
||||
- 'app/controllers/admin/orders_controller.rb'
|
||||
- 'app/controllers/crops_controller.rb'
|
||||
- 'app/controllers/posts_controller.rb'
|
||||
- 'app/helpers/application_helper.rb'
|
||||
- 'app/models/crop.rb'
|
||||
- 'app/models/member.rb'
|
||||
- 'app/models/order.rb'
|
||||
- 'config/environments/test.rb'
|
||||
- 'spec/controllers/admin/orders_controller_spec.rb'
|
||||
- 'spec/controllers/comments_controller_spec.rb'
|
||||
- 'spec/controllers/harvests_controller_spec.rb'
|
||||
- 'spec/controllers/member_controller_spec.rb'
|
||||
- 'spec/controllers/notifications_controller_spec.rb'
|
||||
- 'spec/controllers/order_items_controller_spec.rb'
|
||||
- 'spec/controllers/orders_controller_spec.rb'
|
||||
- 'spec/controllers/places_controller_spec.rb'
|
||||
- 'spec/controllers/plantings_controller_spec.rb'
|
||||
- 'spec/controllers/posts_controller_spec.rb'
|
||||
- 'spec/controllers/scientific_names_controller_spec.rb'
|
||||
- 'spec/controllers/seeds_controller_spec.rb'
|
||||
- 'spec/lib/actions/oauth_signup_action_spec.rb'
|
||||
- 'spec/views/notifier/notify.html.haml_spec.rb'
|
||||
- 'spec/views/photos/new.html.haml_spec.rb'
|
||||
|
||||
# Offense count: 4
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: nested, compact
|
||||
@@ -223,16 +183,11 @@ Style/ClassAndModuleChildren:
|
||||
- 'lib/haml/filters/escaped_markdown.rb'
|
||||
- 'lib/haml/filters/growstuff_markdown.rb'
|
||||
|
||||
# Offense count: 8
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
Style/ClassMethods:
|
||||
Exclude:
|
||||
- 'app/models/crop.rb'
|
||||
- 'app/models/member.rb'
|
||||
- 'app/models/order.rb'
|
||||
- 'app/models/planting.rb'
|
||||
- 'app/models/post.rb'
|
||||
- 'app/models/seed.rb'
|
||||
|
||||
# Offense count: 2
|
||||
# Cop supports --auto-correct.
|
||||
@@ -262,18 +217,23 @@ Style/EachForSimpleLoop:
|
||||
- 'spec/models/crop_spec.rb'
|
||||
- 'spec/views/home/_crops.html.haml_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Offense count: 11
|
||||
# Cop supports --auto-correct.
|
||||
Style/EmptyLiteral:
|
||||
Exclude:
|
||||
- 'app/models/member.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: for, each
|
||||
Style/For:
|
||||
# SupportedStyles: compact, expanded
|
||||
Style/EmptyMethod:
|
||||
Exclude:
|
||||
- 'app/models/order.rb'
|
||||
- 'app/controllers/account_types_controller.rb'
|
||||
- 'app/controllers/accounts_controller.rb'
|
||||
- 'app/controllers/alternate_names_controller.rb'
|
||||
- 'app/controllers/gardens_controller.rb'
|
||||
- 'app/controllers/photos_controller.rb'
|
||||
- 'app/controllers/plant_parts_controller.rb'
|
||||
- 'app/controllers/posts_controller.rb'
|
||||
- 'app/controllers/products_controller.rb'
|
||||
- 'app/controllers/roles_controller.rb'
|
||||
- 'app/controllers/scientific_names_controller.rb'
|
||||
- 'app/controllers/seeds_controller.rb'
|
||||
|
||||
# Offense count: 5
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
@@ -284,32 +244,19 @@ Style/FormatString:
|
||||
- 'spec/helpers/application_helper_spec.rb'
|
||||
- 'spec/views/shop/index_spec.rb'
|
||||
|
||||
# Offense count: 4
|
||||
# Offense count: 2
|
||||
Style/IdenticalConditionalBranches:
|
||||
Exclude:
|
||||
- 'app/controllers/crops_controller.rb'
|
||||
- 'app/controllers/follows_controller.rb'
|
||||
|
||||
# Offense count: 1
|
||||
Style/IfInsideElse:
|
||||
Exclude:
|
||||
- 'app/models/harvest.rb'
|
||||
|
||||
# Offense count: 26
|
||||
# Offense count: 6
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: MaxLineLength.
|
||||
Style/IfUnlessModifier:
|
||||
Exclude:
|
||||
- 'app/controllers/gardens_controller.rb'
|
||||
- 'app/controllers/shop_controller.rb'
|
||||
- 'app/helpers/crops_helper.rb'
|
||||
- 'app/models/crop.rb'
|
||||
- 'app/models/garden.rb'
|
||||
- 'app/models/harvest.rb'
|
||||
- 'app/models/member.rb'
|
||||
- 'app/models/order.rb'
|
||||
- 'app/models/planting.rb'
|
||||
- 'app/models/seed.rb'
|
||||
- 'config/initializers/geocoder.rb'
|
||||
- 'lib/tasks/growstuff.rake'
|
||||
|
||||
@@ -322,22 +269,12 @@ Style/Lambda:
|
||||
- 'spec/controllers/member_controller_spec.rb'
|
||||
- 'spec/models/photo_spec.rb'
|
||||
|
||||
|
||||
# Offense count: 3
|
||||
# Cop supports --auto-correct.
|
||||
Style/MethodCallParentheses:
|
||||
Exclude:
|
||||
- 'app/models/photo.rb'
|
||||
- 'spec/helpers/application_helper_spec.rb'
|
||||
- 'spec/views/plantings/new.html.haml_spec.rb'
|
||||
|
||||
# Offense count: 2
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: symmetrical, new_line, same_line
|
||||
Style/MultilineArrayBraceLayout:
|
||||
Style/MethodCallWithoutArgsParentheses:
|
||||
Exclude:
|
||||
- 'app/models/seed.rb'
|
||||
- 'spec/helpers/application_helper_spec.rb'
|
||||
- 'spec/views/plantings/new.html.haml_spec.rb'
|
||||
|
||||
# Offense count: 8
|
||||
# Cop supports --auto-correct.
|
||||
@@ -349,17 +286,13 @@ Style/MultilineBlockLayout:
|
||||
- 'spec/models/member_spec.rb'
|
||||
- 'spec/models/planting_spec.rb'
|
||||
|
||||
# Offense count: 7
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: symmetrical, new_line, same_line
|
||||
Style/MultilineHashBraceLayout:
|
||||
Exclude:
|
||||
- 'app/models/garden.rb'
|
||||
- 'app/models/harvest.rb'
|
||||
- 'app/models/planting.rb'
|
||||
- 'app/models/product.rb'
|
||||
- 'app/models/seed.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
@@ -367,15 +300,14 @@ Style/MultilineIfModifier:
|
||||
Exclude:
|
||||
- 'spec/rails_helper.rb'
|
||||
|
||||
# Offense count: 6
|
||||
# Offense count: 5
|
||||
# Cop supports --auto-correct.
|
||||
Style/MultilineIfThen:
|
||||
Exclude:
|
||||
- 'lib/tasks/growstuff.rake'
|
||||
- 'script/check_contributors_md'
|
||||
- 'script/gemfile_check'
|
||||
|
||||
# Offense count: 93
|
||||
# Offense count: 95
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: symmetrical, new_line, same_line
|
||||
@@ -384,8 +316,6 @@ Style/MultilineMethodCallBraceLayout:
|
||||
- 'app/controllers/application_controller.rb'
|
||||
- 'app/controllers/authentications_controller.rb'
|
||||
- 'app/controllers/seeds_controller.rb'
|
||||
- 'app/models/account.rb'
|
||||
- 'app/models/crop.rb'
|
||||
- 'spec/controllers/order_items_controller_spec.rb'
|
||||
- 'spec/helpers/gardens_helper_spec.rb'
|
||||
- 'spec/helpers/harvests_helper_spec.rb'
|
||||
@@ -431,25 +361,18 @@ Style/MultilineTernaryOperator:
|
||||
- 'app/controllers/notifications_controller.rb'
|
||||
- 'app/controllers/order_items_controller.rb'
|
||||
|
||||
# Offense count: 10
|
||||
# Offense count: 3
|
||||
# Cop supports --auto-correct.
|
||||
Style/MutableConstant:
|
||||
Exclude:
|
||||
- 'app/controllers/members_controller.rb'
|
||||
- 'app/models/garden.rb'
|
||||
- 'app/models/harvest.rb'
|
||||
- 'app/models/planting.rb'
|
||||
- 'app/models/seed.rb'
|
||||
|
||||
# Offense count: 7
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
Style/NegatedIf:
|
||||
Exclude:
|
||||
- 'app/controllers/crops_controller.rb'
|
||||
- 'app/helpers/crops_helper.rb'
|
||||
- 'app/models/crop.rb'
|
||||
- 'app/models/garden.rb'
|
||||
- 'script/check_contributors_md'
|
||||
|
||||
# Offense count: 2
|
||||
Style/NestedTernaryOperator:
|
||||
@@ -457,13 +380,12 @@ Style/NestedTernaryOperator:
|
||||
- 'app/controllers/harvests_controller.rb'
|
||||
- 'app/controllers/plantings_controller.rb'
|
||||
|
||||
# Offense count: 2
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, MinBodyLength, SupportedStyles.
|
||||
# SupportedStyles: skip_modifier_ifs, always
|
||||
Style/Next:
|
||||
Exclude:
|
||||
- 'app/models/post.rb'
|
||||
- 'lib/tasks/growstuff.rake'
|
||||
|
||||
# Offense count: 2
|
||||
@@ -472,13 +394,6 @@ Style/NilComparison:
|
||||
Exclude:
|
||||
- 'lib/tasks/growstuff.rake'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: IncludeSemanticChanges.
|
||||
Style/NonNilCheck:
|
||||
Exclude:
|
||||
- 'app/models/harvest.rb'
|
||||
|
||||
# Offense count: 2
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedOctalStyle, SupportedOctalStyles.
|
||||
@@ -492,20 +407,15 @@ Style/NumericLiteralPrefix:
|
||||
Style/NumericLiterals:
|
||||
MinDigits: 9
|
||||
|
||||
# Offense count: 16
|
||||
# Offense count: 5
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: AutoCorrect, EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: predicate, comparison
|
||||
Style/NumericPredicate:
|
||||
Exclude:
|
||||
- 'spec/**/*'
|
||||
- 'app/helpers/crops_helper.rb'
|
||||
- 'app/helpers/harvests_helper.rb'
|
||||
- 'app/helpers/plantings_helper.rb'
|
||||
- 'app/models/crop.rb'
|
||||
- 'app/models/garden.rb'
|
||||
- 'app/models/harvest.rb'
|
||||
- 'app/models/photo.rb'
|
||||
- 'lib/tasks/growstuff.rake'
|
||||
- 'script/check_contributors_md'
|
||||
|
||||
@@ -515,7 +425,7 @@ Style/ParallelAssignment:
|
||||
Exclude:
|
||||
- 'app/mailers/notifier.rb'
|
||||
|
||||
# Offense count: 8
|
||||
# Offense count: 4
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: AllowSafeAssignment.
|
||||
Style/ParenthesesAroundCondition:
|
||||
@@ -523,8 +433,6 @@ Style/ParenthesesAroundCondition:
|
||||
- 'app/controllers/application_controller.rb'
|
||||
- 'app/controllers/orders_controller.rb'
|
||||
- 'app/helpers/crops_helper.rb'
|
||||
- 'app/models/garden.rb'
|
||||
- 'app/models/member.rb'
|
||||
- 'config/factory_girl.rb'
|
||||
|
||||
# Offense count: 5
|
||||
@@ -537,60 +445,30 @@ Style/PercentLiteralDelimiters:
|
||||
- 'spec/features/signin_spec.rb'
|
||||
- 'spec/features/signout_spec.rb'
|
||||
|
||||
# Offense count: 6
|
||||
# Offense count: 3
|
||||
# Cop supports --auto-correct.
|
||||
Style/PerlBackrefs:
|
||||
Exclude:
|
||||
- 'app/models/post.rb'
|
||||
- 'lib/haml/filters/growstuff_markdown.rb'
|
||||
|
||||
# Offense count: 3
|
||||
# Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist.
|
||||
# NamePrefix: is_, has_, have_
|
||||
# NamePrefixBlacklist: is_, has_, have_
|
||||
# NameWhitelist: is_a?
|
||||
Style/PredicateName:
|
||||
Exclude:
|
||||
- 'spec/**/*'
|
||||
- 'app/models/member.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
Style/RedundantBegin:
|
||||
Exclude:
|
||||
- 'app/controllers/members_controller.rb'
|
||||
|
||||
# Offense count: 2
|
||||
# Cop supports --auto-correct.
|
||||
Style/RedundantParentheses:
|
||||
Exclude:
|
||||
- 'app/helpers/plantings_helper.rb'
|
||||
- 'app/models/garden.rb'
|
||||
|
||||
# Offense count: 56
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
Style/RedundantSelf:
|
||||
Exclude:
|
||||
- 'app/models/comment.rb'
|
||||
- 'app/models/crop.rb'
|
||||
- 'app/models/follow.rb'
|
||||
- 'app/models/harvest.rb'
|
||||
- 'app/models/member.rb'
|
||||
- 'app/models/notification.rb'
|
||||
- 'app/models/order.rb'
|
||||
- 'app/models/photo.rb'
|
||||
- 'app/models/planting.rb'
|
||||
- 'app/models/post.rb'
|
||||
- 'app/models/seed.rb'
|
||||
- 'lib/geocodable.rb'
|
||||
|
||||
# Offense count: 9
|
||||
# Offense count: 6
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles, AllowInnerSlashes.
|
||||
# SupportedStyles: slashes, percent_r, mixed
|
||||
Style/RegexpLiteral:
|
||||
Exclude:
|
||||
- 'app/models/crop.rb'
|
||||
- 'spec/lib/haml/filters/growstuff_markdown_spec.rb'
|
||||
- 'spec/rails_helper.rb'
|
||||
- 'spec/views/devise/registrations/edit_spec.rb'
|
||||
@@ -611,55 +489,39 @@ Style/SelfAssignment:
|
||||
Style/SpecialGlobalVars:
|
||||
EnforcedStyle: use_perl_names
|
||||
|
||||
# Offense count: 2
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: single_quotes, double_quotes
|
||||
Style/StringLiteralsInInterpolation:
|
||||
Exclude:
|
||||
- 'app/models/follow.rb'
|
||||
- 'app/models/post.rb'
|
||||
|
||||
# Offense count: 9
|
||||
# Offense count: 3
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: IgnoredMethods.
|
||||
# IgnoredMethods: respond_to, define_method
|
||||
Style/SymbolProc:
|
||||
Exclude:
|
||||
- 'app/controllers/crops_controller.rb'
|
||||
- 'app/models/crop.rb'
|
||||
- 'app/models/garden.rb'
|
||||
- 'app/models/harvest.rb'
|
||||
- 'app/models/planting.rb'
|
||||
- 'app/models/post.rb'
|
||||
- 'lib/tasks/growstuff.rake'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles, AllowSafeAssignment.
|
||||
# SupportedStyles: require_parentheses, require_no_parentheses
|
||||
# SupportedStyles: require_parentheses, require_no_parentheses, require_parentheses_when_complex
|
||||
Style/TernaryParentheses:
|
||||
Exclude:
|
||||
- 'app/helpers/plantings_helper.rb'
|
||||
|
||||
# Offense count: 5
|
||||
# Offense count: 4
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyleForMultiline, SupportedStyles.
|
||||
# SupportedStyles: comma, consistent_comma, no_comma
|
||||
# Configuration parameters: EnforcedStyleForMultiline, SupportedStylesForMultiline.
|
||||
# SupportedStylesForMultiline: comma, consistent_comma, no_comma
|
||||
Style/TrailingCommaInArguments:
|
||||
Exclude:
|
||||
- 'app/models/post.rb'
|
||||
- 'db/seeds.rb'
|
||||
- 'lib/actions/oauth_signup_action.rb'
|
||||
- 'lib/tasks/growstuff.rake'
|
||||
|
||||
# Offense count: 5
|
||||
# Offense count: 4
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyleForMultiline, SupportedStyles.
|
||||
# SupportedStyles: comma, consistent_comma, no_comma
|
||||
# Configuration parameters: EnforcedStyleForMultiline, SupportedStylesForMultiline.
|
||||
# SupportedStylesForMultiline: comma, consistent_comma, no_comma
|
||||
Style/TrailingCommaInLiteral:
|
||||
Exclude:
|
||||
- 'app/models/crop.rb'
|
||||
- 'config/environments/test.rb'
|
||||
- 'spec/rails_helper.rb'
|
||||
|
||||
@@ -669,12 +531,10 @@ Style/UnlessElse:
|
||||
Exclude:
|
||||
- 'app/controllers/omniauth_callbacks_controller.rb'
|
||||
|
||||
# Offense count: 16
|
||||
# Offense count: 12
|
||||
# Cop supports --auto-correct.
|
||||
Style/UnneededInterpolation:
|
||||
Exclude:
|
||||
- 'app/models/crop.rb'
|
||||
- 'app/models/harvest.rb'
|
||||
- 'spec/features/crops/crop_wranglers_spec.rb'
|
||||
- 'spec/features/following_spec.rb'
|
||||
- 'spec/features/shared_examples/append_date.rb'
|
||||
@@ -690,19 +550,10 @@ Style/UnneededPercentQ:
|
||||
Exclude:
|
||||
- 'spec/support/feature_helpers.rb'
|
||||
|
||||
# Offense count: 4
|
||||
# Offense count: 2
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles, MinSize, WordRegex.
|
||||
# Configuration parameters: SupportedStyles, WordRegex.
|
||||
# SupportedStyles: percent, brackets
|
||||
Style/WordArray:
|
||||
Exclude:
|
||||
- 'app/controllers/omniauth_callbacks_controller.rb'
|
||||
- 'app/models/crop.rb'
|
||||
- 'spec/models/seed_spec.rb'
|
||||
|
||||
# Offense count: 6
|
||||
# Cop supports --auto-correct.
|
||||
Style/ZeroLengthPredicate:
|
||||
Exclude:
|
||||
- 'app/models/crop.rb'
|
||||
- 'app/models/photo.rb'
|
||||
EnforcedStyle: percent
|
||||
MinSize: 5
|
||||
|
||||
@@ -28,6 +28,7 @@ before_script:
|
||||
- bundle exec rake assets:precompile
|
||||
script:
|
||||
- bundle exec rubocop --display-cop-names --rails
|
||||
- bundle exec haml-lint app/views/account_types app/views/admin app/views/alternate_names app/views/account_types app/views/comments app/views/crops app/views/forums app/views/gardens app/views/harvests app/views/notifier app/views/orders app/views/photos
|
||||
- script/gemfile_check
|
||||
- bundle exec script/check_contributors_md
|
||||
- bundle exec rake db:migrate --trace
|
||||
|
||||
@@ -54,6 +54,8 @@ submit the change with your pull request.
|
||||
- Rocky Jaiswal / [rocky-jaiswal](https://github.com/rocky-jaiswal)
|
||||
- Robert Landreaux / [robertlandreaux](https://github.com/robertlandreaux)
|
||||
- Savant Krishna / [sksavant](https://github.com/sksavant)
|
||||
- Marlena Compton / [marlena](https://github/marlena)
|
||||
- Ryan Dy / [rdy](https://github/rdy)
|
||||
- Jake Yesbeck / [yez](https://github.com/yez)
|
||||
- Mauricio Gonzalez / [mauricio-gonzalez](https://github.com/mauricio-gonzalez)
|
||||
- Andrey Bazhutkin / [andrba](https://github.com/andrba)
|
||||
@@ -73,3 +75,4 @@ submit the change with your pull request.
|
||||
- Kristine Nicole Polvoriza / [polveenomials](https://github.com/polveenomials)
|
||||
- Brenda Wallace / [br3nda](https://github.com/br3nda)
|
||||
- Jim Stallings / [jestallin](https://github.com/jestallin)
|
||||
- Alyssa Ransbury / [alran](https://github.com/alran)
|
||||
|
||||
67
Gemfile
67
Gemfile
@@ -7,9 +7,9 @@ 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,15 +64,18 @@ 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'
|
||||
|
||||
# For charting data
|
||||
gem 'd3-rails'
|
||||
|
||||
# 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
|
||||
# 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"
|
||||
@@ -81,12 +84,15 @@ 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
|
||||
|
||||
@@ -94,33 +100,36 @@ 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 'i18n-tasks' # adds tests for finding missing and unused translations
|
||||
gem 'selenium-webdriver'
|
||||
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 "active_merchant-paypal-bogus-gateway"
|
||||
gem 'haml_lint' # Checks haml files for goodness
|
||||
gem 'haml-rails' # HTML templating language
|
||||
gem 'i18n-tasks' # adds tests for finding missing and unused translations
|
||||
gem 'jasmine' # javascript unit testing
|
||||
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
|
||||
|
||||
100
Gemfile.lock
100
Gemfile.lock
@@ -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.5.3.1)
|
||||
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,8 +90,7 @@ 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)
|
||||
@@ -106,8 +105,8 @@ GEM
|
||||
coffee-script (2.4.1)
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.11.1)
|
||||
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,19 +118,21 @@ 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)
|
||||
d3-rails (3.4.13)
|
||||
railties (>= 3.1)
|
||||
dalli (2.7.6)
|
||||
database_cleaner (1.5.3)
|
||||
debug_inspector (0.0.2)
|
||||
@@ -141,7 +142,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 +164,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 +180,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)
|
||||
@@ -216,6 +217,11 @@ GEM
|
||||
haml (>= 4.0.6, < 5.0)
|
||||
html2haml (>= 1.0.1)
|
||||
railties (>= 4.0.1)
|
||||
haml_lint (0.20.0)
|
||||
haml (~> 4.0)
|
||||
rake (>= 10, < 13)
|
||||
rubocop (>= 0.47.0)
|
||||
sysexits (~> 1.1)
|
||||
hashie (3.4.6)
|
||||
heroku-api (0.4.2)
|
||||
excon (~> 0.45)
|
||||
@@ -229,7 +235,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)
|
||||
@@ -239,7 +245,13 @@ GEM
|
||||
parser (>= 2.2.3.0)
|
||||
term-ansicolor (>= 1.3.2)
|
||||
terminal-table (>= 1.5.1)
|
||||
jquery-rails (4.2.1)
|
||||
jasmine (2.5.1)
|
||||
jasmine-core (>= 2.5.1, < 3.0.0)
|
||||
phantomjs
|
||||
rack (>= 1.2.1)
|
||||
rake
|
||||
jasmine-core (2.5.2)
|
||||
jquery-rails (4.2.2)
|
||||
rails-dom-testing (>= 1, < 3)
|
||||
railties (>= 4.2.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
@@ -248,13 +260,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)
|
||||
@@ -268,7 +280,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)
|
||||
@@ -296,7 +308,7 @@ 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 (4.0.0)
|
||||
@@ -320,9 +332,10 @@ 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)
|
||||
phantomjs (2.1.1.0)
|
||||
plupload-rails (1.2.1)
|
||||
rails (>= 3.1)
|
||||
poltergeist (1.11.0)
|
||||
@@ -334,7 +347,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)
|
||||
@@ -355,9 +368,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)
|
||||
@@ -408,26 +421,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)
|
||||
@@ -450,14 +463,15 @@ 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)
|
||||
sysexits (1.2.0)
|
||||
term-ansicolor (1.4.0)
|
||||
tins (~> 1.0)
|
||||
terminal-table (1.7.3)
|
||||
unicode-display_width (~> 1.1.1)
|
||||
@@ -472,7 +486,7 @@ GEM
|
||||
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)
|
||||
@@ -515,6 +529,7 @@ DEPENDENCIES
|
||||
comfortable_mexican_sofa (~> 1.12.0)
|
||||
coveralls
|
||||
csv_shaper
|
||||
d3-rails
|
||||
dalli
|
||||
database_cleaner (~> 1.5.0)
|
||||
devise (>= 4.0.0)
|
||||
@@ -534,8 +549,10 @@ DEPENDENCIES
|
||||
haml
|
||||
haml-i18n-extractor
|
||||
haml-rails
|
||||
haml_lint
|
||||
heroku-api
|
||||
i18n-tasks
|
||||
jasmine
|
||||
jquery-rails
|
||||
jquery-ui-rails (~> 5.0.2)
|
||||
js-routes
|
||||
@@ -555,6 +572,7 @@ DEPENDENCIES
|
||||
quiet_assets
|
||||
rails (~> 4.2.7)
|
||||
rails_12factor
|
||||
rainbow (< 2.2.0)
|
||||
rake (>= 10.0.0)
|
||||
rspec-activemodel-mocks
|
||||
rspec-rails
|
||||
@@ -573,4 +591,4 @@ RUBY VERSION
|
||||
ruby 2.3.3p222
|
||||
|
||||
BUNDLED WITH
|
||||
1.13.6
|
||||
1.13.7
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
//= require graphs/horizontal_bar_graph
|
||||
|
||||
if (document.getElementById("cropmap") !== null) {
|
||||
mapbox_map_id = "<%= Rails.env == 'test' ? 0 : Growstuff::Application.config.mapbox_map_id %>";
|
||||
mapbox_access_token = "<%= Rails.env == 'test' ? 0 : Growstuff::Application.config.mapbox_access_token %>";
|
||||
@@ -49,6 +51,41 @@ function showCropMap(cropmap) {
|
||||
cropmap.addLayer(markers);
|
||||
}
|
||||
|
||||
function plantingStats(crop) {
|
||||
var sunniness_counts = { 'empty': 0, 'sun': 0, 'semi-shade': 0, 'shade': 0 };
|
||||
$.each(crop.plantings, function(i, planting) {
|
||||
if (planting.sunniness) {
|
||||
sunniness_counts[planting.sunniness]++;
|
||||
} else {
|
||||
sunniness_counts['Empty']++;
|
||||
}
|
||||
});
|
||||
return [
|
||||
{name: 'Empty', value: sunniness_counts['empty']},
|
||||
{name: 'Sun', value: sunniness_counts['sun']},
|
||||
{name: 'Semi-shade', value: sunniness_counts['semi-shade']},
|
||||
{name: 'Shade', value: sunniness_counts['shade']}
|
||||
];
|
||||
}
|
||||
|
||||
if ($("#sunchart")[0] !== null) {
|
||||
var HorizontalBarGraph = growstuff.HorizontalBarGraph;
|
||||
$.getJSON(location.pathname + '.json', function (crop) {
|
||||
data = {
|
||||
bars: plantingStats(crop),
|
||||
bar_color: 'steelblue',
|
||||
width: {size: 300, scale: 'linear'},
|
||||
height: {size: 100, scale: 'ordinal'},
|
||||
//left is used to shift the bars over so that there is
|
||||
//room for the labels
|
||||
margin: {top: 0, right: 0, bottom: 0, left: 100}
|
||||
};
|
||||
|
||||
var graph = new HorizontalBarGraph(data);
|
||||
graph.render(d3.select($('#sunchart')[0]));
|
||||
});
|
||||
}
|
||||
|
||||
$('.btn.toggle.crop-hierarchy').click(function () {
|
||||
$('.toggle.crop-hierarchy').toggleClass('hide');
|
||||
});
|
||||
|
||||
50
app/assets/javascripts/graphs/bar_group.js
Normal file
50
app/assets/javascripts/graphs/bar_group.js
Normal file
@@ -0,0 +1,50 @@
|
||||
//= require graphs/width_scale
|
||||
//= require graphs/height_scale
|
||||
|
||||
(function(){
|
||||
'use strict';
|
||||
|
||||
/*
|
||||
This represents bars for a bar graph.
|
||||
Currently these are used for HorizontalBarGraph.
|
||||
*/
|
||||
|
||||
var growstuff = (window.growstuff = window.growstuff || {});
|
||||
var WidthScale = growstuff.WidthScale;
|
||||
var HeightScale = growstuff.HeightScale;
|
||||
|
||||
function BarGroup(data) {
|
||||
this._data = data;
|
||||
}
|
||||
|
||||
BarGroup.prototype.render = function(root){
|
||||
|
||||
var data = this._data;
|
||||
var bars = this._data.bars;
|
||||
var widthScale = new WidthScale(data).render();
|
||||
var heightScale = new HeightScale(data).render();
|
||||
|
||||
return root.append('g')
|
||||
.attr("class", "bar")
|
||||
.selectAll("rect")
|
||||
.data(bars.map(function(bar) { return bar.value; }))
|
||||
.enter()
|
||||
.append("rect")
|
||||
.attr("y", function(d, i){
|
||||
return heightScale(i);
|
||||
|
||||
})
|
||||
.attr("height", heightScale.rangeBand())
|
||||
.attr("fill", data.bar_color)
|
||||
.attr("width", function(d){
|
||||
return widthScale(d);
|
||||
})
|
||||
.append("title")
|
||||
.text(function(d){
|
||||
return 'This value is ' + d + '.';
|
||||
});
|
||||
};
|
||||
|
||||
growstuff.BarGroup = BarGroup;
|
||||
|
||||
}());
|
||||
40
app/assets/javascripts/graphs/bar_label_group.js
Normal file
40
app/assets/javascripts/graphs/bar_label_group.js
Normal file
@@ -0,0 +1,40 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/*
|
||||
This file draws the labels to the left of each bar.
|
||||
*/
|
||||
|
||||
var growstuff = (window.growstuff = window.growstuff || {});
|
||||
|
||||
function BarLabelGroup(data) {
|
||||
this._data = data;
|
||||
}
|
||||
|
||||
BarLabelGroup.prototype.render = function(d3){
|
||||
var bars = this._data.bars;
|
||||
//vvcopy pasta from spike vv -- this is a good candidate for refactor
|
||||
var barHeight = 40;
|
||||
|
||||
return d3.append('g')
|
||||
.attr("class", "bar-label")
|
||||
.selectAll("text")
|
||||
.data(bars.map(function(bar){ return bar.name;}))
|
||||
.enter()
|
||||
.append("text")
|
||||
.attr('x', -80)
|
||||
.attr('y', function(d, i){
|
||||
//shrink the margin between each label to give them an even spread with
|
||||
//bars
|
||||
var barLabelSpread = 2/3;
|
||||
//move them downward to line up with bars
|
||||
var barLabelTopEdge = 17;
|
||||
return i * barHeight * (barLabelSpread) + barLabelTopEdge;
|
||||
})
|
||||
.text(function(d){return d});
|
||||
|
||||
};
|
||||
|
||||
growstuff.BarLabelGroup = BarLabelGroup;
|
||||
|
||||
}())
|
||||
29
app/assets/javascripts/graphs/height_scale.js
Normal file
29
app/assets/javascripts/graphs/height_scale.js
Normal file
@@ -0,0 +1,29 @@
|
||||
//=require d3
|
||||
|
||||
/*
|
||||
Height Scale is used to map the number of bars to the display size of
|
||||
the svg
|
||||
*/
|
||||
|
||||
(function(){
|
||||
'use strict';
|
||||
|
||||
var growstuff = (window.growstuff = window.growstuff || {});
|
||||
|
||||
function HeightScale(data){
|
||||
this._data = data;
|
||||
}
|
||||
|
||||
HeightScale.prototype.render = function(){
|
||||
var data = this._data;
|
||||
var scaleType = data.height.scale;
|
||||
var axisSize = data.height.size;
|
||||
|
||||
return d3.scale[scaleType]()
|
||||
.domain(d3.range(data.bars.length))
|
||||
.rangeRoundBands([0, data.height.size], 0.05, 0);
|
||||
};
|
||||
|
||||
growstuff.HeightScale = HeightScale;
|
||||
|
||||
}());
|
||||
51
app/assets/javascripts/graphs/horizontal_bar_graph.js
Normal file
51
app/assets/javascripts/graphs/horizontal_bar_graph.js
Normal file
@@ -0,0 +1,51 @@
|
||||
//= require d3
|
||||
//= require graphs/bar_group
|
||||
//= require graphs/bar_label_group
|
||||
|
||||
/*
|
||||
Horizontal Bar Graph represents sum total of the graph including all of the parts:
|
||||
Bars
|
||||
Bar Labels
|
||||
|
||||
The main dimensions of the graph are rendered here.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var growstuff = (window.growstuff = window.growstuff || {});
|
||||
var BarGroup = growstuff.BarGroup;
|
||||
var BarLabelGroup = growstuff.BarLabelGroup;
|
||||
|
||||
function HorizontalBarGraph(data) {
|
||||
this._data = data;
|
||||
this._d3 = d3;
|
||||
}
|
||||
|
||||
HorizontalBarGraph.prototype.render = function(root) {
|
||||
var bars = this._data.bars;
|
||||
var width = this._data.width;
|
||||
var height = this._data.height;
|
||||
|
||||
var barLabelGroup = new BarLabelGroup(this._data);
|
||||
var margin = this._data.margin;
|
||||
|
||||
var barGroup = new BarGroup(this._data);
|
||||
|
||||
var svg = root
|
||||
.append("svg")
|
||||
.attr("width", width.size + margin.left + margin.right)
|
||||
.attr("height", height.size + margin.top + margin.bottom)
|
||||
.append("g")
|
||||
.attr("class","bar-graph")
|
||||
.attr("transform","translate(" + margin.left + "," + margin.top + ")");
|
||||
|
||||
|
||||
barGroup.render(svg);
|
||||
barLabelGroup.render(svg);
|
||||
|
||||
return svg;
|
||||
};
|
||||
|
||||
growstuff.HorizontalBarGraph = HorizontalBarGraph;
|
||||
}());
|
||||
33
app/assets/javascripts/graphs/width_scale.js
Normal file
33
app/assets/javascripts/graphs/width_scale.js
Normal file
@@ -0,0 +1,33 @@
|
||||
//=require d3
|
||||
|
||||
/*
|
||||
Width scale is used to map the value for the length of each bar
|
||||
to the display size of the svg
|
||||
*/
|
||||
|
||||
(function(){
|
||||
'use strict';
|
||||
|
||||
var growstuff = (window.growstuff = window.growstuff || {});
|
||||
|
||||
function WidthScale (data){
|
||||
this._data = data;
|
||||
}
|
||||
|
||||
WidthScale.prototype.render = function() {
|
||||
var data = this._data;
|
||||
var scaleType = data.width.scale;
|
||||
var axisSize = data.width.size;
|
||||
|
||||
return d3.scale[scaleType]()
|
||||
.domain([0, this.getMaxValue()])
|
||||
.range([0, axisSize]);
|
||||
};
|
||||
|
||||
WidthScale.prototype.getMaxValue = function(){
|
||||
return d3.max(this._data.bars.map(function(bar) { return bar.value; }));
|
||||
}
|
||||
|
||||
growstuff.WidthScale = WidthScale;
|
||||
|
||||
}());
|
||||
18
app/assets/javascripts/posts.js
Normal file
18
app/assets/javascripts/posts.js
Normal file
@@ -0,0 +1,18 @@
|
||||
$(document).ready(function () {
|
||||
$('.post-like').show();
|
||||
|
||||
$('.post-like').on('ajax:success', function(event, data) {
|
||||
var like_control = $('#post-' + data.id + ' .post-like');
|
||||
|
||||
$('#post-' + data.id + ' .like-count').text(data.description);
|
||||
if (data.liked_by_member) {
|
||||
like_control.data("method", "delete");
|
||||
like_control.attr("href", data.url);
|
||||
like_control.text("Unlike");
|
||||
} else {
|
||||
like_control.data("method", "post");
|
||||
like_control.attr("href", '/likes.json?post_id=' + data.id);
|
||||
like_control.text("Like");
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -5,3 +5,4 @@
|
||||
@import 'leaflet.markercluster.default'
|
||||
@import 'custom_bootstrap/custom_bootstrap'
|
||||
@import 'overrides'
|
||||
@import 'graphs'
|
||||
|
||||
@@ -11,12 +11,13 @@ $brown: #413f3b
|
||||
$green: #5f8e43
|
||||
$blue: #2f4365
|
||||
$red: #8e4d43
|
||||
$orange: #b2685c
|
||||
$orange: #ffa500
|
||||
$yellow: #b2935c
|
||||
|
||||
$body-bg: $beige
|
||||
$text-color: $brown
|
||||
$link-color: $green
|
||||
$graph-hover: $orange
|
||||
|
||||
$brand-primary: $green
|
||||
|
||||
|
||||
2
app/assets/stylesheets/graphs.sass
Normal file
2
app/assets/stylesheets/graphs.sass
Normal file
@@ -0,0 +1,2 @@
|
||||
.bar rect:hover
|
||||
fill: $graph-hover
|
||||
@@ -319,9 +319,6 @@ $state-success-bg: lighten($green, 50%)
|
||||
text-overflow: ellipsis
|
||||
overflow: hidden
|
||||
|
||||
#gardens_panel_body
|
||||
height: 20em
|
||||
|
||||
.form-group.required .control-label:before
|
||||
content: "* "
|
||||
color: red
|
||||
|
||||
@@ -37,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
|
||||
@@ -48,7 +48,7 @@ class AccountTypesController < ApplicationController
|
||||
def update
|
||||
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
|
||||
@@ -60,7 +60,7 @@ class AccountTypesController < ApplicationController
|
||||
@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
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ class AccountsController < ApplicationController
|
||||
def update
|
||||
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
|
||||
|
||||
@@ -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]}"
|
||||
|
||||
@@ -7,13 +7,12 @@ class ApplicationController < ActionController::Base
|
||||
before_action :set_locale
|
||||
|
||||
def store_location
|
||||
if (request.path != "/members/sign_in" &&
|
||||
request.path != "/members/sign_up" &&
|
||||
request.path != "/members/password/new" &&
|
||||
request.path != "/members/password/edit" &&
|
||||
request.path != "/members/confirmation" &&
|
||||
request.path != "/members/sign_out" &&
|
||||
!request.xhr?)
|
||||
unless (request.path.in?(["/members/sign_in",
|
||||
"/members/sign_up",
|
||||
"/members/password/new",
|
||||
"/members/password/edit",
|
||||
"/members/confirmation",
|
||||
"/members/sign_out"]) || request.xhr?)
|
||||
store_location_for(:member, request.fullpath)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -10,12 +10,14 @@ class CropsController < ApplicationController
|
||||
def index
|
||||
@sort = params[:sort]
|
||||
@crops = if @sort == 'alpha'
|
||||
Crop.includes(:scientific_names, { plantings: :photos })
|
||||
Crop.includes(:scientific_names, plantings: :photos)
|
||||
else
|
||||
popular_crops
|
||||
end
|
||||
@paginated_crops = @crops.approved.paginate(page: params[:page])
|
||||
|
||||
@has_requested_pending = Crop.pending_approval.where(requester: current_member).count if current_member
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.json { render json: @crops }
|
||||
@@ -31,6 +33,10 @@ class CropsController < ApplicationController
|
||||
end
|
||||
end
|
||||
|
||||
def requested
|
||||
@requested = Crop.pending_approval.where(requester: current_member).paginate(page: params[:page])
|
||||
end
|
||||
|
||||
# GET /crops/wrangle
|
||||
def wrangle
|
||||
@approval_status = params[:approval_status]
|
||||
@@ -74,7 +80,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|
|
||||
@@ -119,7 +125,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
|
||||
@@ -136,9 +142,9 @@ 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!
|
||||
Notifier.new_crop_request(w, @crop).deliver_now!
|
||||
end
|
||||
end
|
||||
|
||||
@@ -166,8 +172,8 @@ class CropsController < ApplicationController
|
||||
if previous_status == "pending"
|
||||
requester = @crop.requester
|
||||
new_status = @crop.approval_status
|
||||
Notifier.crop_request_approved(requester, @crop).deliver_later! if new_status == "approved"
|
||||
Notifier.crop_request_rejected(requester, @crop).deliver_later! if new_status == "rejected"
|
||||
Notifier.crop_request_approved(requester, @crop).deliver_now! if new_status == "approved"
|
||||
Notifier.crop_request_rejected(requester, @crop).deliver_now! if new_status == "rejected"
|
||||
end
|
||||
format.html { redirect_to @crop, notice: 'Crop was successfully updated.' }
|
||||
format.json { head :no_content }
|
||||
@@ -192,7 +198,7 @@ class CropsController < ApplicationController
|
||||
private
|
||||
|
||||
def popular_crops
|
||||
Crop.popular.includes(:scientific_names, { plantings: :photos })
|
||||
Crop.popular.includes(:scientific_names, plantings: :photos)
|
||||
end
|
||||
|
||||
def recreate_names(param_name, name_type)
|
||||
|
||||
@@ -6,11 +6,8 @@ class GardensController < ApplicationController
|
||||
# GET /gardens.json
|
||||
def index
|
||||
@owner = Member.find_by(slug: params[:owner])
|
||||
@gardens = if @owner
|
||||
@owner.gardens.paginate(page: params[:page])
|
||||
else
|
||||
Garden.paginate(page: params[:page])
|
||||
end
|
||||
@show_all = params[:all] == '1'
|
||||
@gardens = gardens
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
@@ -45,12 +42,11 @@ class GardensController < ApplicationController
|
||||
# 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,7 +61,7 @@ class GardensController < ApplicationController
|
||||
def update
|
||||
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" }
|
||||
@@ -82,7 +78,7 @@ class GardensController < ApplicationController
|
||||
|
||||
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
|
||||
@@ -94,4 +90,12 @@ class GardensController < ApplicationController
|
||||
params.require(:garden).permit(:name, :slug, :owner_id, :description, :active,
|
||||
:location, :latitude, :longitude, :area, :area_unit)
|
||||
end
|
||||
|
||||
def gardens
|
||||
g = @owner ? @owner.gardens : Garden.all
|
||||
g = g.active unless @show_all
|
||||
g = g.includes(:owner).order(:name)
|
||||
g = g.paginate(page: params[:page])
|
||||
g
|
||||
end
|
||||
end
|
||||
|
||||
@@ -26,10 +26,15 @@ 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_or_initialize_by(id: params[:crop_id])
|
||||
@@ -42,18 +47,17 @@ class HarvestsController < ApplicationController
|
||||
|
||||
# GET /harvests/1/edit
|
||||
def edit
|
||||
@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" }
|
||||
@@ -67,7 +71,7 @@ class HarvestsController < ApplicationController
|
||||
def update
|
||||
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" }
|
||||
@@ -90,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
|
||||
|
||||
71
app/controllers/likes_controller.rb
Normal file
71
app/controllers/likes_controller.rb
Normal file
@@ -0,0 +1,71 @@
|
||||
class LikesController < ApplicationController
|
||||
before_action :authenticate_member!, except: :index
|
||||
|
||||
respond_to :html, :json
|
||||
|
||||
def create
|
||||
@like = Like.new
|
||||
@like.member = current_member
|
||||
@like.likeable = find_likeable
|
||||
|
||||
respond_to do |format|
|
||||
if @like.save
|
||||
format.html { redirect_to @like.likeable }
|
||||
format.json do
|
||||
render(
|
||||
json: {
|
||||
id: @like.likeable.id,
|
||||
liked_by_member: true,
|
||||
description: ActionController::Base.helpers.pluralize(@like.likeable.likes.count, "like"),
|
||||
url: like_path(@like, format: :json)
|
||||
},
|
||||
status: 201
|
||||
)
|
||||
end
|
||||
else
|
||||
format.html do
|
||||
flash[:error] = 'Unable to like'
|
||||
redirect_to @like.likeable
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
like = Like.find(params[:id])
|
||||
likeable = like.likeable
|
||||
respond_to do |format|
|
||||
if like.destroy
|
||||
format.html { redirect_to likeable }
|
||||
format.json do
|
||||
render(
|
||||
json: {
|
||||
id: likeable.id,
|
||||
liked_by_member: false,
|
||||
description: ActionController::Base.helpers.pluralize(likeable.likes.count, "like"),
|
||||
url: likes_path(Like.new, "#{likeable.class.name.underscore}_id", likeable.id, format: :json)
|
||||
},
|
||||
status: 200
|
||||
)
|
||||
end
|
||||
else
|
||||
format.html do
|
||||
flash[:error] = 'Unable to unlike'
|
||||
redirect_to likeable
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_likeable
|
||||
params.each do |name, value|
|
||||
return Regexp.last_match[1].classify.constantize.find(value) if name =~ /(.+)_id$/
|
||||
end
|
||||
end
|
||||
|
||||
def like_params
|
||||
params.require(:like).permit(:member, :likeable)
|
||||
end
|
||||
end
|
||||
@@ -30,6 +30,7 @@ class MembersController < ApplicationController
|
||||
@flickr_auth = @member.auth('flickr')
|
||||
@facebook_auth = @member.auth('facebook')
|
||||
@posts = @member.posts
|
||||
@gardens = @member.gardens.active.order(:name)
|
||||
# The garden form partial is called from the "New Garden" tab;
|
||||
# it requires a garden to be passed in @garden.
|
||||
# The new garden is not persisted unless Garden#save is called.
|
||||
@@ -74,10 +75,10 @@ class MembersController < ApplicationController
|
||||
@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."
|
||||
flash.now[:alert] = I18n.t('members.unsubscribe.error')
|
||||
end
|
||||
|
||||
def finish_signup
|
||||
@@ -87,9 +88,9 @@ class MembersController < ApplicationController
|
||||
if @member.update(member_params)
|
||||
@member.skip_reconfirmation!
|
||||
bypass_sign_in(@member)
|
||||
redirect_to root_path, notice: 'Welcome.'
|
||||
redirect_to root_path, notice: I18n.t('members.welcome')
|
||||
else
|
||||
flash[:alert] = 'Failed to complete signup'
|
||||
flash[:alert] = I18n.t('members.signup.error')
|
||||
@show_errors = true
|
||||
end
|
||||
end
|
||||
|
||||
@@ -23,22 +23,21 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
||||
action = Growstuff::OauthSignupAction.new
|
||||
|
||||
@authentication = nil
|
||||
if auth
|
||||
member = action.find_or_create_from_authorization(auth)
|
||||
@authentication = action.establish_authentication(auth, member)
|
||||
|
||||
unless action.member_created?
|
||||
sign_in_and_redirect member, event: :authentication # this will throw if @user is not activated
|
||||
set_flash_message(:notice, :success, kind: auth['provider']) if is_navigational_format?
|
||||
else
|
||||
raise "Invalid provider" unless ['facebook', 'twitter', 'flickr'].index(auth['provider'].to_s)
|
||||
return redirect_to request.env['omniauth.origin'] || edit_member_registration_path unless auth
|
||||
|
||||
session["devise.#{auth['provider']}_data"] = request.env["omniauth.auth"]
|
||||
sign_in member
|
||||
redirect_to finish_signup_url(member)
|
||||
end
|
||||
member = action.find_or_create_from_authorization(auth)
|
||||
@authentication = action.establish_authentication(auth, member)
|
||||
|
||||
unless action.member_created?
|
||||
sign_in_and_redirect member, event: :authentication # this will throw if @user is not activated
|
||||
set_flash_message(:notice, :success, kind: auth['provider']) if is_navigational_format?
|
||||
else
|
||||
redirect_to request.env['omniauth.origin'] || edit_member_registration_path
|
||||
raise "Invalid provider" unless ['facebook', 'twitter', 'flickr'].index(auth['provider'].to_s)
|
||||
|
||||
session["devise.#{auth['provider']}_data"] = request.env["omniauth.auth"]
|
||||
sign_in member
|
||||
redirect_to finish_signup_url(member)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -5,15 +5,10 @@ class PlantingsController < ApplicationController
|
||||
# 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,7 +36,7 @@ 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
|
||||
@@ -127,4 +122,16 @@ class PlantingsController < ApplicationController
|
||||
(planting.finished_at - planting.planted_at).to_i
|
||||
end
|
||||
end
|
||||
|
||||
def plantings
|
||||
p = if @owner
|
||||
@owner.plantings
|
||||
elsif @crop
|
||||
@crop.plantings
|
||||
else
|
||||
Planting
|
||||
end
|
||||
p = p.current unless @show_all
|
||||
p.includes(:owner, :crop, :garden).order(:created_at).paginate(page: params[:page])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -8,9 +8,9 @@ class PostsController < ApplicationController
|
||||
def index
|
||||
@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
|
||||
|
||||
@@ -7,13 +7,7 @@ class SeedsController < ApplicationController
|
||||
def index
|
||||
@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
|
||||
@crop.seeds.includes(:owner, :crop).paginate(page: params[:page])
|
||||
else
|
||||
Seed.includes(:owner, :crop).paginate(page: params[:page])
|
||||
end
|
||||
@seeds = seeds(owner: @owner, crop: @crop)
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
@@ -109,4 +103,14 @@ class SeedsController < ApplicationController
|
||||
:days_until_maturity_min, :days_until_maturity_max, :organic, :gmo,
|
||||
:heirloom, :tradable_to, :slug)
|
||||
end
|
||||
|
||||
def seeds(owner: nil, crop: nil)
|
||||
if owner
|
||||
owner.seeds
|
||||
elsif crop
|
||||
crop.seeds
|
||||
else
|
||||
Seed
|
||||
end.includes(:owner, :crop).paginate(page: params[:page])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -70,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
|
||||
@@ -83,4 +81,29 @@ module ApplicationHelper
|
||||
model_name = model.model_name.human(count: size)
|
||||
"#{size} #{model_name}"
|
||||
end
|
||||
|
||||
def show_inactive_tickbox_path(type, owner, show_all)
|
||||
all = show_all ? '' : 1
|
||||
if owner
|
||||
plantings_by_owner_path(owner: owner.slug, all: all) if type == 'plantings'
|
||||
gardens_by_owner_path(owner: owner.slug, all: all) if type == 'gardens'
|
||||
else
|
||||
plantings_path(all: all) if type == 'plantings'
|
||||
gardens_path(all: all) if type == 'gardens'
|
||||
end
|
||||
end
|
||||
|
||||
def title(type, owner, crop)
|
||||
if owner
|
||||
t(".title.owner_#{type}", owner: owner.login_name)
|
||||
elsif crop
|
||||
t(".title.crop_#{type}", crop: crop.name)
|
||||
else
|
||||
t(".title.default")
|
||||
end
|
||||
end
|
||||
|
||||
def og_description(description)
|
||||
strip_tags(description).split(' ')[0..20].join(' ')
|
||||
end
|
||||
end
|
||||
|
||||
@@ -18,4 +18,8 @@ module CropsHelper
|
||||
"You have an unknown quantity of seeds of this crop."
|
||||
end
|
||||
end
|
||||
|
||||
def crop_ebay_seeds_url(crop)
|
||||
"http://rover.ebay.com/rover/1/705-53470-19255-0/1?icep_ff3=9&pub=5575213277&toolid=10001&campid=5337940151&customid=&icep_uq=#{URI.escape crop.name}&icep_sellerId=&icep_ex_kw=&icep_sortBy=12&icep_catId=181003&icep_minPrice=&icep_maxPrice=&ipn=psmain&icep_vectorid=229515&kwid=902099&mtid=824&kw=lg" # rubocop:disable Metrics/LineLength
|
||||
end
|
||||
end
|
||||
|
||||
@@ -9,6 +9,14 @@ module GardensHelper
|
||||
end
|
||||
end
|
||||
|
||||
def gardens_active_tickbox_path(owner, show_all)
|
||||
show_inactive_tickbox_path('gardens', owner, show_all)
|
||||
end
|
||||
|
||||
def display_garden_name(garden)
|
||||
truncate(garden.name, length: 50, separator: ' ', omission: '... ')
|
||||
end
|
||||
|
||||
def display_garden_plantings(plantings)
|
||||
if plantings.blank?
|
||||
"None"
|
||||
|
||||
@@ -28,7 +28,7 @@ module HarvestsHelper
|
||||
end
|
||||
|
||||
def display_harvest_description(harvest)
|
||||
return "No description provided." if harvest.description.empty?
|
||||
return "No description provided." if harvest.description.nil?
|
||||
harvest.description
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
module PlantingsHelper
|
||||
def display_days_before_maturity(planting)
|
||||
if planting.finished?
|
||||
"0"
|
||||
elsif !planting.finished_at.nil?
|
||||
((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"
|
||||
# First try to calc from finished/finished_at
|
||||
if planting.finished? || planting.finished_at.present?
|
||||
planting.days_until_finished.to_s
|
||||
# then try to calc from planted at + maturity
|
||||
elsif planting.planted_at.present? && planting.days_before_maturity.present?
|
||||
planting.days_until_mature.to_s
|
||||
else
|
||||
((p = (planting.planted_at + planting.days_before_maturity) - Date.current).to_i <= 0) ? "0" : p.to_i.to_s
|
||||
"unknown"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -40,4 +40,8 @@ module PlantingsHelper
|
||||
"#{planting.owner}."
|
||||
end
|
||||
end
|
||||
|
||||
def plantings_active_tickbox_path(owner, show_all)
|
||||
show_inactive_tickbox_path('plantings', owner, show_all)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -40,6 +40,7 @@ class Ability
|
||||
|
||||
# members can see even rejected or pending crops if they requested it
|
||||
can :read, Crop, requester_id: member.id
|
||||
can :requested, Crop # see list of crops they've requested
|
||||
|
||||
# managing your own user settings
|
||||
can :update, Member, id: member.id
|
||||
@@ -57,7 +58,7 @@ class Ability
|
||||
# note we don't support update for notifications
|
||||
|
||||
# only crop wranglers can create/edit/destroy crops
|
||||
if member.has_role? :crop_wrangler
|
||||
if member.role? :crop_wrangler
|
||||
can :wrangle, Crop
|
||||
can :manage, Crop
|
||||
can :manage, ScientificName
|
||||
@@ -92,6 +93,8 @@ class Ability
|
||||
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, Photo
|
||||
can :update, Photo, owner_id: member.id
|
||||
@@ -122,7 +125,7 @@ class Ability
|
||||
can :destroy, Follow
|
||||
cannot :destroy, Follow, followed_id: member.id # can't unfollow yourself
|
||||
|
||||
return unless member.has_role? :admin
|
||||
return unless member.role? :admin
|
||||
|
||||
can :read, :all
|
||||
can :manage, :all
|
||||
|
||||
@@ -9,8 +9,7 @@ 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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
8
app/models/concerns/likeable.rb
Normal file
8
app/models/concerns/likeable.rb
Normal file
@@ -0,0 +1,8 @@
|
||||
module Likeable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
has_many :likes, as: :likeable, dependent: :destroy
|
||||
has_many :members, through: :likes
|
||||
end
|
||||
end
|
||||
@@ -18,7 +18,7 @@ class Crop < ActiveRecord::Base
|
||||
|
||||
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
|
||||
## 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
|
||||
min_gram: 3,
|
||||
max_gram: 10,
|
||||
# token_chars: Elasticsearch will split on characters
|
||||
# that don’t 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
|
||||
tokenizer: "gs_edgeNGram_tokenizer",
|
||||
filter: ["lowercase"]
|
||||
}
|
||||
},
|
||||
}
|
||||
} do
|
||||
mappings dynamic: 'false' do
|
||||
indexes :id, type: 'long'
|
||||
@@ -103,18 +103,19 @@ class Crop < ActiveRecord::Base
|
||||
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)
|
||||
def update_index(_name_obj)
|
||||
__elasticsearch__.index_document if ENV["GROWSTUFF_ELASTICSEARCH"] == "true"
|
||||
end
|
||||
|
||||
@@ -125,7 +126,7 @@ class Crop < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def default_scientific_name
|
||||
scientific_names.first.name if scientific_names.size > 0
|
||||
scientific_names.first.name unless scientific_names.empty?
|
||||
end
|
||||
|
||||
# crop.default_photo
|
||||
@@ -162,11 +163,11 @@ class Crop < ActiveRecord::Base
|
||||
# key: plant part (eg. 'fruit')
|
||||
# value: count of how many times it's been used by harvests
|
||||
def popular_plant_parts
|
||||
popular_plant_parts = Hash.new(0)
|
||||
harvests.each do |h|
|
||||
popular_plant_parts[h.plant_part] += 1 if h.plant_part
|
||||
end
|
||||
popular_plant_parts
|
||||
PlantPart.joins(:harvests)
|
||||
.where("crop_id = ?", id)
|
||||
.order("count_harvests_id DESC")
|
||||
.group("plant_parts.id", "plant_parts.name")
|
||||
.count("harvests.id")
|
||||
end
|
||||
|
||||
def interesting?
|
||||
@@ -190,7 +191,7 @@ class Crop < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def approval_statuses
|
||||
['rejected', 'pending', 'approved']
|
||||
%w(rejected pending approved)
|
||||
end
|
||||
|
||||
def reasons_for_rejection
|
||||
@@ -199,7 +200,7 @@ class Crop < ActiveRecord::Base
|
||||
|
||||
# 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|
|
||||
@@ -218,7 +219,7 @@ class Crop < ActiveRecord::Base
|
||||
# - 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')
|
||||
@@ -246,16 +247,16 @@ class Crop < ActiveRecord::Base
|
||||
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')
|
||||
|
||||
return unless names_to_add.size > 0
|
||||
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')
|
||||
@@ -266,7 +267,7 @@ class Crop < ActiveRecord::Base
|
||||
return if alternate_names.blank?
|
||||
|
||||
cropbot = Member.find_by!(login_name: 'cropbot')
|
||||
names_to_add = alternate_names.split(%r{,\s*})
|
||||
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
|
||||
@@ -281,23 +282,21 @@ class Crop < ActiveRecord::Base
|
||||
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
|
||||
)
|
||||
response.records.to_a
|
||||
else
|
||||
@@ -320,7 +319,7 @@ class Crop < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
def Crop.case_insensitive_name(name)
|
||||
def self.case_insensitive_name(name)
|
||||
where(["lower(name) = :value", { value: name.downcase }])
|
||||
end
|
||||
|
||||
@@ -339,22 +338,22 @@ class Crop < ActiveRecord::Base
|
||||
def create_crop_in_list(list_name, name)
|
||||
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|
|
||||
data[p.send("#{col_name}")] += 1 if !p.send("#{col_name}").blank?
|
||||
end
|
||||
data
|
||||
plantings.unscoped
|
||||
.where(crop_id: id)
|
||||
.where.not(col_name => nil)
|
||||
.group(col_name)
|
||||
.count
|
||||
end
|
||||
|
||||
# Custom validations
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -30,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 = {
|
||||
@@ -38,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,
|
||||
@@ -47,12 +48,12 @@ class Garden < ActiveRecord::Base
|
||||
after_validation :cleanup_area
|
||||
|
||||
def cleanup_area
|
||||
self.area = nil if area == 0
|
||||
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,
|
||||
@@ -62,7 +63,7 @@ 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
|
||||
|
||||
@@ -7,6 +7,7 @@ class Harvest < ActiveRecord::Base
|
||||
belongs_to :crop
|
||||
belongs_to :owner, class_name: 'Member'
|
||||
belongs_to :plant_part
|
||||
belongs_to :planting
|
||||
|
||||
default_scope { order('created_at DESC') }
|
||||
|
||||
@@ -19,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 = {
|
||||
@@ -33,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,
|
||||
@@ -47,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,
|
||||
@@ -60,52 +62,58 @@ 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
|
||||
return if self.weight_unit.nil?
|
||||
weight_string = "#{self.weight_quantity} #{self.weight_unit}"
|
||||
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
|
||||
self.quantity = nil if quantity == 0
|
||||
self.quantity = nil if quantity && quantity.zero?
|
||||
self.unit = nil if quantity.blank?
|
||||
self.weight_quantity = nil if weight_quantity == 0
|
||||
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
|
||||
def to_s
|
||||
# 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'
|
||||
'individual '
|
||||
elsif self.quantity == 1
|
||||
"#{self.unit} of "
|
||||
else
|
||||
"#{self.unit.pluralize} of "
|
||||
end
|
||||
"#{quantity_to_human} #{unit_to_human} #{crop_name_to_human} #{weight_to_human}".strip
|
||||
end
|
||||
|
||||
def quantity_to_human
|
||||
return number_to_human(quantity.to_s, strip_insignificant_zeros: true) if quantity
|
||||
""
|
||||
end
|
||||
|
||||
def unit_to_human
|
||||
return "" unless quantity
|
||||
if unit == 'individual'
|
||||
'individual'
|
||||
elsif quantity == 1
|
||||
"#{unit} of"
|
||||
else
|
||||
"#{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}"
|
||||
else
|
||||
"#{self.crop.name.pluralize}"
|
||||
end
|
||||
def weight_to_human
|
||||
return "" unless weight_quantity
|
||||
"weighing #{number_to_human(weight_quantity, strip_insignificant_zeros: true)} #{weight_unit}"
|
||||
end
|
||||
|
||||
if self.weight_quantity
|
||||
string += " weighing #{number_to_human(self.weight_quantity, strip_insignificant_zeros: true)}"\
|
||||
" #{self.weight_unit}"
|
||||
end
|
||||
|
||||
string
|
||||
def crop_name_to_human
|
||||
if unit != 'individual' # buckets of apricot*s*
|
||||
crop.name.pluralize
|
||||
elsif quantity == 1
|
||||
crop.name
|
||||
else
|
||||
crop.name.pluralize
|
||||
end.to_s
|
||||
end
|
||||
|
||||
def default_photo
|
||||
|
||||
6
app/models/like.rb
Normal file
6
app/models/like.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
class Like < ActiveRecord::Base
|
||||
belongs_to :member
|
||||
belongs_to :likeable, polymorphic: true
|
||||
validates :member, :likeable, presence: true
|
||||
validates :member, uniqueness: { scope: :likeable }
|
||||
end
|
||||
@@ -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'
|
||||
@@ -27,6 +27,8 @@ class Member < ActiveRecord::Base
|
||||
|
||||
has_many :photos
|
||||
|
||||
has_many :likes, dependent: :destroy
|
||||
|
||||
default_scope { order("lower(login_name) asc") }
|
||||
scope :confirmed, -> { where('confirmed_at IS NOT NULL') }
|
||||
scope :located, -> { where("location <> '' and latitude IS NOT NULL and longitude IS NOT NULL") }
|
||||
@@ -57,8 +59,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: {
|
||||
@@ -100,7 +102,7 @@ class Member < ActiveRecord::Base
|
||||
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
|
||||
|
||||
@@ -114,9 +116,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
|
||||
@@ -124,7 +124,7 @@ class Member < ActiveRecord::Base
|
||||
account.save
|
||||
end
|
||||
|
||||
def is_paid?
|
||||
def paid?
|
||||
if account.account_type.is_permanent_paid
|
||||
true
|
||||
elsif account.account_type.is_paid && account.paid_until >= Time.zone.now
|
||||
@@ -176,7 +176,7 @@ class Member < ActiveRecord::Base
|
||||
|
||||
# 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
|
||||
@@ -191,27 +191,25 @@ class Member < ActiveRecord::Base
|
||||
false
|
||||
end
|
||||
|
||||
def Member.login_name_or_email(login)
|
||||
def self.login_name_or_email(login)
|
||||
where(["lower(login_name) = :value OR lower(email) = :value", { value: login.downcase }])
|
||||
end
|
||||
|
||||
def Member.case_insensitive_login_name(login)
|
||||
def self.case_insensitive_login_name(login)
|
||||
where(["lower(login_name) = :value", { value: login.downcase }])
|
||||
end
|
||||
|
||||
def Member.interesting
|
||||
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
|
||||
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 })
|
||||
@@ -223,42 +221,36 @@ class Member < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def update_newsletter_subscription
|
||||
if confirmed_at_changed? && newsletter # just signed up
|
||||
newsletter_subscribe
|
||||
elsif confirmed_at # i.e. after member's confirmed their account
|
||||
if newsletter_changed? # edited member settings
|
||||
if newsletter
|
||||
newsletter_subscribe
|
||||
else
|
||||
newsletter_unsubscribe
|
||||
end
|
||||
end
|
||||
return unless confirmed_at_changed? || newsletter_changed?
|
||||
|
||||
if newsletter
|
||||
newsletter_subscribe if confirmed_at_changed? || confirmed_at && newsletter_changed?
|
||||
elsif confirmed_at
|
||||
newsletter_unsubscribe
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
})
|
||||
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(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 }
|
||||
})
|
||||
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.find_by(followed_id: member.id) if already_following?(member)
|
||||
follows.find_by(followed_id: member.id) if already_following?(member)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -13,14 +13,14 @@ class Notification < ActiveRecord::Base
|
||||
after_create :send_email
|
||||
|
||||
def self.unread_count
|
||||
self.unread.size
|
||||
unread.size
|
||||
end
|
||||
|
||||
def replace_blank_subject
|
||||
self.subject = "(no subject)" if self.subject.nil? or self.subject =~ /^\s*$/
|
||||
self.subject = "(no subject)" if subject.nil? || subject =~ /^\s*$/
|
||||
end
|
||||
|
||||
def send_email
|
||||
Notifier.notify(self).deliver_later if self.recipient.send_notification_email
|
||||
Notifier.notify(self).deliver_now! if recipient.send_notification_email
|
||||
end
|
||||
end
|
||||
|
||||
@@ -17,7 +17,7 @@ class Order < ActiveRecord::Base
|
||||
# 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
|
||||
@@ -28,11 +28,9 @@ class Order < ActiveRecord::Base
|
||||
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
|
||||
items
|
||||
end
|
||||
@@ -42,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
|
||||
@@ -56,35 +54,27 @@ 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
|
||||
self.referral_code = referral_code.upcase.gsub /\s/, '' if referral_code
|
||||
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
|
||||
return member.orders if member
|
||||
when "order_id"
|
||||
order = Order.find_by(id: args[:for])
|
||||
if order
|
||||
return [order]
|
||||
end
|
||||
return [order] if order
|
||||
when "paypal_token"
|
||||
order = Order.find_by(paypal_express_token: args[:for])
|
||||
if order
|
||||
return [order]
|
||||
end
|
||||
return [order] if order
|
||||
when "paypal_payer_id"
|
||||
order = Order.find_by(paypal_express_payer_id: args[:for])
|
||||
if order
|
||||
return [order]
|
||||
end
|
||||
return [order] if order
|
||||
when "referral_code"
|
||||
# coerce to uppercase
|
||||
return Order.where(referral_code: args[:for].upcase)
|
||||
|
||||
@@ -3,8 +3,7 @@ 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)
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
require_relative '../constants/photo_models.rb'
|
||||
class Photo < ActiveRecord::Base
|
||||
belongs_to :owner, class_name: 'Member'
|
||||
|
||||
Growstuff::Constants::PhotoModels.relations.each do |relation|
|
||||
has_and_belongs_to_many relation.to_sym
|
||||
has_and_belongs_to_many relation.to_sym # rubocop:disable Rails/HasAndBelongsToMany
|
||||
end
|
||||
|
||||
before_destroy { all_associations.clear }
|
||||
@@ -12,13 +13,13 @@ class Photo < ActiveRecord::Base
|
||||
def all_associations
|
||||
associations = []
|
||||
Growstuff::Constants::PhotoModels.relations.each do |association_name|
|
||||
associations << self.send(association_name.to_s).to_a
|
||||
associations << send(association_name.to_s).to_a
|
||||
end
|
||||
associations.flatten!
|
||||
end
|
||||
|
||||
def destroy_if_unused
|
||||
self.destroy unless all_associations.size > 0
|
||||
destroy if all_associations.empty?
|
||||
end
|
||||
|
||||
# This is split into a side-effect free method and a side-effecting method
|
||||
@@ -26,7 +27,7 @@ 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 }
|
||||
{
|
||||
title: info.title || "Untitled",
|
||||
@@ -39,6 +40,6 @@ class Photo < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def set_flickr_metadata
|
||||
self.update_attributes(flickr_metadata)
|
||||
update_attributes(flickr_metadata)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,6 +6,7 @@ class Planting < ActiveRecord::Base
|
||||
belongs_to :garden
|
||||
belongs_to :owner, class_name: 'Member', counter_cache: true
|
||||
belongs_to :crop, counter_cache: true
|
||||
has_many :harvests, -> { order(harvested_at: :desc) }, dependent: :destroy
|
||||
|
||||
default_scope { order("created_at desc") }
|
||||
scope :finished, -> { where(finished: true) }
|
||||
@@ -63,17 +64,25 @@ 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
|
||||
"#{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
|
||||
@@ -103,6 +112,17 @@ class Planting < ActiveRecord::Base
|
||||
planted_at.present? && current_date.to_date >= planted_at
|
||||
end
|
||||
|
||||
def days_until_finished
|
||||
return 0 if finished?
|
||||
days = (finished_at - Date.current).to_i
|
||||
days.positive? ? days : 0
|
||||
end
|
||||
|
||||
def days_until_mature
|
||||
days = ((planted_at + days_before_maturity) - Date.current).to_i
|
||||
days.positive? ? days : 0
|
||||
end
|
||||
|
||||
def percentage_grown(current_date = Date.current)
|
||||
return nil unless days_before_maturity && planted?(current_date)
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
class Post < ActiveRecord::Base
|
||||
extend FriendlyId
|
||||
include Likeable
|
||||
friendly_id :author_date_subject, use: [:slugged, :finders]
|
||||
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 +13,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.case_insensitive_login_name($1).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.case_insensitive_login_name($1[1..-1]).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 +47,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 +71,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.case_insensitive_name($1).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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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|
|
||||
|
||||
@@ -14,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" },
|
||||
@@ -40,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" },
|
||||
@@ -51,21 +55,22 @@ 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'
|
||||
if tradable_to == 'nowhere'
|
||||
false
|
||||
else
|
||||
true
|
||||
@@ -81,21 +86,23 @@ class Seed < ActiveRecord::Base
|
||||
|
||||
# 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
|
||||
|
||||
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
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
= form_for @account_type do |f|
|
||||
- if @account_type.errors.any?
|
||||
#error_explanation
|
||||
%h2= "#{pluralize(@account_type.errors.size, "error")} prohibited this account_type from being saved:"
|
||||
%h2
|
||||
= pluralize(@account_type.errors.size, "error")
|
||||
prohibited this account_type from being saved:
|
||||
%ul
|
||||
- @account_type.errors.full_messages.each do |msg|
|
||||
%li= msg
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
-content_for :title, "Editing account type"
|
||||
- content_for :title, "Editing account type"
|
||||
|
||||
= render 'form'
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
%td= account_type.is_permanent_paid
|
||||
%td= link_to 'Show', account_type
|
||||
%td= link_to 'Edit', edit_account_type_path(account_type)
|
||||
%td= link_to 'Destroy', account_type, :method => :delete, :data => { :confirm => 'Are you sure?' }
|
||||
%td= link_to 'Destroy', account_type, method: :delete, data: { confirm: 'Are you sure?' }
|
||||
|
||||
%br
|
||||
|
||||
|
||||
@@ -12,6 +12,6 @@
|
||||
|
||||
= link_to 'Edit', edit_account_type_path(@account_type)
|
||||
\|
|
||||
= link_to 'Delete', @account_type, :method => :delete, :data => { :confirm => 'Are you sure?' }
|
||||
= link_to 'Delete', @account_type, method: :delete, data: { confirm: 'Are you sure?' }
|
||||
\|
|
||||
= link_to 'Back', account_types_path
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
= form_for @account do |f|
|
||||
- if @account.errors.any?
|
||||
#error_explanation
|
||||
%h2= "#{pluralize(@account.errors.size, "error")} prohibited this account from being saved:"
|
||||
%h2
|
||||
= pluralize(@account.errors.size, "error")
|
||||
prohibited this account from being saved:
|
||||
%ul
|
||||
- @account.errors.full_messages.each do |msg|
|
||||
%li= msg
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
%td= account.paid_until
|
||||
%td= link_to 'Show', account
|
||||
%td= link_to 'Edit', edit_account_path(account)
|
||||
%td= link_to 'Destroy', account, :method => :delete, :data => { :confirm => 'Are you sure?' }
|
||||
%td= link_to 'Destroy', account, method: :delete, data: { confirm: 'Are you sure?' }
|
||||
|
||||
%br
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
-content_for :title, 'Admin'
|
||||
- content_for :title, 'Admin'
|
||||
|
||||
%h2 Manage
|
||||
|
||||
@@ -12,4 +12,4 @@
|
||||
|
||||
%h2 Orders
|
||||
|
||||
=render "admin/orders/searchform"
|
||||
= render "admin/orders/searchform"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
-content_for :title, 'Newsletter subscribers'
|
||||
- content_for :title, 'Newsletter subscribers'
|
||||
|
||||
%p
|
||||
- @members.each do |m|
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
= form_tag(url_for(:controller => 'admin/orders', :action => 'search'), :method => :get, :class => 'form-inline') do
|
||||
= label_tag :distance, "Search orders:", :class => 'control-label'
|
||||
= form_tag(url_for(controller: 'admin/orders', action: 'search'), method: :get, class: 'form-inline') do
|
||||
= label_tag :distance, "Search orders:", class: 'control-label'
|
||||
= text_field_tag :search_text
|
||||
= select_tag :search_by, options_for_select({'Member' => 'member', 'Referral code' => 'referral_code', 'Order ID' => 'order_id', 'Paypal Token' => 'paypal_token', 'Paypal Payer ID' => 'paypal_payer_id' })
|
||||
= submit_tag "Search", :class => 'btn btn-primary'
|
||||
= select_tag :search_by,
|
||||
options_for_select('Member': 'member', 'Referral code': 'referral_code',
|
||||
'Order ID': 'order_id', 'Paypal Token': 'paypal_token',
|
||||
'Paypal Payer ID': 'paypal_payer_id')
|
||||
= submit_tag "Search", class: 'btn btn-primary'
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
-content_for :title, 'Admin Orders'
|
||||
- content_for :title, 'Admin Orders'
|
||||
|
||||
=render "admin/orders/searchform"
|
||||
= render "admin/orders/searchform"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-content_for :title, 'Search Orders'
|
||||
- content_for :title, 'Search Orders'
|
||||
|
||||
=render "admin/orders/searchform"
|
||||
= render "admin/orders/searchform"
|
||||
|
||||
- unless @orders.empty?
|
||||
%h2
|
||||
@@ -28,7 +28,7 @@
|
||||
%td
|
||||
= order.referral_code
|
||||
%td
|
||||
- if order.order_items.size > 0
|
||||
- unless order.order_items.empty?
|
||||
- order.order_items.each do |o|
|
||||
= o.quantity
|
||||
x
|
||||
@@ -36,4 +36,4 @@
|
||||
@
|
||||
= price_with_currency(o.price)
|
||||
%br/
|
||||
%td= link_to 'Details', order, :class => 'btn btn-default btn-xs'
|
||||
%td= link_to 'Details', order, class: 'btn btn-default btn-xs'
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
= form_for @alternate_name, :html => {:class => 'form-horizontal', :role => "form"} do |f|
|
||||
= form_for @alternate_name, html: { class: 'form-horizontal', role: "form" } do |f|
|
||||
- if @alternate_name.errors.any?
|
||||
#error_explanation
|
||||
%h2= "#{pluralize(@alternate_name.errors.size, "error")} prohibited this alternate_name from being saved:"
|
||||
%h2
|
||||
= pluralize(@alternate_name.errors.size, "error")
|
||||
prohibited this alternate_name from being saved:
|
||||
%ul
|
||||
- @alternate_name.errors.full_messages.each do |msg|
|
||||
%li= msg
|
||||
@@ -9,19 +11,22 @@
|
||||
%p
|
||||
%span.help-block
|
||||
For detailed crop wrangling guidelines, please consult the
|
||||
=link_to "crop wrangling guide", "http://wiki.growstuff.org/index.php/Crop_wrangling"
|
||||
= link_to "crop wrangling guide", "http://wiki.growstuff.org/index.php/Crop_wrangling"
|
||||
on the Growstuff wiki.
|
||||
|
||||
.form-group
|
||||
= f.label :crop_id, :class => 'control-label col-md-2'
|
||||
= f.label :crop_id, class: 'control-label col-md-2'
|
||||
.col-md-8
|
||||
= collection_select(:alternate_name, :crop_id, Crop.all, :id, :name, { :selected => @alternate_name.crop_id || @crop.id }, :class => 'form-control')
|
||||
= collection_select(:alternate_name, :crop_id,
|
||||
Crop.all, :id, :name,
|
||||
{ selected: @alternate_name.crop_id || @crop.id },
|
||||
class: 'form-control')
|
||||
|
||||
.form-group
|
||||
= f.label :name, :class => 'control-label col-md-2'
|
||||
= f.label :name, class: 'control-label col-md-2'
|
||||
.col-md-8
|
||||
= f.text_field :name, :class => 'form-control'
|
||||
= f.text_field :name, class: 'form-control'
|
||||
|
||||
.form-group
|
||||
.form-actions.col-md-offset-2.col-md-8
|
||||
= f.submit 'Save', :class => 'btn btn-primary'
|
||||
= f.submit 'Save', class: 'btn btn-primary'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
- content_for :title, "Listing alternate names"
|
||||
|
||||
- if can? :create, AlternateName
|
||||
%p= link_to 'New alternate name', new_alternate_name_path, :class => 'btn btn-primary'
|
||||
%p= link_to 'New alternate name', new_alternate_name_path, class: 'btn btn-primary'
|
||||
|
||||
%table
|
||||
%tr
|
||||
@@ -17,7 +17,10 @@
|
||||
%td= link_to 'Show', alternate_name
|
||||
%td
|
||||
- if can? :edit, alternate_name
|
||||
= link_to 'Edit', edit_alternate_name_path(alternate_name), :class => 'btn btn-default btn-xs'
|
||||
= link_to 'Edit', edit_alternate_name_path(alternate_name), class: 'btn btn-default btn-xs'
|
||||
%td
|
||||
- if can? :destroy, alternate_name
|
||||
= link_to 'Delete', alternate_name, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'
|
||||
= link_to 'Delete', alternate_name,
|
||||
method: :delete,
|
||||
data: { confirm: 'Are you sure?' },
|
||||
class: 'btn btn-default btn-xs'
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
%p#notice= notice
|
||||
|
||||
= render :partial => 'crops/approval_status_message', :locals => { :crop => @alternate_name.crop }
|
||||
= render partial: 'crops/approval_status_message', locals: { crop: @alternate_name.crop }
|
||||
|
||||
%p
|
||||
%b Alternate name:
|
||||
@@ -17,6 +17,6 @@
|
||||
= link_to @alternate_name.crop, @alternate_name.crop
|
||||
|
||||
- if can? :edit, @alternate_name
|
||||
= link_to 'Edit', edit_alternate_name_path(@alternate_name), :class => 'btn btn-default btn-xs'
|
||||
= link_to 'Edit', edit_alternate_name_path(@alternate_name), class: 'btn btn-default btn-xs'
|
||||
\|
|
||||
= link_to 'Back', alternate_names_path
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
= form_for(@comment, :html => {:class => "form-horizontal", :role => "form"}) do |f|
|
||||
= form_for(@comment, html: { class: "form-horizontal", role: "form" }) do |f|
|
||||
- if @comment.errors.any?
|
||||
#error_explanation
|
||||
%h2= "#{pluralize(@comment.errors.size, "error")} prohibited this comment from being saved:"
|
||||
%h2
|
||||
= pluralize(@comment.errors.size, "error")
|
||||
prohibited this comment from being saved:
|
||||
%ul
|
||||
- @comment.errors.full_messages.each do |msg|
|
||||
%li= msg
|
||||
|
||||
.form-group
|
||||
= f.label :body, "Your comment:"
|
||||
= f.text_area :body, :rows => 6, :class => 'form-control', :autofocus => 'autofocus'
|
||||
= f.text_area :body, rows: 6, class: 'form-control', autofocus: 'autofocus'
|
||||
%span.help-block
|
||||
= render :partial => "shared/markdown_help"
|
||||
= render partial: "shared/markdown_help"
|
||||
.actions
|
||||
= f.submit 'Post comment', :class => 'btn btn-primary'
|
||||
= f.submit 'Post comment', class: 'btn btn-primary'
|
||||
- if defined?(@post)
|
||||
.field
|
||||
= f.hidden_field :post_id, :value => @post.id
|
||||
= f.hidden_field :post_id, value: @post.id
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
.comment
|
||||
.row
|
||||
.col-md-1
|
||||
= render :partial => "members/avatar", :locals => { :member => comment.author }
|
||||
= render partial: "members/avatar", locals: { member: comment.author }
|
||||
.col-md-11
|
||||
.comment-meta
|
||||
Posted by
|
||||
@@ -17,11 +17,11 @@
|
||||
:growstuff_markdown
|
||||
#{ strip_tags comment.body }
|
||||
|
||||
- if can? :edit, comment or can? :destroy, comment
|
||||
- if can?(:edit, comment) || can?(:destroy, comment)
|
||||
.comment-actions
|
||||
- if can? :edit, comment
|
||||
= link_to 'Edit', edit_comment_path(comment), :class => 'btn btn-default btn-xs'
|
||||
= link_to 'Edit', edit_comment_path(comment), class: 'btn btn-default btn-xs'
|
||||
- if can? :destroy, comment
|
||||
= link_to 'Delete', comment, method: :delete, |
|
||||
data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'
|
||||
= link_to 'Delete', comment, method: :delete,
|
||||
data: { confirm: 'Are you sure?' }, class: 'btn btn-default btn-xs'
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
= content_for :title, "Recent comments"
|
||||
|
||||
%div.pagination
|
||||
.pagination
|
||||
= page_entries_info @comments
|
||||
= will_paginate @comments
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
%h2
|
||||
Comment on
|
||||
= link_to comment.post.subject, comment.post
|
||||
= render :partial => "single", :locals => { :comment => comment }
|
||||
= render partial: "single", locals: { comment: comment }
|
||||
|
||||
%div.pagination
|
||||
.pagination
|
||||
= page_entries_info @comments
|
||||
= will_paginate @comments
|
||||
|
||||
%p
|
||||
Subscribe to the #{ENV['GROWSTUFF_SITE_NAME']}
|
||||
= succeed "." do
|
||||
= link_to "comments RSS feed", comments_path(:format => 'rss')
|
||||
= link_to "comments RSS feed", comments_path(format: 'rss')
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
%rss{:version => 2.0}
|
||||
%rss{ version: 2.0 }
|
||||
%channel
|
||||
%title Recent comments on all posts (#{ENV['GROWSTUFF_SITE_NAME']})
|
||||
%link= comments_url
|
||||
@@ -16,6 +16,6 @@
|
||||
:escaped_markdown
|
||||
#{ strip_tags comment.body }
|
||||
|
||||
%pubDate= comment.created_at.to_s(:rfc822)
|
||||
%pubdate= comment.created_at.to_s(:rfc822)
|
||||
%link= post_url(comment.post)
|
||||
%guid= comment_url(comment)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
= content_for :title, "New comment"
|
||||
|
||||
= render :partial => "posts/single", :locals => { :post => @post || @comment.post, :subject => true }
|
||||
= render partial: "posts/single", locals: { post: @post || @comment.post, subject: true }
|
||||
|
||||
= render :partial => "posts/comments", :locals => {:post => @post || @comment.post}
|
||||
= render partial: "posts/comments", locals: { post: @post || @comment.post }
|
||||
|
||||
= render 'form'
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
= tag("meta", property: "og:image", content: avatar_uri(@comment.post.author, 200))
|
||||
= tag("meta", property: "og:image:user_generated", content: "true")
|
||||
= tag("meta", property: "og:title", content: @comment.post.subject)
|
||||
= tag("meta", property: "og:description", content: strip_tags(@comment.post.body).split(' ')[0..20].join(' '))
|
||||
= tag("meta", property: "og:description", content: og_description(@comment.post.body))
|
||||
= tag("meta", property: "og:type", content: "website")
|
||||
= tag("meta", property: "og:url", content: request.original_url)
|
||||
= tag("meta", property: "og:site_name", content: ENV['GROWSTUFF_SITE_NAME'])
|
||||
|
||||
= render :partial => "posts/single", :locals => { :post => @comment.post }
|
||||
= render partial: "posts/single", locals: { post: @comment.post }
|
||||
|
||||
%h2 Showing 1 comment
|
||||
|
||||
= render :partial => "single", :locals => { :comment => @comment }
|
||||
= render partial: "single", locals: { comment: @comment }
|
||||
|
||||
=link_to "View all comments", post_path(@comment.post)
|
||||
= link_to "View all comments", post_path(@comment.post)
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
%li
|
||||
= an.name
|
||||
- if can? :edit, an
|
||||
= link_to 'Edit', edit_alternate_name_path(an), { :class => 'btn btn-default btn-xs' }
|
||||
= link_to 'Edit', edit_alternate_name_path(an), class: 'btn btn-default btn-xs'
|
||||
- if can? :destroy, an
|
||||
= link_to 'Delete', an, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'
|
||||
= link_to 'Delete', an, method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn btn-default btn-xs'
|
||||
%p
|
||||
- if can? :edit, crop
|
||||
= link_to 'Add', new_alternate_name_path( :crop_id => crop.id ), { :class => 'btn btn-default btn-xs' }
|
||||
= link_to 'Add', new_alternate_name_path(crop_id: crop.id), class: 'btn btn-default btn-xs'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
%h4 Find #{ crop.name } seeds
|
||||
%h4 Find #{crop.name} seeds
|
||||
- if crop.seeds.empty?
|
||||
%p
|
||||
There are no seeds available to trade on Growstuff right now.
|
||||
@@ -7,13 +7,16 @@
|
||||
- crop.seeds.tradable.each do |seed|
|
||||
%li
|
||||
= link_to "#{seed.owner} will trade #{seed.tradable_to}.", seed_path(seed)
|
||||
= render :partial => 'members/location', :locals => { :member => seed.owner }
|
||||
= render partial: 'members/location', locals: { member: seed.owner }
|
||||
%p
|
||||
= link_to "View all #{crop.name} seeds", seeds_by_crop_path(crop)
|
||||
%p
|
||||
= link_to "Purchase seeds via Ebay", "http://rover.ebay.com/rover/1/705-53470-19255-0/1?icep_ff3=9&pub=5575213277&toolid=10001&campid=5337940151&customid=&icep_uq=#{URI.escape crop.name}&icep_sellerId=&icep_ex_kw=&icep_sortBy=12&icep_catId=181003&icep_minPrice=&icep_maxPrice=&ipn=psmain&icep_vectorid=229515&kwid=902099&mtid=824&kw=lg", target: "_blank", rel: "noopener noreferrer"
|
||||
= link_to "Purchase seeds via Ebay",
|
||||
crop_ebay_seeds_url(crop),
|
||||
target: "_blank",
|
||||
rel: "noopener noreferrer"
|
||||
- if crop.approved?
|
||||
- if current_member
|
||||
%p= link_to "List #{crop.name} seeds to trade", new_seed_path(:crop_id => crop.id)
|
||||
%p= link_to "List #{crop.name} seeds to trade", new_seed_path(crop_id: crop.id)
|
||||
- else
|
||||
= render :partial => 'shared/signin_signup', :locals => { :to => 'list your seeds to trade' }
|
||||
= render partial: 'shared/signin_signup', locals: { to: 'list your seeds to trade' }
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
= form_for @crop, :html => {:class => 'form-horizontal', :role => "form"} do |f|
|
||||
= form_for @crop, html: { class: 'form-horizontal', role: "form" } do |f|
|
||||
- if @crop.errors.any?
|
||||
#error_explanation
|
||||
%h3= "#{pluralize(@crop.errors.size, "error")} prohibited this crop from being saved:"
|
||||
%h3
|
||||
= pluralize(@crop.errors.size, "error")
|
||||
prohibited this crop from being saved:
|
||||
%ul
|
||||
- @crop.errors.full_messages.each do |msg|
|
||||
%li= msg
|
||||
@@ -11,16 +13,16 @@
|
||||
%p
|
||||
%span.help-block
|
||||
For detailed crop wrangling guidelines, please consult the
|
||||
=link_to "crop wrangling guide", "http://wiki.growstuff.org/index.php/Crop_wrangling"
|
||||
= link_to "crop wrangling guide", "http://wiki.growstuff.org/index.php/Crop_wrangling"
|
||||
on the Growstuff wiki.
|
||||
|
||||
-# Everyone (wranglers and requesters) sees the basic info section
|
||||
%h2 Basic information
|
||||
|
||||
.form-group#new_crop
|
||||
= f.label :name, :class => 'control-label col-md-2'
|
||||
= f.label :name, class: 'control-label col-md-2'
|
||||
.col-md-8
|
||||
= f.text_field :name, :class => 'form-control'
|
||||
= f.text_field :name, class: 'form-control'
|
||||
%span.help-block
|
||||
The common name for the crop, in English (required).
|
||||
- if can? :wrangle, @crop
|
||||
@@ -28,87 +30,89 @@
|
||||
proper nouns only.
|
||||
|
||||
.form-group
|
||||
= f.label :en_wikipedia_url, 'Wikipedia URL', :class => 'control-label col-md-2'
|
||||
= f.label :en_wikipedia_url, 'Wikipedia URL', class: 'control-label col-md-2'
|
||||
.col-md-8
|
||||
= f.text_field :en_wikipedia_url, :class => 'form-control', :id => "en_wikipedia_url"
|
||||
= f.text_field :en_wikipedia_url, class: 'form-control', id: "en_wikipedia_url"
|
||||
%span.help-block
|
||||
Link to the crop's page on the English language Wikipedia (required).
|
||||
|
||||
-# Only crop wranglers see the crop hierarchy (for now)
|
||||
- if can? :wrangle, @crop
|
||||
.form-group
|
||||
= f.label :parent_id, 'Parent crop', :class => 'control-label col-md-2'
|
||||
= f.label :parent_id, 'Parent crop', class: 'control-label col-md-2'
|
||||
.col-md-8
|
||||
= collection_select(:crop, :parent_id, Crop.all, :id, :name, {:include_blank => true}, :class => 'form-control')
|
||||
= collection_select(:crop, :parent_id, Crop.all, :id, :name, { include_blank: true }, class: 'form-control')
|
||||
%span.help-block Optional. For setting up crop hierarchies for varieties etc.
|
||||
|
||||
|
||||
-# Everyone (wranglers and requesters) gets to add scientific names
|
||||
%h2
|
||||
Scientific names
|
||||
= button_tag "+", :id => "add-sci_name-row", :type => "button"
|
||||
= button_tag "-", :id => "remove-sci_name-row", :type => "button"
|
||||
= button_tag "+", id: "add-sci_name-row", type: "button"
|
||||
= button_tag "-", id: "remove-sci_name-row", type: "button"
|
||||
|
||||
.form-group#scientific_names
|
||||
- @crop.scientific_names.each.with_index do |sci, index|
|
||||
.template.col-md-12{ :id => "sci_template[#{index+1}]" }
|
||||
.template.col-md-12{ id: "sci_template[#{index + 1}]" }
|
||||
.col-md-2
|
||||
= label_tag :scientific_names, "Scientific name #{index+1}:", :class => 'control-label'
|
||||
= label_tag :scientific_names, "Scientific name #{index + 1}:", class: 'control-label'
|
||||
.col-md-8
|
||||
= text_field_tag "sci_name[#{index+1}]", sci.name, :id => "sci_name[#{index+1}]", :class => 'form-control'
|
||||
= text_field_tag "sci_name[#{index + 1}]", sci.name, id: "sci_name[#{index + 1}]", class: 'form-control'
|
||||
%span.help-block Scientific name of crop.
|
||||
.col-md-2
|
||||
|
||||
%h2
|
||||
Alternate names
|
||||
= button_tag "+", :id => "add-alt_name-row", :type => "button"
|
||||
= button_tag "-", :id => "remove-alt_name-row", :type => "button"
|
||||
= button_tag "+", id: "add-alt_name-row", type: "button"
|
||||
= button_tag "-", id: "remove-alt_name-row", type: "button"
|
||||
|
||||
.form-group#alternate_names
|
||||
- @crop.alternate_names.each.with_index do |alt, index|
|
||||
.template.col-md-12{ :id => "alt_template[#{index+1}]" }
|
||||
.template.col-md-12{ id: "alt_template[#{index + 1}]" }
|
||||
.col-md-2
|
||||
= label_tag :alternate_names, "Alternate name #{index+1}:", :class => 'control-label'
|
||||
= label_tag :alternate_names, "Alternate name #{index + 1}:", class: 'control-label'
|
||||
.col-md-8
|
||||
= text_field_tag "alt_name[#{index+1}]", alt.name, :id => "alt_name[#{index+1}]", :class => 'form-control'
|
||||
= text_field_tag "alt_name[#{index + 1}]", alt.name, id: "alt_name[#{index + 1}]", class: 'form-control'
|
||||
%span.help-block Alternate name of crop.
|
||||
.col-md-2
|
||||
|
||||
-# This is used for comments from crop requesters. We need to show it
|
||||
-# to everyone, but we don't include it on new crops from wranglers.
|
||||
|
||||
- if (can? :wrangle, @crop and @crop.requester) or (cannot? :wrangle, @crop and @crop.new_record?)
|
||||
- if (can?(:wrangle, @crop) && @crop.requester) || (cannot?(:wrangle, @crop) && @crop.new_record?)
|
||||
%h2 Crop request notes
|
||||
.form-group
|
||||
= f.label :request_notes, 'Comments', :class => 'control-label col-md-2'
|
||||
= f.label :request_notes, 'Comments', class: 'control-label col-md-2'
|
||||
.col-md-8
|
||||
= f.text_area :request_notes, :rows => 3, :class => 'form-control', :id => 'request_notes'
|
||||
= f.text_area :request_notes, rows: 3, class: 'form-control', id: 'request_notes'
|
||||
|
||||
-# A final explanation of what's going to happen next, for crop requesters
|
||||
- unless can? :wrangle, @crop
|
||||
%p When you submit this form, your suggestion will be sent to our team of #{link_to 'volunteer crop wranglers', 'http://talk.growstuff.org/c/crop-wrangling'} for review. We'll let you know the outcome as soon as we can.
|
||||
%p
|
||||
When you submit this form, your suggestion will be sent to our team of
|
||||
= link_to 'volunteer crop wranglers', 'http://talk.growstuff.org/c/crop-wrangling'
|
||||
for review. We'll let you know the outcome as soon as we can.
|
||||
|
||||
-# Now, for crop wranglers, let's have approval/rejection at the bottom of the page
|
||||
- if can? :wrangle, @crop and @crop.requester
|
||||
- if can?(:wrangle, @crop) && @crop.requester
|
||||
%h2 Approve or reject pending crops
|
||||
.form-group
|
||||
= f.label :approval_status, 'Approval status', :class=> 'control-label col-md-2'
|
||||
= f.label :approval_status, 'Approval status', class: 'control-label col-md-2'
|
||||
.col-md-8
|
||||
= f.select(:approval_status, @crop.approval_statuses, {}, {:class => 'form-control'})
|
||||
= f.select(:approval_status, @crop.approval_statuses, {}, class: 'form-control')
|
||||
|
||||
.form-group
|
||||
= f.label :reason_for_rejection, 'Reason for rejection', :class => 'control-label col-md-2'
|
||||
= f.label :reason_for_rejection, 'Reason for rejection', class: 'control-label col-md-2'
|
||||
.col-md-8
|
||||
= f.select(:reason_for_rejection, @crop.reasons_for_rejection, {:include_blank => true}, {:class => 'form-control'})
|
||||
= f.select(:reason_for_rejection, @crop.reasons_for_rejection, include_blank: true, class: 'form-control')
|
||||
|
||||
.form-group
|
||||
= f.label :rejection_notes, 'Rejection notes', :class => 'control-label col-md-2'
|
||||
= f.label :rejection_notes, 'Rejection notes', class: 'control-label col-md-2'
|
||||
.col-md-8
|
||||
= f.text_area :rejection_notes, :rows => 3, :class => 'form-control'
|
||||
= f.text_area :rejection_notes, rows: 3, class: 'form-control'
|
||||
%span.help-block
|
||||
Please provide additional notes why this crop request was rejected if the above reasons do not apply.
|
||||
|
||||
|
||||
.form-group
|
||||
.form-actions.col-md-offset-2.col-md-8
|
||||
= f.submit 'Save', :class => 'btn btn-primary'
|
||||
= f.submit 'Save', class: 'btn btn-primary'
|
||||
|
||||
@@ -3,5 +3,7 @@
|
||||
- if crop.harvests.empty?
|
||||
not known.
|
||||
- else
|
||||
- popular_plant_parts = crop.popular_plant_parts.sort_by {|s, freq| freq }.reverse
|
||||
!= popular_plant_parts.map {|p, freq| link_to(p, p) + " (#{freq})" }.join(", ")
|
||||
- crop.popular_plant_parts.each do |plant_part, frequency|
|
||||
- id, name = plant_part
|
||||
= link_to name, plant_part_path(id: id)
|
||||
(#{frequency})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
%h4 #{ crop.name.capitalize } harvests
|
||||
%h4 #{crop.name.capitalize} harvests
|
||||
- if crop.harvests.empty?
|
||||
%p
|
||||
Nobody has harvested this crop yet.
|
||||
@@ -7,7 +7,7 @@
|
||||
- crop.harvests.take(3).each do |harvest|
|
||||
%li
|
||||
= link_to "#{harvest.owner} harvested #{display_quantity(harvest)}.", harvest_path(harvest)
|
||||
= render :partial => 'members/location', :locals => { :member => harvest.owner }
|
||||
= render partial: 'members/location', locals: { member: harvest.owner }
|
||||
%small
|
||||
= distance_of_time_in_words(harvest.created_at, Time.zone.now)
|
||||
ago.
|
||||
@@ -15,7 +15,6 @@
|
||||
= link_to "View all #{crop.name} harvests", harvests_by_crop_path(crop)
|
||||
- if crop.approved?
|
||||
- if current_member
|
||||
%p= link_to "Harvest #{crop.name}", new_harvest_path(:crop_id => crop.id)
|
||||
%p= link_to "Harvest #{crop.name}", new_harvest_path(crop_id: crop.id)
|
||||
- else
|
||||
= render :partial => 'shared/signin_signup', :locals => { :to => "track your #{crop.name} harvests" }
|
||||
|
||||
= render partial: 'shared/signin_signup', locals: { to: "track your #{crop.name} harvests" }
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
- unless defined? max
|
||||
- max = 0 # list all without "show all" toggle button
|
||||
- display_crops.each do |c|
|
||||
%li.crop-hierarchy{:class => max != 0 && @count >= max ? ['hide', 'toggle'] : []}
|
||||
%li.crop-hierarchy{ class: max != 0 && @count >= max ? ['hide', 'toggle'] : [] }
|
||||
= link_to c, c
|
||||
- @count += 1
|
||||
- if c.varieties.present?
|
||||
- c.varieties.each do |v|
|
||||
= render :partial => 'hierarchy', :locals => { :display_crops => [ v ], :max => max }
|
||||
= render partial: 'hierarchy', locals: { display_crops: [v], max: max }
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
- cache crop do
|
||||
= link_to |
|
||||
image_tag( |
|
||||
crop.default_photo ? crop.default_photo.thumbnail_url : 'placeholder_150.png', |
|
||||
:alt => crop.name, |
|
||||
:class => 'image-responsive crop-image' |
|
||||
), |
|
||||
crop, |
|
||||
:rel => "popover", |
|
||||
'data-trigger' => 'hover', |
|
||||
'data-title' => crop.name, |
|
||||
'data-content' => "#{ render :partial => 'crops/popover', :locals => { :crop => crop } }", |
|
||||
'data-html' => true |
|
||||
= link_to image_tag(crop.default_photo.present? ? crop.default_photo.thumbnail_url : 'placeholder_150.png',
|
||||
alt: crop.name, class: 'image-responsive crop-image'),
|
||||
crop.name,
|
||||
rel: "popover",
|
||||
'data-trigger': 'hover',
|
||||
'data-title': crop.name,
|
||||
'data-content': render(partial: 'crops/popover', locals: { crop: crop }),
|
||||
'data-html': true
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
.well
|
||||
.row
|
||||
.col-md-4
|
||||
= link_to image_tag((crop.default_photo ? crop.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => '', :class => 'img crop-image'), crop
|
||||
= link_to image_tag((crop.default_photo ? crop.default_photo.thumbnail_url : 'placeholder_150.png'),
|
||||
alt: '',
|
||||
class: 'img crop-image'),
|
||||
crop
|
||||
.col-md-8
|
||||
%h3{:style => 'padding-top: 0px; margin-top: 0px'}
|
||||
%h3{ style: 'padding-top: 0px; margin-top: 0px' }
|
||||
= link_to crop, crop
|
||||
|
||||
%p
|
||||
@@ -16,6 +19,6 @@
|
||||
by #{ENV['GROWSTUFF_SITE_NAME']} members
|
||||
|
||||
- if can? :create, Planting
|
||||
= link_to 'Plant this', new_planting_path(:params => { :crop_id => crop.id }), :class => 'btn btn-primary'
|
||||
= link_to 'Plant this', new_planting_path(params: { crop_id: crop.id }), class: 'btn btn-primary'
|
||||
- if can? :create, Seed
|
||||
= link_to 'Add seeds to stash', new_seed_path(:params => { :crop_id => crop.id }), :class => 'btn btn-primary'
|
||||
= link_to 'Add seeds to stash', new_seed_path(params: { crop_id: crop.id }), class: 'btn btn-primary'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.row
|
||||
- if !crop.photos.empty?
|
||||
- unless crop.photos.empty?
|
||||
- crop.photos.first(3).each do |p|
|
||||
.col-md-4
|
||||
= render :partial => "photos/thumbnail", :locals => { :photo => p }
|
||||
= render partial: "photos/thumbnail", locals: { photo: p }
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
- if crop.planted_from.empty?
|
||||
not known.
|
||||
- else
|
||||
- planted_from = crop.planted_from.sort_by {|s, freq| freq }.reverse
|
||||
= planted_from.map {|s, freq| "#{s} (#{freq})" }.join(", ")
|
||||
- planted_from = crop.planted_from.sort_by { |_, freq| freq }.reverse
|
||||
= planted_from.map { |s, freq| "#{s} (#{freq})" }.join(", ")
|
||||
|
||||
%p
|
||||
%strong Plant in:
|
||||
- if crop.sunniness.empty?
|
||||
not known.
|
||||
- else
|
||||
- sunniness = crop.sunniness.sort_by {|s, freq| freq }.reverse
|
||||
= sunniness.map {|s, freq| "#{s} (#{freq})" }.join(", ")
|
||||
- sunniness = crop.sunniness.sort_by { |_, freq| freq }.reverse
|
||||
= sunniness.map { |s, freq| "#{s} (#{freq})" }.join(", ")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
%h4 See who's planted #{ crop.name.pluralize }
|
||||
%h4 See who's planted #{crop.name.pluralize}
|
||||
- if crop.plantings.empty?
|
||||
%p
|
||||
Nobody has planted this crop yet.
|
||||
@@ -7,7 +7,7 @@
|
||||
- crop.plantings.take(3).each do |planting|
|
||||
%li
|
||||
= link_to display_planting(planting), planting_path(planting)
|
||||
= render :partial => 'members/location', :locals => { :member => planting.owner }
|
||||
= render partial: 'members/location', locals: { member: planting.owner }
|
||||
%small
|
||||
= distance_of_time_in_words(planting.created_at, Time.zone.now)
|
||||
ago.
|
||||
@@ -15,7 +15,7 @@
|
||||
= link_to "View all #{crop.name} plantings", plantings_by_crop_path(crop)
|
||||
- if crop.approved?
|
||||
- if current_member
|
||||
%p= link_to "Plant #{crop.name}", new_planting_path(:crop_id => crop.id)
|
||||
%p= link_to "Plant #{crop.name}", new_planting_path(crop_id: crop.id)
|
||||
- else
|
||||
= render :partial => 'shared/signin_signup', :locals => { :to => "track your #{crop.name} plantings" }
|
||||
= render partial: 'shared/signin_signup', locals: { to: "track your #{crop.name} plantings" }
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%p
|
||||
%small
|
||||
- if crop.scientific_names.size > 0
|
||||
- unless crop.scientific_names.empty?
|
||||
%i
|
||||
= crop.scientific_names.first.name
|
||||
%br/
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
%li
|
||||
= sn.name
|
||||
- if can? :edit, sn
|
||||
= link_to 'Edit', edit_scientific_name_path(sn), { :class => 'btn btn-default btn-xs' }
|
||||
= link_to 'Edit', edit_scientific_name_path(sn), class: 'btn btn-default btn-xs'
|
||||
- if can? :destroy, sn
|
||||
= link_to 'Delete', sn, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'
|
||||
= link_to 'Delete', sn, method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn btn-default btn-xs'
|
||||
%p
|
||||
- if can? :edit, crop
|
||||
= link_to 'Add', new_scientific_name_path( :crop_id => crop.id ), { :class => 'btn btn-default btn-xs' }
|
||||
= link_to 'Add', new_scientific_name_path(crop_id: crop.id), class: 'btn btn-default btn-xs'
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
.crop-thumbnail
|
||||
- if crop
|
||||
- cache cache_key_for(Crop, crop.id) do
|
||||
= link_to image_tag((crop.default_photo ? crop.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => crop.name, :class => 'img'), crop
|
||||
= link_to image_tag((crop.default_photo ? crop.default_photo.thumbnail_url : 'placeholder_150.png'),
|
||||
alt: crop.name, class: 'img'),
|
||||
crop
|
||||
.cropinfo
|
||||
.cropname
|
||||
= link_to crop.name, crop
|
||||
- if crop.scientific_names.size > 0
|
||||
- unless crop.scientific_names.empty?
|
||||
.scientificname
|
||||
= crop.scientific_names.first.name
|
||||
.plantingcount
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
Varieties of #{crop.name}:
|
||||
|
||||
- max = 5
|
||||
= render :partial => 'hierarchy', :locals => { :display_crops => [ crop ], :max => max }
|
||||
= render partial: 'hierarchy', locals: { display_crops: [crop], max: max }
|
||||
- if max != 0 && @count > max
|
||||
= button_tag "Show all #{@count-1} varieties", :class => 'btn btn-link toggle crop-hierarchy'
|
||||
= button_tag "Show less varieties", :class => 'btn btn-link toggle crop-hierarchy hide'
|
||||
= button_tag "Show all #{@count - 1} varieties", class: 'btn btn-link toggle crop-hierarchy'
|
||||
= button_tag "Show less varieties", class: 'btn btn-link toggle crop-hierarchy hide'
|
||||
|
||||
- if ! crop.parent and crop.varieties.empty?
|
||||
- if !crop.parent && crop.varieties.empty?
|
||||
%p None known.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
- if can? :edit, crop or can? :destroy, crop
|
||||
- if can?(:edit, crop) || can?(:destroy, crop)
|
||||
%h4 Crop wrangling
|
||||
%p
|
||||
You are a
|
||||
@@ -6,6 +6,9 @@
|
||||
%strong CROP WRANGLER
|
||||
%p
|
||||
- if can? :edit, crop
|
||||
= link_to 'Edit crop', edit_crop_path(crop), { :class => 'btn btn-default btn-xs' }
|
||||
= link_to 'Edit crop', edit_crop_path(crop), class: 'btn btn-default btn-xs'
|
||||
- if can? :destroy, crop
|
||||
= link_to 'Delete crop', crop, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'
|
||||
= link_to 'Delete crop', crop,
|
||||
method: :delete,
|
||||
data: { confirm: 'Are you sure?' },
|
||||
class: 'btn btn-default btn-xs'
|
||||
|
||||
@@ -2,18 +2,29 @@
|
||||
|
||||
- if @crop.approval_status == "approved"
|
||||
- if @crop.requester
|
||||
%p Requested by #{link_to @crop.requester, @crop.requester} #{distance_of_time_in_words(@crop.created_at, Time.zone.now)} ago.
|
||||
%p Approved by #{link_to @crop.creator, @crop.creator}.
|
||||
%p
|
||||
Requested by #{link_to @crop.requester, @crop.requester}
|
||||
#{distance_of_time_in_words(@crop.created_at, Time.zone.now)} ago.
|
||||
%p
|
||||
Approved by #{link_to @crop.creator, @crop.creator}.
|
||||
- else
|
||||
%p Added by #{link_to @crop.creator, @crop.creator} #{distance_of_time_in_words(@crop.created_at, Time.zone.now)} ago.
|
||||
%p
|
||||
Added by #{link_to @crop.creator, @crop.creator}
|
||||
#{distance_of_time_in_words(@crop.created_at, Time.zone.now)} ago.
|
||||
- elsif @crop.approval_status == "pending"
|
||||
.alert.alert-danger
|
||||
%p Requested by #{link_to @crop.requester, @crop.requester} #{distance_of_time_in_words(@crop.created_at, Time.zone.now)} ago.
|
||||
%p Status: #{@crop.approval_status}.
|
||||
%p
|
||||
Requested by #{link_to @crop.requester, @crop.requester}
|
||||
#{distance_of_time_in_words(@crop.created_at, Time.zone.now)} ago.
|
||||
%p
|
||||
Status: #{@crop.approval_status}.
|
||||
- elsif @crop.approval_status == "rejected"
|
||||
.alert.alert-danger
|
||||
%p Requested by #{link_to @crop.requester, @crop.requester} #{distance_of_time_in_words(@crop.created_at, Time.zone.now)} ago.
|
||||
%p Status: #{@crop.approval_status} by #{link_to @crop.creator, @crop.creator}.
|
||||
%p
|
||||
Requested by #{link_to @crop.requester, @crop.requester}
|
||||
#{distance_of_time_in_words(@crop.created_at, Time.zone.now)} ago.
|
||||
%p
|
||||
Status: #{@crop.approval_status} by #{link_to @crop.creator, @crop.creator}.
|
||||
|
||||
= render 'form'
|
||||
|
||||
|
||||
@@ -6,4 +6,4 @@
|
||||
= link_to "crops database", crops_path
|
||||
|
||||
- cache cache_key_for(Crop) do
|
||||
= render :partial => "hierarchy", :locals => { :display_crops => @crops }
|
||||
= render partial: "hierarchy", locals: { display_crops: @crops }
|
||||
|
||||
@@ -2,36 +2,44 @@
|
||||
- content_for :subtitle, t('.subtitle', crops_size: @crops.size)
|
||||
|
||||
- if can? :wrangle, Crop
|
||||
= link_to 'Wrangle Crops', wrangle_crops_path, :class => 'btn btn-primary'
|
||||
= link_to 'Wrangle Crops', wrangle_crops_path, class: 'btn btn-primary'
|
||||
|
||||
- if @has_requested_pending
|
||||
= link_to(I18n.t('crops.requested.link', number_crops: @has_requested_pending), requested_crops_path)
|
||||
|
||||
%p
|
||||
#{ENV['GROWSTUFF_SITE_NAME']} tracks who's growing what, where.
|
||||
View any crop page to see which of our members have planted it and find
|
||||
information on how to grow it yourself.
|
||||
|
||||
= form_tag(crops_path, :method => :get, :class => 'form-inline', :role => 'form') do
|
||||
= form_tag(crops_path, method: :get, class: 'form-inline', role: 'form') do
|
||||
.form-group
|
||||
= label_tag :sort, "Sort by:", :class => 'sr-only'
|
||||
= select_tag "sort", options_for_select({"Sort by popularity" => 'popular', "Sort alphabetically" => 'alpha'}, @sort || 'popular'), :class => 'form-control'
|
||||
= submit_tag "Show", :class => 'btn btn-primary'
|
||||
= label_tag :sort, "Sort by:", class: 'sr-only'
|
||||
= select_tag "sort",
|
||||
options_for_select({ "Sort by popularity": 'popular',
|
||||
"Sort alphabetically": 'alpha' },
|
||||
@sort || 'popular'),
|
||||
class: 'form-control'
|
||||
= submit_tag "Show", class: 'btn btn-primary'
|
||||
|
||||
%div.pagination
|
||||
.pagination
|
||||
= will_paginate @paginated_crops
|
||||
|
||||
.row
|
||||
- @paginated_crops.each do |crop|
|
||||
.col-md-2.six-across
|
||||
= render :partial => "thumbnail", :locals => { :crop => crop }
|
||||
= render partial: "thumbnail", locals: { crop: crop }
|
||||
|
||||
- if can? :create, Crop
|
||||
%div
|
||||
= link_to 'New Crop', new_crop_path, {:class => 'btn btn-primary'}
|
||||
= link_to 'New Crop', new_crop_path, class: 'btn btn-primary'
|
||||
|
||||
%div.pagination
|
||||
.pagination
|
||||
= will_paginate @paginated_crops
|
||||
|
||||
|
||||
%ul.list-inline
|
||||
%li The data on this page is available in the following formats:
|
||||
%li= link_to "CSV", crops_path(:format => 'csv')
|
||||
%li= link_to "JSON", crops_path(:format => 'json')
|
||||
%li= link_to "RSS", crops_path(:format => 'rss')
|
||||
%li= link_to "CSV", crops_path(format: 'csv')
|
||||
%li= link_to "JSON", crops_path(format: 'json')
|
||||
%li= link_to "RSS", crops_path(format: 'rss')
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
%rss{:version => 2.0}
|
||||
%rss{ version: 2.0 }
|
||||
%channel
|
||||
%title Recently added crops (#{ENV['GROWSTUFF_SITE_NAME']})
|
||||
%link= crops_url
|
||||
- @crops.each do |crop|
|
||||
%item
|
||||
%title= crop.name
|
||||
%pubDate= crop.created_at.to_s(:rfc822)
|
||||
%pubdate= crop.created_at.to_s(:rfc822)
|
||||
%link= post_url(crop)
|
||||
%guid= post_url(crop)
|
||||
|
||||
@@ -1,14 +1,23 @@
|
||||
- content_for :title, (can?(:wrangle, @crop) ? "New crop" : "Suggest a crop")
|
||||
|
||||
- unless can? :wrangler, @crop
|
||||
|
||||
%p Thanks for taking the time to suggest a crop! Our crop database is managed by volunteers, and we appreciate your help. Here are some things to consider when suggesting a new crop:
|
||||
|
||||
%p
|
||||
Thanks for taking the time to suggest a crop! Our crop database is
|
||||
managed by volunteers, and we appreciate your help. Here are some
|
||||
things to consider when suggesting a new crop:
|
||||
%ul
|
||||
%li First, you might want to #{link_to 'search our crops', crops_search_path} to make sure we don't have it already, perhaps under an alternate name.
|
||||
%li
|
||||
First, you might want to #{link_to 'search our crops', crops_search_path}
|
||||
to make sure we don't have it already, perhaps under an alternate name.
|
||||
%li
|
||||
The Growstuff database only contains edible crops. In future we hope to
|
||||
support other crops, but for now, if your suggestion is not edible we
|
||||
won't be able to add it.
|
||||
|
||||
%li The Growstuff database only contains edible crops. In future we hope to support other crops, but for now, if your suggestion is not edible we won't be able to add it.
|
||||
|
||||
%li At this time, we are only adding crops which have a Wikipedia page. If you want to add a specific variety of crop that doesn't have its own Wikipedia entry, please use the more general form of the crop instead and put the name of your variety in the notes/description.
|
||||
%li
|
||||
At this time, we are only adding crops which have a Wikipedia page. If you
|
||||
want to add a specific variety of crop that doesn't have its own Wikipedia
|
||||
entry, please use the more general form of the crop instead and put the name
|
||||
of your variety in the notes/description.
|
||||
|
||||
= render 'form'
|
||||
|
||||
15
app/views/crops/requested.haml
Normal file
15
app/views/crops/requested.haml
Normal file
@@ -0,0 +1,15 @@
|
||||
- content_for :title, t('crops.requested.title')
|
||||
- content_for :subtitle, t('crops.requested.subtitle', crops_size: @crops.size)
|
||||
|
||||
%p Crops you have requested
|
||||
|
||||
.pagination
|
||||
= will_paginate @requested
|
||||
|
||||
.row
|
||||
- @requested.each do |crop|
|
||||
.col-md-2.six-across
|
||||
= render partial: "thumbnail", locals: { crop: crop }
|
||||
|
||||
.pagination
|
||||
= will_paginate @requested
|
||||
@@ -6,11 +6,14 @@
|
||||
- content_for :title, "Crop search"
|
||||
|
||||
%div
|
||||
= form_tag crops_search_path, :method => :get, :id => 'crop-search', :class => 'form-inline' do
|
||||
= form_tag crops_search_path, method: :get, id: 'crop-search', class: 'form-inline' do
|
||||
.form-group
|
||||
= label_tag :term, "Search crops:", :class => 'sr-only'
|
||||
= text_field_tag 'term', nil, :class => 'search-query input-medium form-control', :placeholder => 'Search crops', :value => @term
|
||||
= submit_tag "Search", :class => 'btn btn-primary'
|
||||
= label_tag :term, "Search crops:", class: 'sr-only'
|
||||
= text_field_tag 'term', nil,
|
||||
class: 'search-query input-medium form-control',
|
||||
placeholder: 'Search crops',
|
||||
value: @term
|
||||
= submit_tag "Search", class: 'btn btn-primary'
|
||||
|
||||
- if @matches.empty?
|
||||
%h2 No results found
|
||||
@@ -22,14 +25,14 @@
|
||||
instead.
|
||||
|
||||
- else
|
||||
%div.pagination
|
||||
.pagination
|
||||
= will_paginate @paginated_matches
|
||||
|
||||
%div#paginated_matches
|
||||
#paginated_matches
|
||||
.row
|
||||
- @paginated_matches.each do |c|
|
||||
.col-md-2.six-across
|
||||
= render :partial => "thumbnail", :locals => { :crop => c }
|
||||
= render partial: "thumbnail", locals: { crop: c }
|
||||
|
||||
%div.pagination
|
||||
.pagination
|
||||
= will_paginate @paginated_matches
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user