mirror of
https://github.com/Growstuff/growstuff.git
synced 2026-05-25 09:19:15 -04:00
Compare commits
463 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
38b2d8de0f | ||
|
|
491982f8f3 | ||
|
|
ac7e116eae | ||
|
|
1526257a0d | ||
|
|
7234848c5f | ||
|
|
6e453707b9 | ||
|
|
dac2d1d4c2 | ||
|
|
6c4c1ff8ba | ||
|
|
93d1bfd05d | ||
|
|
6167e291d2 | ||
|
|
deb1e27176 | ||
|
|
82bb6c2f3b | ||
|
|
24d9d714b2 | ||
|
|
d9ad55db7c | ||
|
|
4dad76e635 | ||
|
|
252791b47d | ||
|
|
aa849c2e1f | ||
|
|
b03a59cb93 | ||
|
|
e761ecc356 | ||
|
|
69b887ba79 | ||
|
|
e4c2f777ac | ||
|
|
f0cb635b42 | ||
|
|
4116e201b5 | ||
|
|
5788c0c5ce | ||
|
|
6f6e0a58a3 | ||
|
|
15b49672ee | ||
|
|
9e2c7d0748 | ||
|
|
5ff0e2c565 | ||
|
|
d40665fb08 | ||
|
|
3b6a42b8f2 | ||
|
|
cf3772af43 | ||
|
|
2f30343303 | ||
|
|
8de7e7a00b | ||
|
|
46efcf3e61 | ||
|
|
7968f3e407 | ||
|
|
639232bc87 | ||
|
|
e0bc1c936a | ||
|
|
910a9673dc | ||
|
|
582dd2c9fd | ||
|
|
1a743d7592 | ||
|
|
174040aa1b | ||
|
|
4471ac64e4 | ||
|
|
a8bb6c9f58 | ||
|
|
7d7053f558 | ||
|
|
6f59896d96 | ||
|
|
e8cf19cc9d | ||
|
|
5a3d15d101 | ||
|
|
142be72fc3 | ||
|
|
c6331fc449 | ||
|
|
e8455cd943 | ||
|
|
080e728905 | ||
|
|
db532fcc8f | ||
|
|
e78d899528 | ||
|
|
1f916b8314 | ||
|
|
1cdcaac41e | ||
|
|
bbc3ca749f | ||
|
|
20b980a162 | ||
|
|
37897ad595 | ||
|
|
72f805e135 | ||
|
|
1bb4f601a1 | ||
|
|
fb012c073e | ||
|
|
3dfd9eedca | ||
|
|
75d2c0ea3c | ||
|
|
08996c4157 | ||
|
|
c48e24845e | ||
|
|
61f93df6ff | ||
|
|
34e5e0850d | ||
|
|
7621da7041 | ||
|
|
8bcc5104e5 | ||
|
|
4bbeca9f3e | ||
|
|
54748ac20d | ||
|
|
3c8b80574a | ||
|
|
288ad782d2 | ||
|
|
5d97a7edac | ||
|
|
ff1c835cda | ||
|
|
479f61b224 | ||
|
|
ac94b8b6d3 | ||
|
|
fedc7a7fb6 | ||
|
|
9f9df07390 | ||
|
|
e5a705aeae | ||
|
|
fb0f74c4d8 | ||
|
|
963aafd5ab | ||
|
|
efe2f49e7f | ||
|
|
a7178b6da7 | ||
|
|
2da3cd6673 | ||
|
|
5d50f9aec2 | ||
|
|
cfb43ba07c | ||
|
|
3811417d70 | ||
|
|
9b3c77a0e6 | ||
|
|
b5636af3be | ||
|
|
3e93fb5e2e | ||
|
|
c22c92e9f4 | ||
|
|
97a763660a | ||
|
|
8a25ecc635 | ||
|
|
ee52c14b95 | ||
|
|
3178e44843 | ||
|
|
f510dfd8d9 | ||
|
|
7ad13d3eff | ||
|
|
e0c7e8c15b | ||
|
|
5e91effb12 | ||
|
|
9560da90ab | ||
|
|
9e1ed8e9eb | ||
|
|
15592d01d0 | ||
|
|
15d93e6c33 | ||
|
|
484e20ba83 | ||
|
|
d341e977c3 | ||
|
|
e7d7ee396e | ||
|
|
adf585852a | ||
|
|
de5b56235e | ||
|
|
318ef46ae8 | ||
|
|
b982793fbf | ||
|
|
6fef56ebb7 | ||
|
|
fa586c15aa | ||
|
|
51be3db970 | ||
|
|
5d654175a9 | ||
|
|
e9003ad32a | ||
|
|
38c3320731 | ||
|
|
e6b556851a | ||
|
|
a30285ef49 | ||
|
|
4f67f17551 | ||
|
|
8f66009d0d | ||
|
|
cdd12fd4dd | ||
|
|
3ff0018a12 | ||
|
|
0b0f479752 | ||
|
|
b7148b99dc | ||
|
|
8076e58a97 | ||
|
|
251d390c23 | ||
|
|
f380f222a9 | ||
|
|
eacdab45ba | ||
|
|
dcb949e7b3 | ||
|
|
ebf1468652 | ||
|
|
4726b57c47 | ||
|
|
f422336aff | ||
|
|
2c622af49c | ||
|
|
0b684eb05e | ||
|
|
9c4a45bc29 | ||
|
|
00f7551c0a | ||
|
|
ee7b915313 | ||
|
|
af0871cd0a | ||
|
|
60d074a0de | ||
|
|
c2ba2719de | ||
|
|
afb0b9e387 | ||
|
|
e4e4d9600e | ||
|
|
a6964a8f4e | ||
|
|
b538330785 | ||
|
|
aee90268a5 | ||
|
|
cabf849774 | ||
|
|
7251f3308b | ||
|
|
121d3d99fe | ||
|
|
c4938e00e4 | ||
|
|
4a926415db | ||
|
|
7d4c9011aa | ||
|
|
b5b2582335 | ||
|
|
7d2a2b96a2 | ||
|
|
e2fe04a44b | ||
|
|
18c02bf33b | ||
|
|
6c0b1018bc | ||
|
|
15e2b4f595 | ||
|
|
6e7bf11ec8 | ||
|
|
5f9b0890fb | ||
|
|
4841c52bcd | ||
|
|
7baabca827 | ||
|
|
9a19007b85 | ||
|
|
677f850e21 | ||
|
|
d771bc3688 | ||
|
|
1dfc58c120 | ||
|
|
6f58f266a6 | ||
|
|
e38395b6ba | ||
|
|
944d477dbc | ||
|
|
cbf7ac0126 | ||
|
|
1ad171f37b | ||
|
|
06896dacd5 | ||
|
|
ff90d6430d | ||
|
|
4dbdbc4285 | ||
|
|
0f1c8e0658 | ||
|
|
c9ec116c9b | ||
|
|
e61c3f619b | ||
|
|
93b25a5c32 | ||
|
|
f7ca32d888 | ||
|
|
d57c46066a | ||
|
|
1e6cb2cfe4 | ||
|
|
67ae80056a | ||
|
|
13fa3c69e8 | ||
|
|
caad557b2a | ||
|
|
0f030d2c27 | ||
|
|
66d548c9c1 | ||
|
|
c168bb4a2b | ||
|
|
811db2961a | ||
|
|
42cea2ebde | ||
|
|
ccc5eb3c9a | ||
|
|
0e71a4fcb3 | ||
|
|
4ea681984f | ||
|
|
dadc5b96c6 | ||
|
|
787fca138b | ||
|
|
b820615081 | ||
|
|
812a6f5ec2 | ||
|
|
f1b42ec699 | ||
|
|
26c17ea19c | ||
|
|
acc75f80bf | ||
|
|
a79a65363f | ||
|
|
dfeb4804e7 | ||
|
|
9d20fafd06 | ||
|
|
e9a5ef0058 | ||
|
|
d2378376e4 | ||
|
|
4b1b5d8a18 | ||
|
|
a0770e80e7 | ||
|
|
f08e740ac6 | ||
|
|
5f23bcfad6 | ||
|
|
3cd7b86c99 | ||
|
|
bd53d4a271 | ||
|
|
16d88730ec | ||
|
|
5ad88eb6bd | ||
|
|
b617eb3140 | ||
|
|
acc4d3ad84 | ||
|
|
beb3f7e2b8 | ||
|
|
ab46a8dd96 | ||
|
|
b6b578d7e6 | ||
|
|
4d07cf80fa | ||
|
|
93f6b65d8d | ||
|
|
b40a6723e1 | ||
|
|
2058d28b37 | ||
|
|
682c6d6f5e | ||
|
|
2be55acc92 | ||
|
|
a9a040182c | ||
|
|
f39fe94173 | ||
|
|
976bdbbd96 | ||
|
|
cff1d8bfb9 | ||
|
|
bbdc54cb69 | ||
|
|
36f1f7b71a | ||
|
|
e1731793dd | ||
|
|
8ea3b27612 | ||
|
|
9469a69078 | ||
|
|
cc46fe3336 | ||
|
|
52b4064a2d | ||
|
|
d367b9ef21 | ||
|
|
4711e4669f | ||
|
|
3e55024f98 | ||
|
|
ccf56bf944 | ||
|
|
42e51a9cf6 | ||
|
|
667e0cc0e3 | ||
|
|
339830b3bb | ||
|
|
7770164672 | ||
|
|
f333607572 | ||
|
|
87d3764eeb | ||
|
|
faf487b719 | ||
|
|
53eb171dfc | ||
|
|
3dbf0df19e | ||
|
|
b0b6931678 | ||
|
|
cd272a6443 | ||
|
|
d515dba7f2 | ||
|
|
4958330c9e | ||
|
|
17236a4a8a | ||
|
|
936a8778ed | ||
|
|
3ccab3f857 | ||
|
|
0201e873eb | ||
|
|
20289e6566 | ||
|
|
85ded414ec | ||
|
|
299c95c5f5 | ||
|
|
8f51090098 | ||
|
|
5551eeba24 | ||
|
|
7a5a68f511 | ||
|
|
6d4ec9ad34 | ||
|
|
fffef75813 | ||
|
|
0e2d7b4393 | ||
|
|
f08068c289 | ||
|
|
ff653934ad | ||
|
|
c4bed2cf4d | ||
|
|
47c0f74f81 | ||
|
|
171e34914b | ||
|
|
8010a8b56c | ||
|
|
ac165ce0cd | ||
|
|
4925fde28f | ||
|
|
6580cf38b0 | ||
|
|
fdf10202ba | ||
|
|
85a368999b | ||
|
|
6ba4b4560e | ||
|
|
71aedb136a | ||
|
|
65c988790b | ||
|
|
0372d3b9b0 | ||
|
|
3272ea1ca5 | ||
|
|
39b461c348 | ||
|
|
a8f7031447 | ||
|
|
17967b7c72 | ||
|
|
e422c8b072 | ||
|
|
5392d7d900 | ||
|
|
d42bbe7fa3 | ||
|
|
45f2abeab5 | ||
|
|
7e754b8293 | ||
|
|
1dcd84009a | ||
|
|
8615df264e | ||
|
|
4e400cc899 | ||
|
|
3cead5fb6b | ||
|
|
1decf6ea11 | ||
|
|
23c0f901c6 | ||
|
|
78f4b3dbf3 | ||
|
|
9340b8d7e5 | ||
|
|
0094473bbe | ||
|
|
743f482818 | ||
|
|
b8ea6116d4 | ||
|
|
2521e52d71 | ||
|
|
d44f9ef4e9 | ||
|
|
63cee1edc9 | ||
|
|
3791b34fe3 | ||
|
|
5d58be110e | ||
|
|
911593b480 | ||
|
|
b72a3d6942 | ||
|
|
804ac8662a | ||
|
|
1601e966ad | ||
|
|
e7553868f2 | ||
|
|
5e8ca392d2 | ||
|
|
815915d933 | ||
|
|
6223076dae | ||
|
|
0182a99654 | ||
|
|
5baa357bb3 | ||
|
|
0fb4d74685 | ||
|
|
eebaef6fde | ||
|
|
59fc550f3c | ||
|
|
64ffaab1ec | ||
|
|
21f53e362f | ||
|
|
20cfa0c5b2 | ||
|
|
204633d533 | ||
|
|
c77ed8c6d0 | ||
|
|
fe7ae18e7b | ||
|
|
8746cc67e2 | ||
|
|
f1feb59818 | ||
|
|
bb62b11070 | ||
|
|
1660d54c01 | ||
|
|
cb7715b6d9 | ||
|
|
a60d0faedd | ||
|
|
7f592579cd | ||
|
|
998befb30f | ||
|
|
ebbf6df87d | ||
|
|
40e4f8df8a | ||
|
|
81d41398a2 | ||
|
|
4f02f45ae8 | ||
|
|
f7ec1826b0 | ||
|
|
d619cd160d | ||
|
|
4a20f68d3a | ||
|
|
62d2b5e9fb | ||
|
|
5935d2e73f | ||
|
|
92b8972b24 | ||
|
|
12254fe0ca | ||
|
|
ea54fca2b2 | ||
|
|
d7db9007fd | ||
|
|
c2acb8cf73 | ||
|
|
8d04d4b223 | ||
|
|
35d9c8e9f1 | ||
|
|
b23118a9db | ||
|
|
5585dbada1 | ||
|
|
fa49234669 | ||
|
|
8833571ab3 | ||
|
|
a54e66f2fd | ||
|
|
7913f85cf4 | ||
|
|
bf46c0a6d2 | ||
|
|
082bdb035f | ||
|
|
15bedb1659 | ||
|
|
5995812215 | ||
|
|
195d1bbdbb | ||
|
|
55e0579384 | ||
|
|
d167a427b9 | ||
|
|
c89c20e842 | ||
|
|
ad04a48c8f | ||
|
|
d3a47b3dc6 | ||
|
|
02de30f617 | ||
|
|
a4360a0fa5 | ||
|
|
39d4dec294 | ||
|
|
4c189b4d56 | ||
|
|
8267b7d16d | ||
|
|
bf9f86d516 | ||
|
|
a93c4e9fb8 | ||
|
|
3243716d13 | ||
|
|
685418507b | ||
|
|
418c5fdcd0 | ||
|
|
322f28eaa6 | ||
|
|
7a06ab0b61 | ||
|
|
a5dda8ab9b | ||
|
|
54b5c139f3 | ||
|
|
864990dc8a | ||
|
|
1e0ccd72a2 | ||
|
|
513a8924d8 | ||
|
|
478d68ee25 | ||
|
|
175780aa06 | ||
|
|
c9558be2d3 | ||
|
|
f1d3a70bbd | ||
|
|
d3dd6f88f2 | ||
|
|
882d641683 | ||
|
|
a53f6073a6 | ||
|
|
7c7020f50a | ||
|
|
41b3c0f4fc | ||
|
|
314087321c | ||
|
|
c67067acaf | ||
|
|
d23be43c2f | ||
|
|
6c282ffbd7 | ||
|
|
0ecc65bbe0 | ||
|
|
076da040b5 | ||
|
|
17858cc17c | ||
|
|
66fec1f4a3 | ||
|
|
69848f11ca | ||
|
|
affbe2a460 | ||
|
|
cc40bb35fb | ||
|
|
542cc1f546 | ||
|
|
0d2fb25881 | ||
|
|
29f050d19f | ||
|
|
2238374080 | ||
|
|
cad8ecad8f | ||
|
|
d161053328 | ||
|
|
dbb74c5675 | ||
|
|
6422070f04 | ||
|
|
b6512ce8e4 | ||
|
|
a3e0bc0798 | ||
|
|
5ec70d1438 | ||
|
|
e848e18574 | ||
|
|
cfff970812 | ||
|
|
0db8c2feb2 | ||
|
|
7e06bf4fd0 | ||
|
|
dd710860de | ||
|
|
4718a9edab | ||
|
|
8c5db9229a | ||
|
|
e229438997 | ||
|
|
85a4490740 | ||
|
|
9684e84420 | ||
|
|
4364c028a2 | ||
|
|
4e44e26c6c | ||
|
|
b07c033863 | ||
|
|
f167f5cbd4 | ||
|
|
7a1b192392 | ||
|
|
642f371416 | ||
|
|
f4e2b6e115 | ||
|
|
1873d28b50 | ||
|
|
ce03b4efde | ||
|
|
102c113b0c | ||
|
|
245cd2e44c | ||
|
|
f28456875b | ||
|
|
9604eed2f3 | ||
|
|
4eda3a506b | ||
|
|
14f3dc7526 | ||
|
|
f2d3c88c85 | ||
|
|
f4e0efc8da | ||
|
|
13bfdeaa1a | ||
|
|
e2fb7c940f | ||
|
|
5bd7d9aa43 | ||
|
|
117c717391 | ||
|
|
72603a2db0 | ||
|
|
9f8cfa8de3 | ||
|
|
221dd45681 | ||
|
|
fb2a600433 | ||
|
|
296f8dddfa | ||
|
|
da16a38d1f | ||
|
|
5abc1fb80e | ||
|
|
86d5f5febd | ||
|
|
0a840abc58 | ||
|
|
968e9bd3ad | ||
|
|
ddd0e0c285 | ||
|
|
00952d5ef6 | ||
|
|
a0e1d8b11d | ||
|
|
3d7f2ec20c | ||
|
|
abbd2cf0a4 | ||
|
|
2f9961651f | ||
|
|
3089c28233 | ||
|
|
4e722dd123 | ||
|
|
5698a78d9b | ||
|
|
71804a0b41 | ||
|
|
d500c9093d |
@@ -20,8 +20,8 @@ engines:
|
||||
- ruby
|
||||
- javascript
|
||||
exclude_fingerprints:
|
||||
- 16dbcb58d6caa7ccfe241417831ecfa6
|
||||
- 7d7dca4f27f50e3084f203280073cc74
|
||||
- 16dbcb58d6caa7ccfe241417831ecfa6
|
||||
- 7d7dca4f27f50e3084f203280073cc74
|
||||
fixme:
|
||||
enabled: true
|
||||
exclude_fingerprints: # rubocop_todo filename
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -16,3 +16,4 @@ zeus.json
|
||||
.bundle
|
||||
.idea/**
|
||||
public/**
|
||||
node_modules
|
||||
@@ -1,4 +1,9 @@
|
||||
linters:
|
||||
LineLength:
|
||||
max: 120
|
||||
|
||||
InstanceVariables:
|
||||
enabled: false
|
||||
IdNames:
|
||||
enabled: false
|
||||
ConsecutiveComments:
|
||||
enabled: false
|
||||
|
||||
3
.mention-bot
Normal file
3
.mention-bot
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"userBlacklist": ["tygriffin","oshiho3"]
|
||||
}
|
||||
102
.overcommit.yml
Normal file
102
.overcommit.yml
Normal file
@@ -0,0 +1,102 @@
|
||||
---
|
||||
# Use this file to configure the Overcommit hooks you wish to use. This will
|
||||
# extend the default configuration defined in:
|
||||
# https://github.com/brigade/overcommit/blob/master/config/default.yml
|
||||
#
|
||||
# At the topmost level of this YAML file is a key representing type of hook
|
||||
# being run (e.g. pre-commit, commit-msg, etc.). Within each type you can
|
||||
# customize each hook, such as whether to only run it on certain files (via
|
||||
# `include`), whether to only display output if it fails (via `quiet`), etc.
|
||||
#
|
||||
# For a complete list of hooks, see:
|
||||
# https://github.com/brigade/overcommit/tree/master/lib/overcommit/hook
|
||||
#
|
||||
# For a complete list of options that you can use to customize hooks, see:
|
||||
# https://github.com/brigade/overcommit#configuration
|
||||
#
|
||||
# Uncomment the following lines to make the configuration take effect.
|
||||
|
||||
PreCommit:
|
||||
ALL:
|
||||
quiet: false
|
||||
problem_on_unmodified_line: warn
|
||||
RuboCop:
|
||||
enabled: true
|
||||
command: ['bundle', 'exec', 'rubocop', '-D', '--rails']
|
||||
TrailingWhitespace:
|
||||
enabled: true
|
||||
exclude:
|
||||
- '**/db/structure.sql' # Ignore trailing whitespace in generated files
|
||||
CoffeeLint:
|
||||
enabled: true
|
||||
on_fail: warn
|
||||
command: ['npm', 'run', 'coffeelint']
|
||||
HardTabs:
|
||||
enabled: true
|
||||
AuthorEmail:
|
||||
enabled: false
|
||||
AuthorName:
|
||||
enabled: false
|
||||
CssLint:
|
||||
enabled: true
|
||||
exclude:
|
||||
- '**/bootstrap.min.css'
|
||||
command: ['npm', 'run', 'csslint']
|
||||
HamlLint:
|
||||
enabled: true
|
||||
command: ['bundle', 'exec', 'haml-lint', 'app/views']
|
||||
JsonSyntax:
|
||||
enabled: true
|
||||
BundleOutdated:
|
||||
enabled: true
|
||||
on_warn: warn
|
||||
BundleAudit:
|
||||
enabled: true
|
||||
on_warn: warn
|
||||
JsHint:
|
||||
enabled: true
|
||||
exclude:
|
||||
- 'app/assets/**'
|
||||
- 'spec/javascripts/support/vendor/**'
|
||||
- '**/bootstrap*'
|
||||
command: ['npm', 'run', 'jshint']
|
||||
ScssLint:
|
||||
enabled: true
|
||||
RailsSchemaUpToDate:
|
||||
enabled: true
|
||||
MergeConflicts:
|
||||
enabled: true
|
||||
YamlLint:
|
||||
enabled: true
|
||||
|
||||
PostCommit:
|
||||
GitGuilt:
|
||||
enabled: true
|
||||
command: ['npm', 'run', 'git-guilt']
|
||||
|
||||
PostCheckout:
|
||||
ALL:
|
||||
quiet: false
|
||||
BundleInstall:
|
||||
enabled: true
|
||||
RailsSchemaUpToDate:
|
||||
enabled: true
|
||||
|
||||
PostMerge:
|
||||
BundleInstall:
|
||||
enabled: true
|
||||
RailsSchemaUpToDate:
|
||||
enabled: true
|
||||
|
||||
# PrePush:
|
||||
# ALL:
|
||||
# on_warn: fail # Treat all warnings as failures
|
||||
# quiet: false
|
||||
# # Brakeman:
|
||||
# # enabled: true
|
||||
# RSpec:
|
||||
# enabled: true
|
||||
# command: ['bundle', 'exec', 'rspec', '--fail-fast']
|
||||
#
|
||||
# IndexTags:
|
||||
# enabled: true # Generate a tags file with `ctags` each time HEAD changes
|
||||
47
.rubocop.yml
47
.rubocop.yml
@@ -27,38 +27,9 @@ Style/MultilineMethodCallIndentation:
|
||||
Style/AlignParameters:
|
||||
EnforcedStyle: with_fixed_indentation
|
||||
|
||||
Metrics/MethodLength:
|
||||
Description: 'Avoid methods longer than 30 lines of code.'
|
||||
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#short-methods'
|
||||
# Set to 30 once all methods are fixed.
|
||||
# Max: 30
|
||||
Max: 34
|
||||
|
||||
# Remove the following once the code style matches
|
||||
# Offense count: 59
|
||||
Metrics/AbcSize:
|
||||
Max: 32
|
||||
|
||||
# Offense count: 5
|
||||
# Configuration parameters: CountComments.
|
||||
Metrics/BlockLength:
|
||||
Max: 62
|
||||
|
||||
# Offense count: 6
|
||||
# Configuration parameters: CountComments.
|
||||
Metrics/ClassLength:
|
||||
Max: 269
|
||||
|
||||
# Offense count: 6
|
||||
Metrics/CyclomaticComplexity:
|
||||
Max: 11
|
||||
|
||||
Metrics/LineLength:
|
||||
Max: 120
|
||||
|
||||
# Offense count: 8
|
||||
Metrics/PerceivedComplexity:
|
||||
Max: 9
|
||||
|
||||
# See https://github.com/bbatsov/rubocop/issues/3629
|
||||
Rails/HttpPositionalArguments:
|
||||
@@ -76,3 +47,21 @@ Rails/Output:
|
||||
Exclude:
|
||||
- 'config/unicorn.rb'
|
||||
- 'db/seeds.rb'
|
||||
|
||||
Metrics/BlockLength:
|
||||
Exclude:
|
||||
- 'spec/**/*'
|
||||
- '**/*.rake'
|
||||
- 'config/**/*.rb'
|
||||
|
||||
# Remove the following once the code style matches
|
||||
Metrics/MethodLength:
|
||||
Max: 34
|
||||
Metrics/AbcSize:
|
||||
Max: 32
|
||||
Metrics/ClassLength:
|
||||
Max: 207
|
||||
Metrics/CyclomaticComplexity:
|
||||
Max: 11
|
||||
Metrics/PerceivedComplexity:
|
||||
Max: 9
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
# This configuration was generated by
|
||||
# `rubocop --auto-gen-config --exclude-limit 500`
|
||||
# on 2017-01-21 15:58:02 +1030 using RuboCop version 0.47.1.
|
||||
# `rubocop --auto-gen-config --no-offense-counts`
|
||||
# on 2017-05-28 10:57:55 +1200 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: 22
|
||||
Lint/AmbiguousRegexpLiteral:
|
||||
Exclude:
|
||||
- 'spec/controllers/admin/orders_controller_spec.rb'
|
||||
@@ -19,22 +18,18 @@ Lint/AmbiguousRegexpLiteral:
|
||||
- 'spec/views/members/show.rss.haml_spec.rb'
|
||||
- 'spec/views/posts/show.html.haml_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
Lint/HandleExceptions:
|
||||
Exclude:
|
||||
- 'lib/tasks/testing.rake'
|
||||
|
||||
# Offense count: 11
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments.
|
||||
Lint/UnusedBlockArgument:
|
||||
Exclude:
|
||||
- 'app/controllers/crops_controller.rb'
|
||||
- 'app/controllers/sessions_controller.rb'
|
||||
- 'config/unicorn.rb'
|
||||
- 'lib/haml/filters/growstuff_markdown.rb'
|
||||
|
||||
# Offense count: 6
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods.
|
||||
Lint/UnusedMethodArgument:
|
||||
@@ -45,47 +40,27 @@ Lint/UnusedMethodArgument:
|
||||
- 'app/validators/approved_validator.rb'
|
||||
- 'spec/views/plantings/show.html.haml_spec.rb'
|
||||
|
||||
# Offense count: 5
|
||||
Lint/Void:
|
||||
Exclude:
|
||||
- 'spec/models/crop_spec.rb'
|
||||
- 'spec/models/garden_spec.rb'
|
||||
- 'spec/models/post_spec.rb'
|
||||
|
||||
# Offense count: 55
|
||||
# Configuration parameters: CountComments, ExcludedMethods.
|
||||
Metrics/BlockLength:
|
||||
Exclude:
|
||||
- '**/*'
|
||||
|
||||
# Offense count: 2
|
||||
# Cop supports --auto-correct.
|
||||
Performance/StringReplacement:
|
||||
Exclude:
|
||||
- 'app/models/planting.rb'
|
||||
- 'spec/rails_helper.rb'
|
||||
|
||||
# Offense count: 4
|
||||
Rails/FilePath:
|
||||
Exclude:
|
||||
- 'spec/rails_helper.rb'
|
||||
|
||||
# Offense count: 3
|
||||
Rails/OutputSafety:
|
||||
Exclude:
|
||||
- 'app/helpers/application_helper.rb'
|
||||
- 'app/helpers/auto_suggest_helper.rb'
|
||||
- 'app/helpers/gardens_helper.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:
|
||||
@@ -96,7 +71,6 @@ Rails/TimeZone:
|
||||
- 'spec/models/post_spec.rb'
|
||||
- 'spec/views/plantings/index.html.haml_spec.rb'
|
||||
|
||||
# Offense count: 7
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: always, conditionals
|
||||
@@ -105,12 +79,10 @@ Style/AndOr:
|
||||
- 'config/unicorn.rb'
|
||||
- 'lib/tasks/growstuff.rake'
|
||||
|
||||
# Offense count: 1
|
||||
Style/AsciiComments:
|
||||
Exclude:
|
||||
- 'config/initializers/comfortable_mexican_sofa.rb'
|
||||
|
||||
# Offense count: 5
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: percent_q, bare_percent
|
||||
@@ -119,7 +91,6 @@ Style/BarePercentLiterals:
|
||||
- 'app/helpers/auto_suggest_helper.rb'
|
||||
- 'spec/support/feature_helpers.rb'
|
||||
|
||||
# Offense count: 26
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles, ProceduralMethods, FunctionalMethods, IgnoredMethods.
|
||||
# SupportedStyles: line_count_based, semantic, braces_for_chaining
|
||||
@@ -128,30 +99,21 @@ Style/BarePercentLiterals:
|
||||
# IgnoredMethods: lambda, proc, it
|
||||
Style/BlockDelimiters:
|
||||
Exclude:
|
||||
- 'app/controllers/members_controller.rb'
|
||||
- 'app/controllers/posts_controller.rb'
|
||||
- 'app/controllers/scientific_names_controller.rb'
|
||||
- 'spec/controllers/order_items_controller_spec.rb'
|
||||
- 'spec/features/notifications_spec.rb'
|
||||
- 'spec/models/ability_spec.rb'
|
||||
- 'spec/models/comment_spec.rb'
|
||||
- 'spec/models/follow_spec.rb'
|
||||
- 'spec/models/member_spec.rb'
|
||||
- 'spec/models/planting_spec.rb'
|
||||
- 'spec/models/post_spec.rb'
|
||||
- 'spec/views/crops/edit.html.haml_spec.rb'
|
||||
|
||||
# Offense count: 8
|
||||
# Cop supports --auto-correct.
|
||||
Style/BlockEndNewline:
|
||||
Exclude:
|
||||
- 'app/controllers/members_controller.rb'
|
||||
- 'app/controllers/posts_controller.rb'
|
||||
- 'spec/models/ability_spec.rb'
|
||||
- 'spec/models/member_spec.rb'
|
||||
- 'spec/models/planting_spec.rb'
|
||||
|
||||
# Offense count: 4
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: nested, compact
|
||||
Style/ClassAndModuleChildren:
|
||||
@@ -161,52 +123,25 @@ Style/ClassAndModuleChildren:
|
||||
- 'lib/haml/filters/escaped_markdown.rb'
|
||||
- 'lib/haml/filters/growstuff_markdown.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
Style/ClassMethods:
|
||||
Exclude:
|
||||
- 'app/models/planting.rb'
|
||||
|
||||
# Offense count: 2
|
||||
# Cop supports --auto-correct.
|
||||
Style/ColonMethodCall:
|
||||
Exclude:
|
||||
- 'spec/lib/haml/filters/escaped_markdown_spec.rb'
|
||||
- 'spec/lib/haml/filters/growstuff_markdown_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: Keywords.
|
||||
# Keywords: TODO, FIXME, OPTIMIZE, HACK, REVIEW
|
||||
Style/CommentAnnotation:
|
||||
Exclude:
|
||||
- 'app/controllers/crops_controller.rb'
|
||||
|
||||
# Offense count: 10
|
||||
# Cop supports --auto-correct.
|
||||
Style/EachForSimpleLoop:
|
||||
Exclude:
|
||||
- 'spec/models/crop_spec.rb'
|
||||
- 'spec/views/home/_crops.html.haml_spec.rb'
|
||||
|
||||
# Offense count: 11
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: compact, expanded
|
||||
Style/EmptyMethod:
|
||||
Exclude:
|
||||
- 'app/controllers/account_types_controller.rb'
|
||||
- 'app/controllers/accounts_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.
|
||||
# SupportedStyles: format, sprintf, percent
|
||||
Style/FormatString:
|
||||
@@ -215,23 +150,19 @@ Style/FormatString:
|
||||
- 'spec/helpers/application_helper_spec.rb'
|
||||
- 'spec/views/shop/index_spec.rb'
|
||||
|
||||
# Offense count: 2
|
||||
Style/IdenticalConditionalBranches:
|
||||
Exclude:
|
||||
- 'app/controllers/follows_controller.rb'
|
||||
|
||||
# Offense count: 6
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: MaxLineLength.
|
||||
Style/IfUnlessModifier:
|
||||
Exclude:
|
||||
- 'app/controllers/shop_controller.rb'
|
||||
- 'app/helpers/crops_helper.rb'
|
||||
- 'app/models/planting.rb'
|
||||
- 'config/initializers/geocoder.rb'
|
||||
- 'lib/tasks/growstuff.rake'
|
||||
|
||||
# Offense count: 7
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: line_count_dependent, lambda, literal
|
||||
@@ -240,44 +171,26 @@ Style/Lambda:
|
||||
- 'spec/controllers/member_controller_spec.rb'
|
||||
- 'spec/models/photo_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
Style/MultilineIfModifier:
|
||||
Exclude:
|
||||
- 'spec/rails_helper.rb'
|
||||
|
||||
# Offense count: 5
|
||||
# Cop supports --auto-correct.
|
||||
Style/MultilineIfThen:
|
||||
Exclude:
|
||||
- 'script/check_contributors_md'
|
||||
- 'script/gemfile_check'
|
||||
|
||||
# Offense count: 2
|
||||
Style/MultilineTernaryOperator:
|
||||
Exclude:
|
||||
- 'app/controllers/notifications_controller.rb'
|
||||
- 'app/controllers/order_items_controller.rb'
|
||||
|
||||
# Offense count: 3
|
||||
# Cop supports --auto-correct.
|
||||
Style/MutableConstant:
|
||||
Exclude:
|
||||
- 'app/controllers/members_controller.rb'
|
||||
- 'app/models/planting.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
Style/NegatedIf:
|
||||
Exclude:
|
||||
- 'app/helpers/crops_helper.rb'
|
||||
|
||||
# Offense count: 2
|
||||
Style/NestedTernaryOperator:
|
||||
Exclude:
|
||||
- 'app/controllers/plantings_controller.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, MinBodyLength, SupportedStyles.
|
||||
# SupportedStyles: skip_modifier_ifs, always
|
||||
@@ -285,26 +198,11 @@ Style/Next:
|
||||
Exclude:
|
||||
- 'lib/tasks/growstuff.rake'
|
||||
|
||||
# Offense count: 2
|
||||
# Cop supports --auto-correct.
|
||||
Style/NilComparison:
|
||||
Exclude:
|
||||
- 'lib/tasks/growstuff.rake'
|
||||
|
||||
# Offense count: 2
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedOctalStyle, SupportedOctalStyles.
|
||||
# SupportedOctalStyles: zero_with_o, zero_only
|
||||
Style/NumericLiteralPrefix:
|
||||
Exclude:
|
||||
- 'spec/views/plantings/_form.html.haml_spec.rb'
|
||||
|
||||
# Offense count: 3
|
||||
# Cop supports --auto-correct.
|
||||
Style/NumericLiterals:
|
||||
MinDigits: 9
|
||||
|
||||
# Offense count: 5
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: AutoCorrect, EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: predicate, comparison
|
||||
@@ -314,44 +212,25 @@ Style/NumericPredicate:
|
||||
- 'app/helpers/harvests_helper.rb'
|
||||
- 'app/helpers/plantings_helper.rb'
|
||||
- 'lib/tasks/growstuff.rake'
|
||||
- 'script/check_contributors_md'
|
||||
|
||||
# Offense count: 3
|
||||
# Cop supports --auto-correct.
|
||||
Style/ParallelAssignment:
|
||||
Exclude:
|
||||
- 'app/mailers/notifier.rb'
|
||||
|
||||
|
||||
# Offense count: 5
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: PreferredDelimiters.
|
||||
Style/PercentLiteralDelimiters:
|
||||
Exclude:
|
||||
- 'app/helpers/auto_suggest_helper.rb'
|
||||
- 'script/check_contributors_md'
|
||||
- 'spec/features/signin_spec.rb'
|
||||
- 'spec/features/signout_spec.rb'
|
||||
|
||||
# Offense count: 3
|
||||
# Cop supports --auto-correct.
|
||||
Style/PerlBackrefs:
|
||||
Exclude:
|
||||
- 'lib/haml/filters/growstuff_markdown.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
Style/RedundantParentheses:
|
||||
Exclude:
|
||||
- 'app/helpers/plantings_helper.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
Style/RedundantSelf:
|
||||
Exclude:
|
||||
- 'lib/geocodable.rb'
|
||||
|
||||
# Offense count: 6
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles, AllowInnerSlashes.
|
||||
# SupportedStyles: slashes, percent_r, mixed
|
||||
@@ -364,49 +243,24 @@ Style/RegexpLiteral:
|
||||
- 'spec/views/posts/index.html.haml_spec.rb'
|
||||
- 'spec/views/posts/show.html.haml_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
Style/SelfAssignment:
|
||||
Exclude:
|
||||
- 'app/helpers/crops_helper.rb'
|
||||
|
||||
# Offense count: 2
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: SupportedStyles.
|
||||
# SupportedStyles: use_perl_names, use_english_names
|
||||
Style/SpecialGlobalVars:
|
||||
EnforcedStyle: use_perl_names
|
||||
|
||||
# Offense count: 3
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: IgnoredMethods.
|
||||
# IgnoredMethods: respond_to, define_method
|
||||
Style/SymbolProc:
|
||||
Exclude:
|
||||
- 'app/controllers/crops_controller.rb'
|
||||
- 'lib/tasks/growstuff.rake'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles, AllowSafeAssignment.
|
||||
# SupportedStyles: require_parentheses, require_no_parentheses, require_parentheses_when_complex
|
||||
Style/TernaryParentheses:
|
||||
Exclude:
|
||||
- 'app/helpers/plantings_helper.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
Style/UnlessElse:
|
||||
Exclude:
|
||||
- 'app/controllers/omniauth_callbacks_controller.rb'
|
||||
|
||||
# Offense count: 3
|
||||
# Cop supports --auto-correct.
|
||||
Style/UnneededPercentQ:
|
||||
Exclude:
|
||||
- 'spec/support/feature_helpers.rb'
|
||||
|
||||
# Offense count: 2
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: SupportedStyles, WordRegex.
|
||||
# SupportedStyles: percent, brackets
|
||||
|
||||
@@ -1 +1 @@
|
||||
2.3.3
|
||||
2.3.4
|
||||
|
||||
49
.travis.yml
49
.travis.yml
@@ -7,41 +7,40 @@ cache:
|
||||
- tmp/cache/assets/test/sprockets
|
||||
env:
|
||||
matrix:
|
||||
- GROWSTUFF_ELASTICSEARCH='true' RSPEC_TAG=elasticsearch
|
||||
- GROWSTUFF_ELASTICSEARCH='false' RSPEC_TAG=~elasticsearch
|
||||
- STATIC_CHECKS='true'
|
||||
- GROWSTUFF_ELASTICSEARCH='true' RSPEC_TAG=elasticsearch STATIC_CHECKS=false
|
||||
- GROWSTUFF_ELASTICSEARCH='false' RSPEC_TAG=~elasticsearch STATIC_CHECKS=false
|
||||
- STATIC_CHECKS=true
|
||||
global:
|
||||
- GROWSTUFF_SITE_NAME="Growstuff (travis)"
|
||||
- RAILS_SECRET_TOKEN='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
|
||||
- secure: "Z5TpM2jEX4UCvNePnk/LwltQX48U2u9BRc+Iypr1x9QW2o228QJhPIOH39a8RMUrepGnkQIq9q3ZRUn98RfrJz1yThtlNFL3NmzdQ57gKgjGwfpa0e4Dwj/ZJqV2D84tDGjvdVYLP7zzaYZxQcwk/cgNpzKf/jq97HLNP7CYuf4="
|
||||
rvm:
|
||||
- 2.3.3
|
||||
- 2.3.4
|
||||
before_install:
|
||||
- ./script/install_phantomjs;
|
||||
- export PATH=$PWD/travis_phantomjs/phantomjs-2.1.1-linux-x86_64/bin:$PATH
|
||||
- >
|
||||
if [ $(phantomjs --version) != '2.1.1' ]; then
|
||||
PHANTOM_URL=https://assets.membergetmember.co/software/phantomjs-2.1.1-linux-x86_64.tar.bz2;
|
||||
rm -rf $PWD/travis_phantomjs;
|
||||
mkdir -p $PWD/travis_phantomjs;
|
||||
wget $PHANTOM_URL -O $PWD/travis_phantomjs/phantomjs-2.1.1-linux-x86_64.tar.bz2;
|
||||
tar -xvf $PWD/travis_phantomjs/phantomjs-2.1.1-linux-x86_64.tar.bz2 -C $PWD/travis_phantomjs;
|
||||
fi
|
||||
- phantomjs --version
|
||||
before_script:
|
||||
- bundle exec rake db:create db:migrate db:test:prepare
|
||||
- set -e
|
||||
- >
|
||||
if [ "$STATIC_CHECKS" != 'true' ]; then
|
||||
bundle exec rake db:create db:migrate db:test:prepare
|
||||
bundle exec rake assets:precompile
|
||||
fi
|
||||
script:
|
||||
- >
|
||||
if [ "$STATIC_CHECKS" = 'true' ]; then
|
||||
bundle exec script/check_static
|
||||
if [ "${STATIC_CHECKS}" = "true" ]; then
|
||||
./script/install_linters;
|
||||
else
|
||||
bundle exec rake db:migrate --trace
|
||||
bundle exec rspec --tag $RSPEC_TAG spec/
|
||||
bundle exec rake jasmine:ci
|
||||
bundle exec rake assets:precompile;
|
||||
fi
|
||||
- set +e
|
||||
script:
|
||||
- set -e
|
||||
- >
|
||||
if [ "${STATIC_CHECKS}" = "true" ]; then
|
||||
./script/check_static.rb
|
||||
else
|
||||
bundle exec rake db:migrate --trace;
|
||||
bundle exec rspec --tag $RSPEC_TAG spec/;
|
||||
bundle exec rake jasmine:ci;
|
||||
fi;
|
||||
- set +e
|
||||
|
||||
services:
|
||||
- elasticsearch
|
||||
before_deploy:
|
||||
@@ -49,7 +48,7 @@ before_deploy:
|
||||
deploy:
|
||||
provider: heroku
|
||||
api_key:
|
||||
secure: WrQxf0fEKkCdXrjcejurobOnNNz3he4dDwjBbToXbQTQNDObPp7NetJrLsfM8FiUFEeOuvhIHHiDQtMvY720zGGAGxDptvgFS+0QHCUqoTRZA/yFfUmHlG2jROXTzk5uVK0AE4k6Ion5kX8+mM0EnMT/7u+MTFiukrJctSiEXfg=
|
||||
secure: "WrQxf0fEKkCdXrjcejurobOnNNz3he4dDwjBbToXbQTQNDObPp7NetJrLsfM8FiUFEeOuvhIHHiDQtMvY720zGGAGxDptvgFS+0QHCUqoTRZA/yFfUmHlG2jROXTzk5uVK0AE4k6Ion5kX8+mM0EnMT/7u+MTFiukrJctSiEXfg="
|
||||
on:
|
||||
repo: Growstuff/growstuff
|
||||
app:
|
||||
|
||||
@@ -10,7 +10,6 @@ When you create a pull request, please include the following:
|
||||
All pull requests should pass our automatic continuous integration and style
|
||||
checks before being merged. You can run tests locally as follows:
|
||||
|
||||
- `rake` to run all tests and static checks
|
||||
- `rake spec` to run all Ruby tests
|
||||
- `rake spec:models` to run Ruby model tests (or `rake spec:views` for view tests, etc)
|
||||
- `rake static` to run all static checks (code style, unfixed Git conflicts, etc)
|
||||
@@ -24,6 +23,12 @@ checks before being merged. You can run tests locally as follows:
|
||||
failing tests so you can easily re-run particular ones.
|
||||
- `rspec --only-failures` to re-run all Ruby tests that failed last time.
|
||||
|
||||
Growstuff runs several linters and checkers before a change is merged. These
|
||||
run from overcommit. To automatically run the same linters yourself you can
|
||||
install overcommit too.
|
||||
|
||||
- `./script/install_linters`
|
||||
|
||||
You can run `rake -T` to see a list of available Rake tasks. If you can't get
|
||||
some tests to pass, please submit a pull request anyway - we'll be happy to
|
||||
help you debug the failures.
|
||||
|
||||
@@ -76,3 +76,12 @@ submit the change with your pull request.
|
||||
- Brenda Wallace / [br3nda](https://github.com/br3nda)
|
||||
- Jim Stallings / [jestallin](https://github.com/jestallin)
|
||||
- Alyssa Ransbury / [alran](https://github.com/alran)
|
||||
- Thomas Countz / [thomascountz](https://github.com/thomascountz)
|
||||
- Megan Talbot / [meganft](https://github.com/meganft)
|
||||
- Arun Kumar / [arun1595](https://github.com/arun1595)
|
||||
- Harry Brodsky / [hbrodsk1](https://github.com/hbrodsk1)
|
||||
- Jeff Kingswood / [ancyentmariner](https://github.com/ancyentmariner)
|
||||
|
||||
## Bots
|
||||
|
||||
- Security and Dependency Updates / [deppbot](https://github.com/deppbot)
|
||||
|
||||
53
Gemfile
53
Gemfile
@@ -1,28 +1,28 @@
|
||||
# frozen_string_literal: true
|
||||
source 'https://rubygems.org'
|
||||
|
||||
ruby '2.3.3'
|
||||
ruby '2.3.4'
|
||||
|
||||
gem 'rails', '~> 4.2.7'
|
||||
gem 'rails', '~> 4.2.8'
|
||||
|
||||
gem 'bundler', '>=1.1.5'
|
||||
|
||||
gem 'coffee-rails', '~> 4.1.0'
|
||||
gem 'coffee-rails'
|
||||
gem 'haml'
|
||||
gem 'sass-rails', '~> 5.0.4'
|
||||
gem 'sass-rails'
|
||||
|
||||
# CSS framework
|
||||
gem 'bootstrap-sass', '~> 3.3.6'
|
||||
gem 'bootstrap-sass'
|
||||
gem 'font-awesome-sass'
|
||||
|
||||
gem 'uglifier', '~> 2.7.2' # JavaScript compressor
|
||||
gem 'uglifier' # JavaScript compressor
|
||||
|
||||
gem 'flickraw'
|
||||
gem 'jquery-rails'
|
||||
gem 'jquery-ui-rails', '~> 5.0.2'
|
||||
gem 'jquery-ui-rails', '~> 5.0.2' # needs careful upgrade with change of location
|
||||
gem 'js-routes' # provides access to Rails routes in Javascript
|
||||
|
||||
gem 'cancancan', '~> 1.9' # for checking member privileges
|
||||
gem 'cancancan' # for checking member privileges
|
||||
gem 'csv_shaper' # CSV export
|
||||
gem 'figaro' # for handling config via ENV variables
|
||||
gem 'gibbon', '~>1.2.0' # for Mailchimp newsletter subscriptions
|
||||
@@ -32,26 +32,26 @@ gem 'pg'
|
||||
gem 'ruby-units' # for unit conversion
|
||||
gem 'unicorn' # http server
|
||||
|
||||
gem 'comfortable_mexican_sofa', '~> 1.12.0' # content management system
|
||||
gem 'comfortable_mexican_sofa' # content management system
|
||||
|
||||
gem 'bootstrap-kaminari-views' # bootstrap views for kaminari
|
||||
gem 'kaminari' # pagination
|
||||
|
||||
gem 'active_utils'
|
||||
gem 'activemerchant'
|
||||
gem 'active_utils'
|
||||
gem 'sidekiq'
|
||||
|
||||
# Markdown formatting for updates etc
|
||||
gem 'bluecloth'
|
||||
|
||||
# Pagination
|
||||
gem 'will_paginate', '~> 3.0'
|
||||
gem 'will_paginate'
|
||||
|
||||
# user signup/login/etc
|
||||
gem 'devise', '>= 4.0.0'
|
||||
gem 'devise'
|
||||
|
||||
# nicely formatted URLs
|
||||
gem 'friendly_id', '~> 5.0.4'
|
||||
gem 'friendly_id'
|
||||
|
||||
# gravatars
|
||||
gem 'gravatar-ultimate'
|
||||
@@ -63,13 +63,13 @@ gem 'geocoder'
|
||||
gem 'bootstrap-datepicker-rails'
|
||||
|
||||
# For connecting to other services (eg Twitter)
|
||||
gem 'omniauth'
|
||||
gem 'omniauth', '~> 1.3'
|
||||
gem 'omniauth-facebook'
|
||||
gem 'omniauth-flickr', '>= 0.0.15'
|
||||
gem 'omniauth-twitter'
|
||||
|
||||
# For charting data
|
||||
gem 'd3-rails'
|
||||
gem 'd3-rails', '~> 3.5' # 4.* produces Error: <spyOn> : could not find an object to spy upon for linear() - see https://travis-ci.org/Growstuff/growstuff/jobs/204461482
|
||||
|
||||
# client for Elasticsearch. Elasticsearch is a flexible
|
||||
# and powerful, distributed, real-time search and analytics engine.
|
||||
@@ -80,13 +80,16 @@ gem 'd3-rails'
|
||||
# See https://github.com/elastic/elasticsearch-ruby#compatibility
|
||||
gem "elasticsearch-api", "~> 2.0.0"
|
||||
gem "elasticsearch-model"
|
||||
gem "hashie", ">= 3.5.3"
|
||||
gem "elasticsearch-rails"
|
||||
gem "hashie", ">= 3.5.3"
|
||||
|
||||
gem 'rake', '>= 10.0.0'
|
||||
|
||||
# # CMS
|
||||
# gem 'comfortable_mexican_sofa', '~> 1.12.0'
|
||||
# locale based flash notices for controllers
|
||||
gem "responders"
|
||||
|
||||
# allows soft delete. Used for members.
|
||||
gem 'acts_as_paranoid', '~> 0.5.0'
|
||||
|
||||
group :production, :staging do
|
||||
gem 'bonsai-elasticsearch-rails' # Integration with Bonsa-Elasticsearch on heroku
|
||||
@@ -112,29 +115,31 @@ end
|
||||
|
||||
group :development, :test do
|
||||
gem "active_merchant-paypal-bogus-gateway"
|
||||
gem 'bullet' # performance tuning by finding unnecesary queries
|
||||
gem 'byebug' # debugging
|
||||
gem 'capybara' # integration tests
|
||||
gem 'capybara-email' # integration tests for email
|
||||
gem 'capybara-screenshot' # for test debugging
|
||||
gem 'coveralls', require: false # coverage analysis
|
||||
gem 'database_cleaner', '~> 1.5.0'
|
||||
gem 'database_cleaner'
|
||||
gem 'factory_girl_rails' # for creating test data
|
||||
gem 'haml-i18n-extractor'
|
||||
gem 'haml_lint' # Checks haml files for goodness
|
||||
gem 'haml-rails' # HTML templating language
|
||||
gem 'haml_lint' # Checks haml files for goodness
|
||||
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 'rspec-activemodel-mocks'
|
||||
gem 'rspec-rails' # unit testing framework
|
||||
gem 'rubocop', '<= 0.47.1', require: false # Pin to rubocop (0.47.1) as 0.48.0 is buggy
|
||||
gem 'selenium-webdriver'
|
||||
gem 'webrat' # provides HTML matchers for view tests
|
||||
gem 'webrat' # provides HTML matchers for view tests
|
||||
end
|
||||
|
||||
group :test do
|
||||
gem 'codeclimate-test-reporter', require: false
|
||||
gem 'timecop'
|
||||
end
|
||||
|
||||
group :travis do
|
||||
|
||||
369
Gemfile.lock
369
Gemfile.lock
@@ -1,58 +1,61 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
actionmailer (4.2.7.1)
|
||||
actionpack (= 4.2.7.1)
|
||||
actionview (= 4.2.7.1)
|
||||
activejob (= 4.2.7.1)
|
||||
actionmailer (4.2.9)
|
||||
actionpack (= 4.2.9)
|
||||
actionview (= 4.2.9)
|
||||
activejob (= 4.2.9)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||
actionpack (4.2.7.1)
|
||||
actionview (= 4.2.7.1)
|
||||
activesupport (= 4.2.7.1)
|
||||
actionpack (4.2.9)
|
||||
actionview (= 4.2.9)
|
||||
activesupport (= 4.2.9)
|
||||
rack (~> 1.6)
|
||||
rack-test (~> 0.6.2)
|
||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||
actionview (4.2.7.1)
|
||||
activesupport (= 4.2.7.1)
|
||||
actionview (4.2.9)
|
||||
activesupport (= 4.2.9)
|
||||
builder (~> 3.1)
|
||||
erubis (~> 2.7.0)
|
||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||
active_link_to (1.0.3)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
||||
active_link_to (1.0.4)
|
||||
actionpack
|
||||
addressable
|
||||
active_merchant-paypal-bogus-gateway (0.1.0)
|
||||
activemerchant
|
||||
active_utils (3.2.3)
|
||||
activesupport (>= 3.2, < 5.1.0)
|
||||
active_utils (3.3.7)
|
||||
activesupport (>= 3.2, < 5.2.0)
|
||||
i18n
|
||||
activejob (4.2.7.1)
|
||||
activesupport (= 4.2.7.1)
|
||||
activejob (4.2.9)
|
||||
activesupport (= 4.2.9)
|
||||
globalid (>= 0.3.0)
|
||||
activemerchant (1.63.0)
|
||||
activesupport (>= 3.2.14, < 5.1)
|
||||
activemerchant (1.69.0)
|
||||
activesupport (>= 3.2.14, < 6.x)
|
||||
builder (>= 2.1.2, < 4.0.0)
|
||||
i18n (>= 0.6.9)
|
||||
nokogiri (~> 1.4)
|
||||
activemodel (4.2.7.1)
|
||||
activesupport (= 4.2.7.1)
|
||||
activemodel (4.2.9)
|
||||
activesupport (= 4.2.9)
|
||||
builder (~> 3.1)
|
||||
activerecord (4.2.7.1)
|
||||
activemodel (= 4.2.7.1)
|
||||
activesupport (= 4.2.7.1)
|
||||
activerecord (4.2.9)
|
||||
activemodel (= 4.2.9)
|
||||
activesupport (= 4.2.9)
|
||||
arel (~> 6.0)
|
||||
activesupport (4.2.7.1)
|
||||
activesupport (4.2.9)
|
||||
i18n (~> 0.7)
|
||||
json (~> 1.7, >= 1.7.7)
|
||||
minitest (~> 5.1)
|
||||
thread_safe (~> 0.3, >= 0.3.4)
|
||||
tzinfo (~> 1.1)
|
||||
addressable (2.5.0)
|
||||
acts_as_paranoid (0.5.0)
|
||||
activerecord (>= 4.0, < 5.1)
|
||||
activesupport (>= 4.0, < 5.1)
|
||||
addressable (2.5.1)
|
||||
public_suffix (~> 2.0, >= 2.0.2)
|
||||
arel (6.0.4)
|
||||
ast (2.3.0)
|
||||
autoprefixer-rails (6.6.1)
|
||||
autoprefixer-rails (7.1.2.3)
|
||||
execjs
|
||||
bcrypt (3.1.11)
|
||||
better_errors (2.1.1)
|
||||
@@ -62,7 +65,9 @@ GEM
|
||||
binding_of_caller (0.7.2)
|
||||
debug_inspector (>= 0.0.1)
|
||||
bluecloth (2.2.0)
|
||||
bonsai-elasticsearch-rails (0.0.4)
|
||||
bonsai-elasticsearch-rails (0.2.0)
|
||||
elasticsearch-model (~> 0)
|
||||
elasticsearch-rails (~> 0)
|
||||
bootstrap-datepicker-rails (1.6.4.1)
|
||||
railties (>= 3.0)
|
||||
bootstrap-kaminari-views (0.0.5)
|
||||
@@ -71,11 +76,14 @@ GEM
|
||||
bootstrap-sass (3.3.7)
|
||||
autoprefixer-rails (>= 5.2.1)
|
||||
sass (>= 3.3.4)
|
||||
bootstrap_form (2.6.0)
|
||||
bootstrap_form (2.7.0)
|
||||
builder (3.2.3)
|
||||
bullet (5.6.0)
|
||||
activesupport (>= 3.0.0)
|
||||
uniform_notifier (~> 1.10.0)
|
||||
byebug (9.0.6)
|
||||
cancancan (1.16.0)
|
||||
capybara (2.12.0)
|
||||
cancancan (2.0.0)
|
||||
capybara (2.14.4)
|
||||
addressable
|
||||
mime-types (>= 1.16)
|
||||
nokogiri (>= 1.3.3)
|
||||
@@ -85,23 +93,23 @@ GEM
|
||||
capybara-email (2.5.0)
|
||||
capybara (~> 2.4)
|
||||
mail
|
||||
capybara-screenshot (1.0.14)
|
||||
capybara-screenshot (1.0.17)
|
||||
capybara (>= 1.0, < 3)
|
||||
launchy
|
||||
childprocess (0.6.1)
|
||||
childprocess (0.7.1)
|
||||
ffi (~> 1.0, >= 1.0.11)
|
||||
climate_control (0.1.0)
|
||||
climate_control (0.2.0)
|
||||
cliver (0.3.2)
|
||||
cocaine (0.5.8)
|
||||
climate_control (>= 0.0.3, < 1.0)
|
||||
codeclimate-test-reporter (1.0.3)
|
||||
simplecov
|
||||
codeclimate-test-reporter (1.0.8)
|
||||
simplecov (<= 0.13)
|
||||
codemirror-rails (5.16.0)
|
||||
railties (>= 3.0, < 6.0)
|
||||
coderay (1.1.1)
|
||||
coffee-rails (4.1.1)
|
||||
coffee-rails (4.2.2)
|
||||
coffee-script (>= 2.2.0)
|
||||
railties (>= 4.0.0, < 5.1.x)
|
||||
railties (>= 4.0.0)
|
||||
coffee-script (2.4.1)
|
||||
coffee-script-source
|
||||
execjs
|
||||
@@ -121,7 +129,7 @@ GEM
|
||||
rails (>= 4.0.0, < 5.1)
|
||||
rails-i18n (>= 4.0.0)
|
||||
sass-rails (>= 4.0.3)
|
||||
concurrent-ruby (1.0.4)
|
||||
concurrent-ruby (1.0.5)
|
||||
connection_pool (2.2.1)
|
||||
coveralls (0.8.19)
|
||||
json (>= 1.8, < 3)
|
||||
@@ -131,15 +139,15 @@ GEM
|
||||
tins (~> 1.6)
|
||||
csv_shaper (1.3.0)
|
||||
activesupport (>= 3.0.0)
|
||||
d3-rails (3.4.13)
|
||||
d3-rails (3.5.17)
|
||||
railties (>= 3.1)
|
||||
dalli (2.7.6)
|
||||
database_cleaner (1.5.3)
|
||||
debug_inspector (0.0.2)
|
||||
devise (4.2.0)
|
||||
database_cleaner (1.6.1)
|
||||
debug_inspector (0.0.3)
|
||||
devise (4.3.0)
|
||||
bcrypt (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (>= 4.1.0, < 5.1)
|
||||
railties (>= 4.1.0, < 5.2)
|
||||
responders
|
||||
warden (~> 1.2.3)
|
||||
diff-lcs (1.3)
|
||||
@@ -148,44 +156,44 @@ GEM
|
||||
json
|
||||
thread
|
||||
thread_safe
|
||||
elasticsearch (2.0.1)
|
||||
elasticsearch-api (= 2.0.1)
|
||||
elasticsearch-transport (= 2.0.1)
|
||||
elasticsearch-api (2.0.1)
|
||||
elasticsearch (2.0.2)
|
||||
elasticsearch-api (= 2.0.2)
|
||||
elasticsearch-transport (= 2.0.2)
|
||||
elasticsearch-api (2.0.2)
|
||||
multi_json
|
||||
elasticsearch-model (0.1.9)
|
||||
activesupport (> 3)
|
||||
elasticsearch (> 0.4)
|
||||
hashie
|
||||
elasticsearch-rails (0.1.9)
|
||||
elasticsearch-transport (2.0.1)
|
||||
elasticsearch-transport (2.0.2)
|
||||
faraday
|
||||
multi_json
|
||||
erubis (2.7.0)
|
||||
excon (0.54.0)
|
||||
excon (0.57.1)
|
||||
execjs (2.7.0)
|
||||
factory_girl (4.8.0)
|
||||
activesupport (>= 3.0.0)
|
||||
factory_girl_rails (4.8.0)
|
||||
factory_girl (~> 4.8.0)
|
||||
railties (>= 3.0.0)
|
||||
faraday (0.9.2)
|
||||
faraday (0.12.2)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
ffi (1.9.17)
|
||||
ffi (1.9.18)
|
||||
figaro (1.1.1)
|
||||
thor (~> 0.14)
|
||||
flickraw (0.9.9)
|
||||
font-awesome-sass (4.7.0)
|
||||
sass (>= 3.2)
|
||||
formatador (0.2.5)
|
||||
friendly_id (5.0.5)
|
||||
friendly_id (5.2.1)
|
||||
activerecord (>= 4.0.0)
|
||||
geocoder (1.4.3)
|
||||
geocoder (1.4.4)
|
||||
gibbon (1.2.1)
|
||||
httparty
|
||||
multi_json (>= 1.9.0)
|
||||
globalid (0.3.7)
|
||||
activesupport (>= 4.1.0)
|
||||
globalid (0.4.0)
|
||||
activesupport (>= 4.2.0)
|
||||
gravatar-ultimate (2.0.0)
|
||||
activesupport (>= 2.3.14)
|
||||
rack
|
||||
@@ -203,7 +211,8 @@ GEM
|
||||
guard (~> 2.1)
|
||||
guard-compat (~> 1.1)
|
||||
rspec (>= 2.99.0, < 4.0)
|
||||
haml (4.0.7)
|
||||
haml (5.0.1)
|
||||
temple (>= 0.8.0)
|
||||
tilt
|
||||
haml-i18n-extractor (0.5.9)
|
||||
activesupport
|
||||
@@ -211,30 +220,31 @@ GEM
|
||||
highline
|
||||
tilt
|
||||
trollop (= 1.16.2)
|
||||
haml-rails (0.9.0)
|
||||
haml-rails (1.0.0)
|
||||
actionpack (>= 4.0.1)
|
||||
activesupport (>= 4.0.1)
|
||||
haml (>= 4.0.6, < 5.0)
|
||||
haml (>= 4.0.6, < 6.0)
|
||||
html2haml (>= 1.0.1)
|
||||
railties (>= 4.0.1)
|
||||
haml_lint (0.20.0)
|
||||
haml (~> 4.0)
|
||||
haml_lint (0.25.1)
|
||||
haml (>= 4.0, < 5.1)
|
||||
rainbow
|
||||
rake (>= 10, < 13)
|
||||
rubocop (>= 0.47.0)
|
||||
sysexits (~> 1.1)
|
||||
hashie (3.5.3)
|
||||
hashie (3.5.6)
|
||||
heroku-api (0.4.2)
|
||||
excon (~> 0.45)
|
||||
multi_json (~> 1.8)
|
||||
highline (1.7.8)
|
||||
html2haml (2.0.0)
|
||||
html2haml (2.2.0)
|
||||
erubis (~> 2.7.0)
|
||||
haml (~> 4.0.0)
|
||||
nokogiri (~> 1.6.0)
|
||||
haml (>= 4.0, < 6)
|
||||
nokogiri (>= 1.6.0)
|
||||
ruby_parser (~> 3.5)
|
||||
httparty (0.14.0)
|
||||
httparty (0.15.6)
|
||||
multi_xml (>= 0.5.2)
|
||||
i18n (0.8.0)
|
||||
i18n (0.8.6)
|
||||
i18n-tasks (0.9.12)
|
||||
activesupport (>= 4.0.2)
|
||||
ast (>= 2.1.0)
|
||||
@@ -245,28 +255,37 @@ GEM
|
||||
parser (>= 2.2.3.0)
|
||||
term-ansicolor (>= 1.3.2)
|
||||
terminal-table (>= 1.5.1)
|
||||
jasmine (2.5.1)
|
||||
jasmine-core (>= 2.5.1, < 3.0.0)
|
||||
jasmine (2.6.0)
|
||||
jasmine-core (>= 2.6.0, < 3.0.0)
|
||||
phantomjs
|
||||
rack (>= 1.2.1)
|
||||
rake
|
||||
jasmine-core (2.5.2)
|
||||
jquery-rails (4.2.2)
|
||||
jasmine-core (2.6.4)
|
||||
jquery-rails (4.3.1)
|
||||
rails-dom-testing (>= 1, < 3)
|
||||
railties (>= 4.2.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
jquery-ui-rails (5.0.5)
|
||||
railties (>= 3.2.16)
|
||||
js-routes (1.3.0)
|
||||
js-routes (1.3.3)
|
||||
railties (>= 3.2)
|
||||
sprockets-rails
|
||||
json (1.8.6)
|
||||
json (2.1.0)
|
||||
jwt (1.5.6)
|
||||
kaminari (0.17.0)
|
||||
actionpack (>= 3.0.0)
|
||||
activesupport (>= 3.0.0)
|
||||
kaminari (1.0.1)
|
||||
activesupport (>= 4.1.0)
|
||||
kaminari-actionview (= 1.0.1)
|
||||
kaminari-activerecord (= 1.0.1)
|
||||
kaminari-core (= 1.0.1)
|
||||
kaminari-actionview (1.0.1)
|
||||
actionview
|
||||
kaminari-core (= 1.0.1)
|
||||
kaminari-activerecord (1.0.1)
|
||||
activerecord
|
||||
kaminari-core (= 1.0.1)
|
||||
kaminari-core (1.0.1)
|
||||
kgio (2.11.0)
|
||||
kramdown (1.13.2)
|
||||
kramdown (1.14.0)
|
||||
launchy (2.4.3)
|
||||
addressable (~> 2.3)
|
||||
leaflet-markercluster-rails (0.7.0)
|
||||
@@ -280,8 +299,8 @@ GEM
|
||||
ruby_dep (~> 1.2)
|
||||
loofah (2.0.3)
|
||||
nokogiri (>= 1.5.9)
|
||||
lumberjack (1.0.11)
|
||||
mail (2.6.4)
|
||||
lumberjack (1.0.12)
|
||||
mail (2.6.6)
|
||||
mime-types (>= 1.16, < 4)
|
||||
memcachier (0.0.2)
|
||||
method_source (0.8.2)
|
||||
@@ -289,28 +308,28 @@ GEM
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2016.0521)
|
||||
mimemagic (0.3.2)
|
||||
mini_portile2 (2.1.0)
|
||||
minitest (5.10.1)
|
||||
mini_portile2 (2.2.0)
|
||||
minitest (5.10.3)
|
||||
multi_json (1.11.3)
|
||||
multi_xml (0.6.0)
|
||||
multipart-post (2.0.0)
|
||||
nenv (0.3.0)
|
||||
newrelic_rpm (3.18.1.330)
|
||||
nokogiri (1.6.8.1)
|
||||
mini_portile2 (~> 2.1.0)
|
||||
newrelic_rpm (4.3.0.335)
|
||||
nokogiri (1.8.0)
|
||||
mini_portile2 (~> 2.2.0)
|
||||
notiffany (0.1.1)
|
||||
nenv (~> 0.1)
|
||||
shellany (~> 0.0)
|
||||
oauth (0.5.1)
|
||||
oauth2 (1.2.0)
|
||||
faraday (>= 0.8, < 0.10)
|
||||
oauth (0.5.3)
|
||||
oauth2 (1.4.0)
|
||||
faraday (>= 0.8, < 0.13)
|
||||
jwt (~> 1.0)
|
||||
multi_json (~> 1.3)
|
||||
multi_xml (~> 0.5)
|
||||
rack (>= 1.2, < 3)
|
||||
omniauth (1.3.2)
|
||||
hashie (>= 1.2, < 4)
|
||||
rack (>= 1.0, < 3)
|
||||
omniauth (1.6.1)
|
||||
hashie (>= 3.4.6, < 3.6.0)
|
||||
rack (>= 1.6.2, < 3)
|
||||
omniauth-facebook (4.0.0)
|
||||
omniauth-oauth2 (~> 1.2)
|
||||
omniauth-flickr (0.0.19)
|
||||
@@ -322,9 +341,9 @@ GEM
|
||||
omniauth-oauth2 (1.4.0)
|
||||
oauth2 (~> 1.0)
|
||||
omniauth (~> 1.2)
|
||||
omniauth-twitter (1.2.1)
|
||||
json (~> 1.3)
|
||||
omniauth-twitter (1.4.0)
|
||||
omniauth-oauth (~> 1.1)
|
||||
rack
|
||||
orm_adapter (0.5.0)
|
||||
paperclip (5.1.0)
|
||||
activemodel (>= 4.2.0)
|
||||
@@ -334,11 +353,11 @@ GEM
|
||||
mimemagic (~> 0.3.0)
|
||||
parser (2.4.0.0)
|
||||
ast (~> 2.2)
|
||||
pg (0.19.0)
|
||||
pg (0.21.0)
|
||||
phantomjs (2.1.1.0)
|
||||
plupload-rails (1.2.1)
|
||||
rails (>= 3.1)
|
||||
poltergeist (1.13.0)
|
||||
poltergeist (1.15.0)
|
||||
capybara (~> 2.1)
|
||||
cliver (~> 0.3.1)
|
||||
websocket-driver (>= 0.2.0)
|
||||
@@ -350,21 +369,21 @@ GEM
|
||||
public_suffix (2.0.5)
|
||||
quiet_assets (1.1.0)
|
||||
railties (>= 3.1, < 5.0)
|
||||
rack (1.6.5)
|
||||
rack-protection (1.5.3)
|
||||
rack (1.6.8)
|
||||
rack-protection (2.0.0)
|
||||
rack
|
||||
rack-test (0.6.3)
|
||||
rack (>= 1.0)
|
||||
rails (4.2.7.1)
|
||||
actionmailer (= 4.2.7.1)
|
||||
actionpack (= 4.2.7.1)
|
||||
actionview (= 4.2.7.1)
|
||||
activejob (= 4.2.7.1)
|
||||
activemodel (= 4.2.7.1)
|
||||
activerecord (= 4.2.7.1)
|
||||
activesupport (= 4.2.7.1)
|
||||
rails (4.2.9)
|
||||
actionmailer (= 4.2.9)
|
||||
actionpack (= 4.2.9)
|
||||
actionview (= 4.2.9)
|
||||
activejob (= 4.2.9)
|
||||
activemodel (= 4.2.9)
|
||||
activerecord (= 4.2.9)
|
||||
activesupport (= 4.2.9)
|
||||
bundler (>= 1.3.0, < 2.0)
|
||||
railties (= 4.2.7.1)
|
||||
railties (= 4.2.9)
|
||||
sprockets-rails
|
||||
rails-deprecated_sanitizer (1.0.3)
|
||||
activesupport (>= 4.2.0.alpha)
|
||||
@@ -382,45 +401,46 @@ GEM
|
||||
rails_stdout_logging
|
||||
rails_serve_static_assets (0.0.5)
|
||||
rails_stdout_logging (0.0.5)
|
||||
railties (4.2.7.1)
|
||||
actionpack (= 4.2.7.1)
|
||||
activesupport (= 4.2.7.1)
|
||||
railties (4.2.9)
|
||||
actionpack (= 4.2.9)
|
||||
activesupport (= 4.2.9)
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
rainbow (2.1.0)
|
||||
raindrops (0.17.0)
|
||||
raindrops (0.18.0)
|
||||
rake (12.0.0)
|
||||
rb-fsevent (0.9.8)
|
||||
rb-inotify (0.9.8)
|
||||
ffi (>= 0.5.0)
|
||||
rb-fsevent (0.10.2)
|
||||
rb-inotify (0.9.10)
|
||||
ffi (>= 0.5.0, < 2)
|
||||
redis (3.3.3)
|
||||
responders (2.3.0)
|
||||
railties (>= 4.2.0, < 5.1)
|
||||
rspec (3.5.0)
|
||||
rspec-core (~> 3.5.0)
|
||||
rspec-expectations (~> 3.5.0)
|
||||
rspec-mocks (~> 3.5.0)
|
||||
responders (2.4.0)
|
||||
actionpack (>= 4.2.0, < 5.3)
|
||||
railties (>= 4.2.0, < 5.3)
|
||||
rspec (3.6.0)
|
||||
rspec-core (~> 3.6.0)
|
||||
rspec-expectations (~> 3.6.0)
|
||||
rspec-mocks (~> 3.6.0)
|
||||
rspec-activemodel-mocks (1.0.3)
|
||||
activemodel (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
rspec-mocks (>= 2.99, < 4.0)
|
||||
rspec-core (3.5.4)
|
||||
rspec-support (~> 3.5.0)
|
||||
rspec-expectations (3.5.0)
|
||||
rspec-core (3.6.0)
|
||||
rspec-support (~> 3.6.0)
|
||||
rspec-expectations (3.6.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.5.0)
|
||||
rspec-mocks (3.5.0)
|
||||
rspec-support (~> 3.6.0)
|
||||
rspec-mocks (3.6.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.5.0)
|
||||
rspec-rails (3.5.2)
|
||||
rspec-support (~> 3.6.0)
|
||||
rspec-rails (3.6.0)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
rspec-core (~> 3.5.0)
|
||||
rspec-expectations (~> 3.5.0)
|
||||
rspec-mocks (~> 3.5.0)
|
||||
rspec-support (~> 3.5.0)
|
||||
rspec-support (3.5.0)
|
||||
rspec-core (~> 3.6.0)
|
||||
rspec-expectations (~> 3.6.0)
|
||||
rspec-mocks (~> 3.6.0)
|
||||
rspec-support (~> 3.6.0)
|
||||
rspec-support (3.6.0)
|
||||
rubocop (0.47.1)
|
||||
parser (>= 2.3.3.1, < 3.0)
|
||||
powerpack (~> 0.1)
|
||||
@@ -428,34 +448,37 @@ GEM
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (~> 1.0, >= 1.0.1)
|
||||
ruby-progressbar (1.8.1)
|
||||
ruby-units (2.0.1)
|
||||
ruby-units (2.1.0)
|
||||
ruby_dep (1.5.0)
|
||||
ruby_parser (3.8.4)
|
||||
sexp_processor (~> 4.1)
|
||||
ruby_parser (3.10.1)
|
||||
sexp_processor (~> 4.9)
|
||||
rubyzip (1.2.1)
|
||||
sass (3.4.23)
|
||||
sass (3.5.1)
|
||||
sass-listen (~> 4.0.0)
|
||||
sass-listen (4.0.0)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
sass-rails (5.0.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 (3.0.8)
|
||||
selenium-webdriver (3.4.4)
|
||||
childprocess (~> 0.5)
|
||||
rubyzip (~> 1.0)
|
||||
websocket (~> 1.0)
|
||||
sexp_processor (4.7.0)
|
||||
sexp_processor (4.10.0)
|
||||
shellany (0.0.1)
|
||||
sidekiq (4.2.9)
|
||||
sidekiq (5.0.4)
|
||||
concurrent-ruby (~> 1.0)
|
||||
connection_pool (~> 2.2, >= 2.2.0)
|
||||
rack-protection (>= 1.5.0)
|
||||
redis (~> 3.2, >= 3.2.1)
|
||||
redis (~> 3.3, >= 3.3.3)
|
||||
simplecov (0.12.0)
|
||||
docile (~> 1.1.0)
|
||||
json (>= 1.8, < 3)
|
||||
simplecov-html (~> 0.10.0)
|
||||
simplecov-html (0.10.0)
|
||||
simplecov-html (0.10.1)
|
||||
slop (3.6.0)
|
||||
sparkpost_rails (1.4.0)
|
||||
rails (>= 4.0, < 5.1)
|
||||
@@ -467,37 +490,38 @@ GEM
|
||||
activesupport (>= 4.0)
|
||||
sprockets (>= 3.0.0)
|
||||
sysexits (1.2.0)
|
||||
term-ansicolor (1.4.0)
|
||||
temple (0.8.0)
|
||||
term-ansicolor (1.6.0)
|
||||
tins (~> 1.0)
|
||||
terminal-table (1.7.3)
|
||||
unicode-display_width (~> 1.1.1)
|
||||
terminal-table (1.8.0)
|
||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||
thor (0.19.4)
|
||||
thread (0.2.2)
|
||||
thread_safe (0.3.5)
|
||||
tilt (2.0.6)
|
||||
tins (1.13.2)
|
||||
thread_safe (0.3.6)
|
||||
tilt (2.0.8)
|
||||
timecop (0.9.1)
|
||||
tins (1.15.0)
|
||||
trollop (1.16.2)
|
||||
tzinfo (1.2.2)
|
||||
tzinfo (1.2.3)
|
||||
thread_safe (~> 0.1)
|
||||
uglifier (2.7.2)
|
||||
execjs (>= 0.3.0)
|
||||
json (>= 1.8.0)
|
||||
unicode-display_width (1.1.3)
|
||||
unicorn (5.2.0)
|
||||
uglifier (3.2.0)
|
||||
execjs (>= 0.3.0, < 3)
|
||||
unicode-display_width (1.3.0)
|
||||
unicorn (5.3.0)
|
||||
kgio (~> 2.6)
|
||||
raindrops (~> 0.7)
|
||||
uniform_notifier (1.10.0)
|
||||
warden (1.2.7)
|
||||
rack (>= 1.0)
|
||||
webrat (0.7.3)
|
||||
nokogiri (>= 1.2.0)
|
||||
rack (>= 1.0)
|
||||
rack-test (>= 0.5.3)
|
||||
websocket (1.2.4)
|
||||
websocket-driver (0.6.5)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.2)
|
||||
will_paginate (3.1.5)
|
||||
xpath (2.0.0)
|
||||
will_paginate (3.1.6)
|
||||
xpath (2.1.0)
|
||||
nokogiri (~> 1.3)
|
||||
|
||||
PLATFORMS
|
||||
@@ -507,28 +531,30 @@ DEPENDENCIES
|
||||
active_merchant-paypal-bogus-gateway
|
||||
active_utils
|
||||
activemerchant
|
||||
acts_as_paranoid (~> 0.5.0)
|
||||
better_errors
|
||||
binding_of_caller
|
||||
bluecloth
|
||||
bonsai-elasticsearch-rails
|
||||
bootstrap-datepicker-rails
|
||||
bootstrap-kaminari-views
|
||||
bootstrap-sass (~> 3.3.6)
|
||||
bootstrap-sass
|
||||
bullet
|
||||
bundler (>= 1.1.5)
|
||||
byebug
|
||||
cancancan (~> 1.9)
|
||||
cancancan
|
||||
capybara
|
||||
capybara-email
|
||||
capybara-screenshot
|
||||
codeclimate-test-reporter
|
||||
coffee-rails (~> 4.1.0)
|
||||
comfortable_mexican_sofa (~> 1.12.0)
|
||||
coffee-rails
|
||||
comfortable_mexican_sofa
|
||||
coveralls
|
||||
csv_shaper
|
||||
d3-rails
|
||||
d3-rails (~> 3.5)
|
||||
dalli
|
||||
database_cleaner (~> 1.5.0)
|
||||
devise (>= 4.0.0)
|
||||
database_cleaner
|
||||
devise
|
||||
elasticsearch-api (~> 2.0.0)
|
||||
elasticsearch-model
|
||||
elasticsearch-rails
|
||||
@@ -536,7 +562,7 @@ DEPENDENCIES
|
||||
figaro
|
||||
flickraw
|
||||
font-awesome-sass
|
||||
friendly_id (~> 5.0.4)
|
||||
friendly_id
|
||||
geocoder
|
||||
gibbon (~> 1.2.0)
|
||||
gravatar-ultimate
|
||||
@@ -559,7 +585,7 @@ DEPENDENCIES
|
||||
letter_opener
|
||||
memcachier
|
||||
newrelic_rpm
|
||||
omniauth
|
||||
omniauth (~> 1.3)
|
||||
omniauth-facebook
|
||||
omniauth-flickr (>= 0.0.15)
|
||||
omniauth-twitter
|
||||
@@ -567,25 +593,28 @@ DEPENDENCIES
|
||||
poltergeist
|
||||
pry
|
||||
quiet_assets
|
||||
rails (~> 4.2.7)
|
||||
rails (~> 4.2.8)
|
||||
rails_12factor
|
||||
rainbow (< 2.2.0)
|
||||
rake (>= 10.0.0)
|
||||
responders
|
||||
rspec-activemodel-mocks
|
||||
rspec-rails
|
||||
rubocop
|
||||
rubocop (<= 0.47.1)
|
||||
ruby-units
|
||||
sass-rails (~> 5.0.4)
|
||||
sass-rails
|
||||
selenium-webdriver
|
||||
sidekiq
|
||||
sparkpost_rails
|
||||
uglifier (~> 2.7.2)
|
||||
timecop
|
||||
uglifier
|
||||
unicorn
|
||||
webrat
|
||||
will_paginate (~> 3.0)
|
||||
will_paginate
|
||||
|
||||
|
||||
RUBY VERSION
|
||||
ruby 2.3.3p222
|
||||
ruby 2.3.4p301
|
||||
|
||||
BUNDLED WITH
|
||||
1.13.7
|
||||
1.15.1
|
||||
|
||||
16
README.md
16
README.md
@@ -1,6 +1,6 @@
|
||||
# Growstuff
|
||||
|
||||
[](https://travis-ci.org/Growstuff/growstuff)
|
||||
[](https://travis-ci.org/Growstuff/growstuff)
|
||||
[](https://coveralls.io/r/Growstuff/growstuff)
|
||||
[](https://codeclimate.com/github/Growstuff/growstuff)
|
||||
|
||||
@@ -19,7 +19,6 @@ encourage participation from people of all backgrounds and skill levels.
|
||||
|
||||
* [Issues](http://github.com/Growstuff/growstuff/issues) (features we're
|
||||
working on, known bugs, etc)
|
||||
* [Discussion forums](http://talk.growstuff.org/) (design ideas, planning releases)
|
||||
* [IRC](https://webchat.freenode.net/) growstuff channel (general chat, brainstorming and troubleshooting) or [Gitter](https://gitter.im/Growstuff/growstuff)
|
||||
* [Wiki](https://github.com/Growstuff/growstuff/wiki) (general documentation, etc. Help by migrating from the [old wiki](https://web.archive.org/web/*/wiki.growstuff.org))
|
||||
|
||||
@@ -30,8 +29,7 @@ frontend features. We welcome contributions -- see
|
||||
[CONTRIBUTING](CONTRIBUTING.md) for details.
|
||||
|
||||
* To set up your development environment, see [Getting started](https://github.com/Growstuff/growstuff/wiki/New-contributor-guide).
|
||||
* We encourage [pair programming](http://wiki.growstuff.org/index.php/Pairing), especially for newer developers. [Find a pair programming partner.](http://talk.growstuff.org/t/find-a-pair-programming-partner/13)
|
||||
* Drop in to our [discussion forums](http://talk.growstuff.org/), IRC or Gitter to chat to other developers, get help, etc.
|
||||
* We encourage [pair programming](http://wiki.growstuff.org/index.php/Pairing), especially for newer developers.
|
||||
* You may also be interested in our [API](https://github.com/Growstuff/growstuff/wiki/API).
|
||||
|
||||
## For designers, writers, researchers, data wranglers, and other contributors
|
||||
@@ -41,23 +39,25 @@ your skills and interests.
|
||||
|
||||
You might like to check out:
|
||||
|
||||
* The [Get Involved](http://wiki.growstuff.org/index.php/Get_involved)
|
||||
* The [New Contributor Guide](https://github.com/Growstuff/growstuff/wiki/New-contributor-guide)
|
||||
page on our wiki, which has lots of detail for different areas
|
||||
* [Growstuff Talk](http://talk.growstuff.org/) especially the [Idea category](http://talk.growstuff.org/c/idea)
|
||||
|
||||
Here on Github, you might find these useful:
|
||||
|
||||
* [Waffle](http://waffle.io/Growstuff/growstuff) has stories in "ready" that can be worked on.
|
||||
* [needs: design](https://github.com/Growstuff/growstuff/labels/needs:%20design) - tasks requiring high-level design
|
||||
* [needs: visual design](https://github.com/Growstuff/growstuff/labels/needs:%20visual design) - tasks requiring visual/graphical design
|
||||
* [needs: documentation](https://github.com/Growstuff/growstuff/labels/needs:%20documentation)
|
||||
* [needs: data](https://github.com/Growstuff/growstuff/labels/needs:%20data) - tasks requiring data entry, data design, data import, or similar
|
||||
* [curated:beginner](https://github.com/Growstuff/growstuff/labels/curated:%20beginner) - tasks that are ideal for beginner programmers or people new to the project
|
||||
|
||||
Feel free to comment on any of the issues you find there, or open up a broader conversation on [Growstuff Talk](http://talk.growstuff.org).
|
||||
Feel free to comment on any of the issues on [Github](https://github.com/Growstuff/growstuff/issues).
|
||||
|
||||
## Contact
|
||||
|
||||
For more information about this project, contact [info@growstuff.org](mailto:info@growstuff.org).
|
||||
|
||||
Security Issues: If you find an authorization bypass or data breach, please contact our maintainers directly at [maintainers@growstuff.org](mailto:maintainers@growstuff.org).
|
||||
|
||||
You can also contact us on [Twitter](http://twitter.com/growstufforg/) or
|
||||
[Facebook](https://www.facebook.com/pages/Growstuff/1531133417099494).
|
||||
[Facebook](https://www.facebook.com/pages/Growstuff/1531133417099494) or [Github](https://github.com/Growstuff/growstuff/issues)..
|
||||
|
||||
@@ -31,10 +31,10 @@ This file draws the labels to the left of each bar.
|
||||
var barLabelTopEdge = 17;
|
||||
return i * barHeight * (barLabelSpread) + barLabelTopEdge;
|
||||
})
|
||||
.text(function(d){return d});
|
||||
.text(function(d){return d;});
|
||||
|
||||
};
|
||||
|
||||
growstuff.BarLabelGroup = BarLabelGroup;
|
||||
|
||||
}())
|
||||
}());
|
||||
@@ -26,7 +26,7 @@ to the display size of the svg
|
||||
|
||||
WidthScale.prototype.getMaxValue = function(){
|
||||
return d3.max(this._data.bars.map(function(bar) { return bar.value; }));
|
||||
}
|
||||
};
|
||||
|
||||
growstuff.WidthScale = WidthScale;
|
||||
|
||||
|
||||
@@ -21,10 +21,10 @@ $ ->
|
||||
|
||||
$('#remove-sci_name-row').click ->
|
||||
if (sci_index > 2)
|
||||
sci_index = sci_index - 1
|
||||
tmp = 'sci_template[' + sci_index + ']'
|
||||
element = document.getElementById(tmp)
|
||||
element.remove()
|
||||
sci_index = sci_index - 1
|
||||
tmp = 'sci_template[' + sci_index + ']'
|
||||
element = document.getElementById(tmp)
|
||||
element.remove()
|
||||
|
||||
alt_template = "<div id='alt_template[INDEX]' class='template col-md-12'><div class='col-md-2'><label>Alternate name INDEX:</label></div><div class='col-md-8'><input name='alt_name[INDEX]' class='form-control', id='alt_name[INDEX]')'></input><span class='help-block'>Alternate name of crop.</span></div><div class='col-md-2'></div></div>"
|
||||
|
||||
|
||||
@@ -108,8 +108,6 @@ p.stats
|
||||
|
||||
.planting
|
||||
dl.planting-attributes
|
||||
font-size: 85%
|
||||
|
||||
dt
|
||||
text-align: left
|
||||
dd
|
||||
@@ -118,14 +116,13 @@ p.stats
|
||||
@media (min-width: $screen-md-min)
|
||||
.planting-thumbnail
|
||||
dl.planting-attributes
|
||||
font-size: 85%
|
||||
width: 100%
|
||||
|
||||
dt
|
||||
text-align: left
|
||||
width: 80px
|
||||
width: 120px
|
||||
dd
|
||||
padding-left: 80px
|
||||
padding-left: 120px
|
||||
margin-left: auto
|
||||
|
||||
.navbar .navbar-form
|
||||
@@ -333,3 +330,10 @@ $state-success-bg: lighten($green, 50%)
|
||||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
white-space: nowrap
|
||||
|
||||
ul.plantings
|
||||
list-style-type: none
|
||||
|
||||
ul.thumbnail-buttons
|
||||
list-style-type: none
|
||||
text-align: right
|
||||
|
||||
@@ -1,67 +1,48 @@
|
||||
class AccountTypesController < ApplicationController
|
||||
before_action :authenticate_member!
|
||||
load_and_authorize_resource
|
||||
respond_to :html
|
||||
|
||||
# GET /account_types
|
||||
def index
|
||||
@account_types = AccountType.all
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
end
|
||||
respond_with(@account_types)
|
||||
end
|
||||
|
||||
# GET /account_types/1
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.html # show.html.erb
|
||||
end
|
||||
respond_with(@account_types)
|
||||
end
|
||||
|
||||
# GET /account_types/new
|
||||
def new
|
||||
@account_type = AccountType.new
|
||||
|
||||
respond_to do |format|
|
||||
format.html # new.html.erb
|
||||
end
|
||||
respond_with(@account_type)
|
||||
end
|
||||
|
||||
# GET /account_types/1/edit
|
||||
def edit
|
||||
respond_with(@account_type)
|
||||
end
|
||||
|
||||
# POST /account_types
|
||||
def create
|
||||
@account_type = AccountType.new(account_type_params)
|
||||
|
||||
respond_to do |format|
|
||||
if @account_type.save
|
||||
format.html { redirect_to @account_type, notice: I18n.t('account_types.created') }
|
||||
else
|
||||
format.html { render action: "new" }
|
||||
end
|
||||
end
|
||||
flash[:notice] = I18n.t('account_types.created') if @account_type.save
|
||||
respond_with(@account_type)
|
||||
end
|
||||
|
||||
# PUT /account_types/1
|
||||
def update
|
||||
respond_to do |format|
|
||||
if @account_type.update(account_type_params)
|
||||
format.html { redirect_to @account_type, notice: I18n.t('account_types.updated') }
|
||||
else
|
||||
format.html { render action: "edit" }
|
||||
end
|
||||
end
|
||||
flash[:notice] = I18n.t('account_types.updated') if @account_type.update(account_type_params)
|
||||
respond_with(@account_type)
|
||||
end
|
||||
|
||||
# DELETE /account_types/1
|
||||
def destroy
|
||||
@account_type.destroy
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to account_types_url, notice: I18n.t('account_types.deleted') }
|
||||
end
|
||||
flash[:notice] = I18n.t('account_types.deleted')
|
||||
respond_with(@account_type)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -1,36 +1,26 @@
|
||||
class AccountsController < ApplicationController
|
||||
before_action :authenticate_member!
|
||||
load_and_authorize_resource
|
||||
respond_to :html
|
||||
|
||||
# GET /accounts
|
||||
def index
|
||||
@accounts = Account.all
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
end
|
||||
respond_with(@accounts)
|
||||
end
|
||||
|
||||
# GET /accounts/1
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.html # show.html.erb
|
||||
end
|
||||
respond_with(@account)
|
||||
end
|
||||
|
||||
# GET /accounts/1/edit
|
||||
def edit
|
||||
end
|
||||
def edit; end
|
||||
|
||||
# PUT /accounts/1
|
||||
def update
|
||||
respond_to do |format|
|
||||
if @account.update(params[:account])
|
||||
format.html { redirect_to @account, notice: I18n.t('account.update') }
|
||||
else
|
||||
format.html { render action: "edit" }
|
||||
end
|
||||
end
|
||||
flash[:notice] = I18n.t('account.update') if @account.update(params[:account])
|
||||
respond_with(@account)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
class AdminController < ApplicationController
|
||||
respond_to :html
|
||||
def index
|
||||
authorize! :manage, :all
|
||||
respond_to do |format|
|
||||
format.html # index.html.haml
|
||||
end
|
||||
end
|
||||
|
||||
def newsletter
|
||||
authorize! :manage, :all
|
||||
@members = Member.confirmed.wants_newsletter.all
|
||||
respond_to do |format|
|
||||
format.html # index.html.haml
|
||||
end
|
||||
respond_with @members
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,6 +2,7 @@ class AlternateNamesController < ApplicationController
|
||||
before_action :authenticate_member!, except: [:index, :show]
|
||||
load_and_authorize_resource
|
||||
respond_to :html, :json
|
||||
responders :flash
|
||||
|
||||
# GET /alternate_names
|
||||
# GET /alternate_names.json
|
||||
|
||||
@@ -3,56 +3,42 @@ class CommentsController < ApplicationController
|
||||
load_and_authorize_resource
|
||||
respond_to :html, :json
|
||||
respond_to :rss, only: :index
|
||||
responders :flash
|
||||
|
||||
# GET /comments
|
||||
# GET /comments.json
|
||||
# GET /comments.rss
|
||||
def index
|
||||
@comments = Comment.paginate(page: params[:page])
|
||||
respond_with(@comments)
|
||||
end
|
||||
|
||||
# GET /comments/new
|
||||
# GET /comments/new.json
|
||||
def new
|
||||
@comment = Comment.new
|
||||
@post = Post.find_by(id: params[:post_id])
|
||||
|
||||
if @post
|
||||
@comments = @post.comments
|
||||
respond_with(@comment)
|
||||
respond_with(@comments)
|
||||
else
|
||||
redirect_to(request.referer || root_url,
|
||||
alert: "Can't post a comment on a non-existent post")
|
||||
end
|
||||
end
|
||||
|
||||
# GET /comments/1/edit
|
||||
def edit
|
||||
@comments = @comment.post.comments
|
||||
end
|
||||
|
||||
# POST /comments
|
||||
# POST /comments.json
|
||||
def create
|
||||
@comment = Comment.new(comment_params)
|
||||
@comment.author = current_member
|
||||
flash[:notice] = "Comment was successfully created." if @comment.save
|
||||
respond_with(@comment.post)
|
||||
@comment.save
|
||||
respond_with @comment, location: @comment.post
|
||||
end
|
||||
|
||||
# PUT /comments/1
|
||||
# PUT /comments/1.json
|
||||
def update
|
||||
# only body can be updated
|
||||
if @comment.update(body: comment_params['body'])
|
||||
flash[:notice] = 'Comment was successfully updated.'
|
||||
end
|
||||
respond_with(@comment.post)
|
||||
@comment.update(body: comment_params['body'])
|
||||
respond_with @comment, location: @comment.post
|
||||
end
|
||||
|
||||
# DELETE /comments/1
|
||||
# DELETE /comments/1.json
|
||||
def destroy
|
||||
@post = @comment.post
|
||||
@comment.destroy
|
||||
|
||||
@@ -4,40 +4,22 @@ class CropsController < ApplicationController
|
||||
before_action :authenticate_member!, except: [:index, :hierarchy, :search, :show]
|
||||
load_and_authorize_resource
|
||||
skip_authorize_resource only: [:hierarchy, :search]
|
||||
respond_to :html, :json, :rss, :csv
|
||||
responders :flash
|
||||
|
||||
# GET /crops
|
||||
# GET /crops.json
|
||||
def index
|
||||
@sort = params[:sort]
|
||||
@crops = if @sort == 'alpha'
|
||||
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 }
|
||||
format.rss do
|
||||
@crops = Crop.recent.includes(:scientific_names, :creator)
|
||||
render rss: @crops
|
||||
end
|
||||
format.csv do
|
||||
@filename = "Growstuff-Crops-#{Time.zone.now.to_s(:number)}.csv"
|
||||
@crops = Crop.includes(:scientific_names, :plantings, :seeds, :creator)
|
||||
render csv: @crops
|
||||
end
|
||||
end
|
||||
@crops = crops
|
||||
@num_requested_crops = requested_crops.size if current_member
|
||||
@filename = filename
|
||||
respond_with @crops
|
||||
end
|
||||
|
||||
def requested
|
||||
@requested = Crop.pending_approval.where(requester: current_member).paginate(page: params[:page])
|
||||
@requested = requested_crops.paginate(page: params[:page])
|
||||
respond_with @requested
|
||||
end
|
||||
|
||||
# GET /crops/wrangle
|
||||
def wrangle
|
||||
@approval_status = params[:approval_status]
|
||||
@crops = case @approval_status
|
||||
@@ -47,176 +29,124 @@ class CropsController < ApplicationController
|
||||
Crop.rejected
|
||||
else
|
||||
Crop.recent
|
||||
end
|
||||
|
||||
@crops = @crops.paginate(page: params[:page])
|
||||
end.paginate(page: params[:page])
|
||||
|
||||
@crop_wranglers = Role.crop_wranglers
|
||||
respond_to do |format|
|
||||
format.html
|
||||
end
|
||||
respond_with @crops
|
||||
end
|
||||
|
||||
# GET /crops/hierarchy
|
||||
def hierarchy
|
||||
@crops = Crop.toplevel
|
||||
respond_to do |format|
|
||||
format.html
|
||||
end
|
||||
respond_with @crops
|
||||
end
|
||||
|
||||
# GET /crops/search
|
||||
def search
|
||||
@term = params[:term]
|
||||
@matches = Crop.search(@term)
|
||||
@paginated_matches = @matches.paginate(page: params[:page])
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.json { render json: @matches }
|
||||
end
|
||||
respond_with @matches
|
||||
end
|
||||
|
||||
# GET /crops/1
|
||||
# GET /crops/1.json
|
||||
def show
|
||||
@crop = Crop.includes(:scientific_names, plantings: :photos).find(params[:id])
|
||||
@posts = @crop.posts.paginate(page: params[:page])
|
||||
|
||||
respond_to do |format|
|
||||
format.html # show.html.haml
|
||||
format.json do
|
||||
# TODO RABL or similar one day to avoid presentation logic here
|
||||
owner_structure = {
|
||||
owner: {
|
||||
only: [:id, :login_name, :location, :latitude, :longitude]
|
||||
}
|
||||
}
|
||||
render json: @crop.to_json(include: {
|
||||
plantings: {
|
||||
include: owner_structure
|
||||
}
|
||||
})
|
||||
end
|
||||
format.json { render json: @crop.to_json(crop_json_fields) }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /crops/new
|
||||
# GET /crops/new.json
|
||||
def new
|
||||
@crop = Crop.new
|
||||
@crop.alternate_names.build
|
||||
@crop.scientific_names.build
|
||||
|
||||
respond_to do |format|
|
||||
format.html # new.html.haml
|
||||
format.json { render json: @crop }
|
||||
end
|
||||
respond_with @crop
|
||||
end
|
||||
|
||||
# GET /crops/1/edit
|
||||
def edit
|
||||
@crop.alternate_names.build if @crop.alternate_names.blank?
|
||||
@crop.scientific_names.build if @crop.scientific_names.blank?
|
||||
end
|
||||
|
||||
# POST /crops
|
||||
# POST /crops.json
|
||||
def create
|
||||
@crop = Crop.new(crop_params)
|
||||
|
||||
if current_member.role? :crop_wrangler
|
||||
@crop.creator = current_member
|
||||
success_msg = "Crop was successfully created."
|
||||
else
|
||||
@crop.requester = current_member
|
||||
@crop.approval_status = "pending"
|
||||
success_msg = "Crop was successfully requested."
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
if @crop.save
|
||||
params[:alt_name].each do |index, value|
|
||||
create_name('alternate', value)
|
||||
end
|
||||
params[:sci_name].each do |index, value|
|
||||
create_name('scientific', value)
|
||||
end
|
||||
unless current_member.role? :crop_wrangler
|
||||
Role.crop_wranglers.each do |w|
|
||||
Notifier.new_crop_request(w, @crop).deliver_now!
|
||||
end
|
||||
end
|
||||
notify_wranglers if Crop.transaction { @crop.save && save_crop_names }
|
||||
|
||||
format.html { redirect_to @crop, notice: success_msg }
|
||||
format.json { render json: @crop, status: :created, location: @crop }
|
||||
else
|
||||
format.html { render action: "new" }
|
||||
format.json { render json: @crop.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
respond_with @crop
|
||||
end
|
||||
|
||||
# PUT /crops/1
|
||||
# PUT /crops/1.json
|
||||
def update
|
||||
previous_status = @crop.approval_status
|
||||
|
||||
@crop.creator = current_member if previous_status == "pending"
|
||||
|
||||
respond_to do |format|
|
||||
if @crop.update(crop_params)
|
||||
recreate_names('alt_name', 'alternate')
|
||||
recreate_names('sci_name', 'scientific')
|
||||
if @crop.update(crop_params)
|
||||
recreate_names('alt_name', 'alternate')
|
||||
recreate_names('sci_name', 'scientific')
|
||||
|
||||
if previous_status == "pending"
|
||||
requester = @crop.requester
|
||||
new_status = @crop.approval_status
|
||||
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 }
|
||||
else
|
||||
format.html { render action: "edit" }
|
||||
format.json { render json: @crop.errors, status: :unprocessable_entity }
|
||||
end
|
||||
notifier.deliver_now! if previous_status == "pending"
|
||||
end
|
||||
|
||||
respond_with @crop
|
||||
end
|
||||
|
||||
# DELETE /crops/1
|
||||
# DELETE /crops/1.json
|
||||
def destroy
|
||||
@crop.destroy
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to crops_url }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
respond_with @crop
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def popular_crops
|
||||
Crop.popular.includes(:scientific_names, plantings: :photos)
|
||||
def notifier
|
||||
case @crop.approval_status
|
||||
when "approved"
|
||||
Notifier.crop_request_approved(@crop.requester, @crop)
|
||||
when "rejected"
|
||||
Notifier.crop_request_rejected(@crop.requester, @crop)
|
||||
end
|
||||
end
|
||||
|
||||
def save_crop_names
|
||||
params[:alt_name]&.values&.each do |value|
|
||||
create_name!('alternate', value) unless value.empty?
|
||||
end
|
||||
params[:sci_name]&.values&.each do |value|
|
||||
create_name!('scientific', value) unless value.empty?
|
||||
end
|
||||
end
|
||||
|
||||
def notify_wranglers
|
||||
return if current_member.role? :crop_wrangler
|
||||
Role.crop_wranglers.each do |w|
|
||||
Notifier.new_crop_request(w, @crop).deliver_now!
|
||||
end
|
||||
end
|
||||
|
||||
def recreate_names(param_name, name_type)
|
||||
return unless params[param_name].present?
|
||||
destroy_names(name_type)
|
||||
params[param_name].each do |index, value|
|
||||
create_name(name_type, value)
|
||||
params[param_name].each do |_i, value|
|
||||
create_name!(name_type, value)
|
||||
end
|
||||
end
|
||||
|
||||
def destroy_names(name_type)
|
||||
@crop.send("#{name_type}_names").each do |alt_name|
|
||||
alt_name.destroy
|
||||
end
|
||||
@crop.send("#{name_type}_names").each(&:destroy)
|
||||
end
|
||||
|
||||
def create_name(name_type, value)
|
||||
@crop.send("#{name_type}_names").create(name: value, creator_id: current_member.id)
|
||||
def create_name!(name_type, value)
|
||||
@crop.send("#{name_type}_names").create!(name: value, creator_id: current_member.id)
|
||||
end
|
||||
|
||||
def crop_params
|
||||
@@ -227,8 +157,37 @@ class CropsController < ApplicationController
|
||||
:approval_status,
|
||||
:request_notes,
|
||||
:reason_for_rejection,
|
||||
:rejection_notes, scientific_names_attributes: [:scientific_name,
|
||||
:_destroy,
|
||||
:id])
|
||||
:rejection_notes,
|
||||
scientific_names_attributes: [:scientific_name,
|
||||
:_destroy,
|
||||
:id])
|
||||
end
|
||||
|
||||
def filename
|
||||
"Growstuff-Crops-#{Time.zone.now.to_s(:number)}.csv"
|
||||
end
|
||||
|
||||
def crop_json_fields
|
||||
{
|
||||
include: {
|
||||
plantings: {
|
||||
include: {
|
||||
owner: { only: [:id, :login_name, :location, :latitude, :longitude] }
|
||||
}
|
||||
},
|
||||
scientific_names: { only: [:name] },
|
||||
alternate_names: { only: [:name] }
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def crops
|
||||
q = Crop.approved.includes(:scientific_names, plantings: :photos)
|
||||
q = q.popular unless @sort == 'alpha'
|
||||
q.includes(:photos).paginate(page: params[:page])
|
||||
end
|
||||
|
||||
def requested_crops
|
||||
current_member.requested_crops.pending_approval
|
||||
end
|
||||
end
|
||||
|
||||
@@ -10,13 +10,18 @@ class GardensController < ApplicationController
|
||||
@owner = Member.find_by(slug: params[:owner])
|
||||
@show_all = params[:all] == '1'
|
||||
@gardens = gardens
|
||||
|
||||
respond_with(@gardens)
|
||||
end
|
||||
|
||||
# GET /gardens/1
|
||||
# GET /gardens/1.json
|
||||
def show
|
||||
@current_plantings = @garden.plantings.current
|
||||
.includes(:crop, :owner)
|
||||
.order(planted_at: :desc)
|
||||
@finished_plantings = @garden.plantings.finished
|
||||
.includes(:crop)
|
||||
.order(finished_at: :desc)
|
||||
respond_with(@garden)
|
||||
end
|
||||
|
||||
@@ -63,7 +68,6 @@ class GardensController < ApplicationController
|
||||
def gardens
|
||||
g = @owner ? @owner.gardens : Garden.all
|
||||
g = g.active unless @show_all
|
||||
g = g.includes(:owner).order(:name)
|
||||
g.paginate(page: params[:page])
|
||||
g.joins(:owner).order(:updated_at).paginate(page: params[:page])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,56 +3,45 @@ class HarvestsController < ApplicationController
|
||||
load_and_authorize_resource
|
||||
respond_to :html, :json
|
||||
respond_to :csv, only: :index
|
||||
responders :flash
|
||||
|
||||
# GET /harvests
|
||||
# GET /harvests.json
|
||||
def index
|
||||
@owner = Member.find_by(slug: params[:owner])
|
||||
@crop = Crop.find_by(slug: params[:crop])
|
||||
@owner = Member.find_by(slug: params[:owner]) if params[:owner]
|
||||
@crop = Crop.find_by(slug: params[:crop]) if params[:crop]
|
||||
@planting = Planting.find_by(slug: params[:planting_id]) if params[:planting_id]
|
||||
|
||||
@harvests = harvests
|
||||
@filename = csv_filename
|
||||
respond_with(@harvests)
|
||||
end
|
||||
|
||||
# GET /harvests/1
|
||||
# GET /harvests/1.json
|
||||
def show
|
||||
@matching_plantings = matching_plantings if @harvest.owner == current_member
|
||||
respond_with(@harvest)
|
||||
end
|
||||
|
||||
# GET /harvests/new
|
||||
# GET /harvests/new.json
|
||||
def new
|
||||
@harvest = Harvest.new(harvested_at: Time.zone.today)
|
||||
@planting = Planting.find_by(slug: params[:planting_id]) if params[:planting_id]
|
||||
# using find_by_id here because it returns nil, unlike find
|
||||
@crop = Crop.find_by(id: params[:crop_id])
|
||||
respond_with(@harvest)
|
||||
end
|
||||
|
||||
# GET /harvests/1/edit
|
||||
def edit
|
||||
@planting = @harvest.planting if @harvest.planting_id
|
||||
end
|
||||
|
||||
# POST /harvests
|
||||
# POST /harvests.json
|
||||
def create
|
||||
@harvest.crop_id = @harvest.planting.crop_id if @harvest.planting_id
|
||||
flash[:notice] = I18n.t('harvests.created') if @harvest.save
|
||||
@harvest.save
|
||||
respond_with(@harvest)
|
||||
end
|
||||
|
||||
# PUT /harvests/1
|
||||
# PUT /harvests/1.json
|
||||
def update
|
||||
flash[:notice] = I18n.t('harvests.updated') if @harvest.update(harvest_params)
|
||||
@harvest.update(harvest_params)
|
||||
respond_with(@harvest)
|
||||
end
|
||||
|
||||
# DELETE /harvests/1
|
||||
# DELETE /harvests/1.json
|
||||
def destroy
|
||||
@harvest.destroy
|
||||
respond_with(@harvest)
|
||||
@@ -79,9 +68,11 @@ class HarvestsController < ApplicationController
|
||||
@owner.harvests
|
||||
elsif @crop
|
||||
@crop.harvests
|
||||
elsif @planting
|
||||
@planting.harvests
|
||||
else
|
||||
Harvest
|
||||
end.includes(:owner, :crop).paginate(page: params[:page])
|
||||
end.joins(:owner, :crop).paginate(page: params[:page])
|
||||
end
|
||||
|
||||
def csv_filename
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
class HomeController < ApplicationController
|
||||
skip_authorize_resource
|
||||
respond_to :html
|
||||
|
||||
def index
|
||||
# we were previously generating a lot of instance variables like
|
||||
# @members_count and @interesting_crops in here, but now we call
|
||||
# the relevant class methods directly in the view, so that fragment
|
||||
# caching will be effective.
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.haml
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,26 +1,15 @@
|
||||
class MembersController < ApplicationController
|
||||
load_and_authorize_resource except: [:finish_signup, :unsubscribe, :view_follows, :view_followers, :show]
|
||||
skip_authorize_resource only: [:nearby, :unsubscribe, :finish_signup]
|
||||
|
||||
after_action :expire_cache_fragments, only: :create
|
||||
respond_to :html, :json, :rss
|
||||
after_action :expire_homepage, only: :create
|
||||
|
||||
def index
|
||||
@sort = params[:sort]
|
||||
@members = if @sort == 'recently_joined'
|
||||
Member.confirmed.recently_joined.paginate(page: params[:page])
|
||||
else
|
||||
Member.confirmed.paginate(page: params[:page])
|
||||
end
|
||||
|
||||
@members = members
|
||||
respond_to do |format|
|
||||
format.html # index.html.haml
|
||||
format.json {
|
||||
render json: @members.to_json(only: [
|
||||
:id, :login_name,
|
||||
:slug, :bio, :created_at,
|
||||
:location, :latitude, :longitude
|
||||
])
|
||||
}
|
||||
format.json { render json: @members.to_json(only: member_json_fields) }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -31,6 +20,7 @@ class MembersController < ApplicationController
|
||||
@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.
|
||||
@@ -38,18 +28,13 @@ class MembersController < ApplicationController
|
||||
|
||||
respond_to do |format|
|
||||
format.html # show.html.haml
|
||||
format.json {
|
||||
render json: @member.to_json(only: [
|
||||
:id, :login_name, :bio,
|
||||
:created_at, :slug, :location,
|
||||
:latitude, :longitude
|
||||
])
|
||||
}
|
||||
format.rss {
|
||||
format.json { render json: @member.to_json(only: member_json_fields) }
|
||||
format.rss do
|
||||
render(
|
||||
layout: false,
|
||||
locals: { member: @member }
|
||||
)}
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -66,7 +51,7 @@ class MembersController < ApplicationController
|
||||
EMAIL_TYPE_STRING = {
|
||||
send_notification_email: "direct message notifications",
|
||||
send_planting_reminder: "planting reminders"
|
||||
}
|
||||
}.freeze
|
||||
|
||||
def unsubscribe
|
||||
verifier = ActiveSupport::MessageVerifier.new(ENV['RAILS_SECRET_TOKEN'])
|
||||
@@ -98,11 +83,21 @@ class MembersController < ApplicationController
|
||||
|
||||
private
|
||||
|
||||
def expire_cache_fragments
|
||||
expire_fragment("homepage_stats")
|
||||
end
|
||||
|
||||
def member_params
|
||||
params.require(:member).permit(:login_name, :tos_agreement, :email, :newsletter)
|
||||
end
|
||||
|
||||
def member_json_fields
|
||||
[
|
||||
:id, :login_name,
|
||||
:slug, :bio, :created_at,
|
||||
:location, :latitude, :longitude
|
||||
]
|
||||
end
|
||||
|
||||
def members
|
||||
q = Member.confirmed
|
||||
q = q.recently_joined if @sort == 'recently_joined'
|
||||
q.paginate(page: params[:page])
|
||||
end
|
||||
end
|
||||
|
||||
13
app/controllers/photo_associations_controller.rb
Normal file
13
app/controllers/photo_associations_controller.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
class PhotoAssociationsController < ApplicationController
|
||||
before_action :authenticate_member!
|
||||
respond_to :json, :html
|
||||
|
||||
def destroy
|
||||
@photo = Photo.find_by!(id: params[:photo_id], owner: current_member)
|
||||
collection = Growstuff::Constants::PhotoModels.get_relation(@photo, params[:type])
|
||||
item_class = Growstuff::Constants::PhotoModels.get_item(params[:type])
|
||||
@item = item_class.find_by!(id: params[:id], owner_id: current_member.id)
|
||||
collection.delete(@item)
|
||||
respond_with(@photo)
|
||||
end
|
||||
end
|
||||
@@ -1,89 +1,43 @@
|
||||
class PhotosController < ApplicationController
|
||||
before_action :authenticate_member!, except: [:index, :show]
|
||||
after_action :expire_homepage, only: [:create, :delete]
|
||||
load_and_authorize_resource
|
||||
respond_to :html, :json
|
||||
responders :flash
|
||||
|
||||
# GET /photos
|
||||
# GET /photos.json
|
||||
def index
|
||||
@photos = Photo.paginate(page: params[:page])
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
format.json { render json: @photos }
|
||||
end
|
||||
respond_with(@photos)
|
||||
end
|
||||
|
||||
# GET /photos/new
|
||||
# GET /photos/new.json
|
||||
def new
|
||||
@photo = Photo.new
|
||||
@type = params[:type]
|
||||
@id = params[:id]
|
||||
|
||||
page = params[:page] || 1
|
||||
|
||||
@flickr_auth = current_member.auth('flickr')
|
||||
@current_set = params[:set]
|
||||
if @flickr_auth
|
||||
@sets = current_member.flickr_sets
|
||||
photos, total = current_member.flickr_photos(page, @current_set)
|
||||
|
||||
@photos = WillPaginate::Collection.create(page, 30, total) do |pager|
|
||||
pager.replace photos
|
||||
end
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.html # new.html.erb
|
||||
format.json { render json: @photo }
|
||||
end
|
||||
@photo = Photo.new
|
||||
retrieve_from_flickr
|
||||
respond_with @photo
|
||||
end
|
||||
|
||||
# GET /photos/1/edit
|
||||
def edit
|
||||
respond_with @photo
|
||||
end
|
||||
|
||||
# POST /photos
|
||||
# POST /photos.json
|
||||
def create
|
||||
find_or_create_photo_from_flickr_photo
|
||||
add_photo_to_collection
|
||||
|
||||
respond_to do |format|
|
||||
if @photo.present? && @photo.save
|
||||
format.html { redirect_to photo_path(@photo), notice: 'Photo was successfully added.' }
|
||||
format.json { render json: @photo, status: :created, location: @photo }
|
||||
else
|
||||
format.html { render action: "new" }
|
||||
format.json { render json: @photo.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
@photo.save if @photo.present?
|
||||
respond_with @photo
|
||||
end
|
||||
|
||||
# PUT /photos/1
|
||||
# PUT /photos/1.json
|
||||
def update
|
||||
respond_to do |format|
|
||||
if @photo.update(photo_params)
|
||||
format.html { redirect_to @photo, notice: 'Photo was successfully updated.' }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
format.html { render action: "edit" }
|
||||
format.json { render json: @photo.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
@photo.update(photo_params)
|
||||
respond_with @photo
|
||||
end
|
||||
|
||||
# DELETE /photos/1
|
||||
# DELETE /photos/1.json
|
||||
def destroy
|
||||
@photo.destroy
|
||||
flash[:alert] = "Photo successfully deleted."
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to photos_url }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
respond_with @photo
|
||||
end
|
||||
|
||||
private
|
||||
@@ -97,7 +51,7 @@ class PhotosController < ApplicationController
|
||||
end
|
||||
|
||||
def photo_params
|
||||
params.require(:photo).permit(:flickr_photo_id, :owner_id, :title, :license_name,
|
||||
params.require(:photo).permit(:flickr_photo_id, :title, :license_name,
|
||||
:license_url, :thumbnail_url, :fullsize_url, :link_url)
|
||||
end
|
||||
|
||||
@@ -122,4 +76,19 @@ class PhotosController < ApplicationController
|
||||
rescue => e
|
||||
flash[:alert] = e.message
|
||||
end
|
||||
|
||||
def retrieve_from_flickr
|
||||
@flickr_auth = current_member.auth('flickr')
|
||||
@current_set = params[:set]
|
||||
return unless @flickr_auth
|
||||
|
||||
page = params[:page] || 1
|
||||
|
||||
@sets = current_member.flickr_sets
|
||||
photos, total = current_member.flickr_photos(page, @current_set)
|
||||
|
||||
@photos = WillPaginate::Collection.create(page, 30, total) do |pager|
|
||||
pager.replace photos
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
class PlacesController < ApplicationController
|
||||
skip_authorize_resource
|
||||
respond_to :html, :json
|
||||
|
||||
def index
|
||||
respond_to do |format|
|
||||
@@ -30,17 +31,9 @@ class PlacesController < ApplicationController
|
||||
|
||||
def search
|
||||
if params[:new_place].empty?
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
redirect_to places_path, alert: 'Please enter a valid location'
|
||||
end
|
||||
end
|
||||
redirect_to places_path, alert: 'Please enter a valid location'
|
||||
else
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
redirect_to place_path(params[:new_place])
|
||||
end
|
||||
end
|
||||
redirect_to place_path(params[:new_place])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,70 +1,37 @@
|
||||
class PlantPartsController < ApplicationController
|
||||
load_and_authorize_resource
|
||||
respond_to :html, :json
|
||||
responders :flash
|
||||
|
||||
# GET /plant_parts
|
||||
# GET /plant_parts.json
|
||||
def index
|
||||
@plant_parts = PlantPart.all
|
||||
respond_with(@plant_parts)
|
||||
end
|
||||
|
||||
# GET /plant_parts/1
|
||||
# GET /plant_parts/1.json
|
||||
def show
|
||||
respond_with(@plant_part)
|
||||
end
|
||||
|
||||
# GET /plant_parts/new
|
||||
# GET /plant_parts/new.json
|
||||
def new
|
||||
@plant_part = PlantPart.new
|
||||
respond_with(@plant_part)
|
||||
end
|
||||
|
||||
# GET /plant_parts/1/edit
|
||||
def edit
|
||||
end
|
||||
def edit; end
|
||||
|
||||
# POST /plant_parts
|
||||
# POST /plant_parts.json
|
||||
def create
|
||||
@plant_part = PlantPart.new(plant_part_params)
|
||||
|
||||
respond_to do |format|
|
||||
if @plant_part.save
|
||||
format.html { redirect_to @plant_part, notice: 'Plant part was successfully created.' }
|
||||
format.json { render json: @plant_part, status: :created, location: @plant_part }
|
||||
else
|
||||
format.html { render action: "new" }
|
||||
format.json { render json: @plant_part.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
@plant_part = PlantPart.create(plant_part_params)
|
||||
respond_with(@plant_part)
|
||||
end
|
||||
|
||||
# PUT /plant_parts/1
|
||||
# PUT /plant_parts/1.json
|
||||
def update
|
||||
respond_to do |format|
|
||||
if @plant_part.update(plant_part_params)
|
||||
format.html { redirect_to @plant_part, notice: 'Plant part was successfully updated.' }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
format.html { render action: "edit" }
|
||||
format.json { render json: @plant_part.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
@plant_part.update(plant_part_params)
|
||||
respond_with(@plant_part)
|
||||
end
|
||||
|
||||
# DELETE /plant_parts/1
|
||||
# DELETE /plant_parts/1.json
|
||||
def destroy
|
||||
@plant_part.destroy
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to plant_parts_url }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
respond_with(@plant_part)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -1,126 +1,81 @@
|
||||
class PlantingsController < ApplicationController
|
||||
before_action :authenticate_member!, except: [:index, :show]
|
||||
after_action :expire_homepage, only: [:create, :update, :destroy]
|
||||
load_and_authorize_resource
|
||||
|
||||
# GET /plantings
|
||||
# GET /plantings.json
|
||||
respond_to :html, :json
|
||||
respond_to :csv, :rss, only: [:index]
|
||||
responders :flash
|
||||
|
||||
def index
|
||||
@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]) }
|
||||
format.json { render json: @plantings }
|
||||
format.rss { render layout: false } # index.rss.builder
|
||||
format.csv do
|
||||
specifics = (@owner ? "#{@owner.login_name}-" : @crop ? "#{@crop.name}-" : nil)
|
||||
@filename = "Growstuff-#{specifics}Plantings-#{Time.zone.now.to_s(:number)}.csv"
|
||||
render csv: @plantings
|
||||
end
|
||||
end
|
||||
specifics = if @owner
|
||||
"#{@owner.login_name}-"
|
||||
elsif @crop
|
||||
"#{@crop.name}-"
|
||||
end
|
||||
|
||||
@filename = "Growstuff-#{specifics}Plantings-#{Time.zone.now.to_s(:number)}.csv"
|
||||
|
||||
respond_with(@plantings)
|
||||
end
|
||||
|
||||
# GET /plantings/1
|
||||
# GET /plantings/1.json
|
||||
def show
|
||||
@planting = Planting.includes(:owner, :crop, :garden, :photos).friendly.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
format.html # show.html.erb
|
||||
format.json { render json: @planting }
|
||||
end
|
||||
@planting = Planting.includes(:owner, :crop, :garden, :photos)
|
||||
.friendly
|
||||
.find(params[:id])
|
||||
respond_with @planting
|
||||
end
|
||||
|
||||
# GET /plantings/new
|
||||
# GET /plantings/new.json
|
||||
def new
|
||||
@planting = Planting.new('planted_at' => Time.zone.today)
|
||||
@planting = Planting.new(planted_at: Time.zone.today)
|
||||
|
||||
# using find_by_id here because it returns nil, unlike find
|
||||
@crop = Crop.find_by(id: params[:crop_id]) || Crop.new
|
||||
@garden = Garden.find_by(id: params[:garden_id]) || Garden.new
|
||||
@crop = Crop.approved.find_by(id: params[:crop_id]) || Crop.new
|
||||
@garden = Garden.find_by(owner: current_member, id: params[:garden_id]) || Garden.new
|
||||
|
||||
respond_to do |format|
|
||||
format.html # new.html.erb
|
||||
format.json { render json: @planting }
|
||||
end
|
||||
respond_with @planting
|
||||
end
|
||||
|
||||
# GET /plantings/1/edit
|
||||
def edit
|
||||
# the following are needed to display the form but aren't used
|
||||
@crop = Crop.new
|
||||
@garden = Garden.new
|
||||
end
|
||||
|
||||
# POST /plantings
|
||||
# POST /plantings.json
|
||||
def create
|
||||
params[:planted_at] = parse_date(params[:planted_at])
|
||||
@planting = Planting.new(planting_params)
|
||||
@planting.owner = current_member
|
||||
|
||||
respond_to do |format|
|
||||
if @planting.save
|
||||
@planting.update_attribute(:days_before_maturity,
|
||||
update_days_before_maturity(@planting, planting_params[:crop_id]))
|
||||
format.html { redirect_to @planting, notice: 'Planting was successfully created.' }
|
||||
format.json { render json: @planting, status: :created, location: @planting }
|
||||
expire_fragment("homepage_stats")
|
||||
else
|
||||
format.html { render action: "new" }
|
||||
format.json { render json: @planting.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
@planting.calc_and_set_days_before_maturity
|
||||
@planting.save
|
||||
respond_with @planting
|
||||
end
|
||||
|
||||
# PUT /plantings/1
|
||||
# PUT /plantings/1.json
|
||||
def update
|
||||
params[:planted_at] = parse_date(params[:planted_at])
|
||||
|
||||
respond_to do |format|
|
||||
if @planting.update(planting_params)
|
||||
@planting.update_attribute(:days_before_maturity,
|
||||
update_days_before_maturity(@planting, planting_params[:crop_id]))
|
||||
format.html { redirect_to @planting, notice: 'Planting was successfully updated.' }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
format.html { render action: "edit" }
|
||||
format.json { render json: @planting.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
@planting.calc_and_set_days_before_maturity
|
||||
@planting.update(planting_params)
|
||||
respond_with @planting
|
||||
end
|
||||
|
||||
# DELETE /plantings/1
|
||||
# DELETE /plantings/1.json
|
||||
def destroy
|
||||
@garden = @planting.garden
|
||||
@planting.destroy
|
||||
expire_fragment("homepage_stats")
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to @garden }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
respond_with @planting, location: garden
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def planting_params
|
||||
params.require(:planting).permit(:crop_id, :description, :garden_id, :planted_at,
|
||||
:quantity, :sunniness, :planted_from, :owner_id, :finished,
|
||||
:finished_at)
|
||||
end
|
||||
|
||||
def update_days_before_maturity(planting, crop_id)
|
||||
if planting.finished_at.nil?
|
||||
planting.calculate_days_before_maturity(planting, crop_id)
|
||||
else
|
||||
(planting.finished_at - planting.planted_at).to_i
|
||||
end
|
||||
params[:planted_at] = parse_date(params[:planted_at]) if params[:planted_at]
|
||||
params.require(:planting).permit(
|
||||
:crop_id, :description, :garden_id, :planted_at,
|
||||
:quantity, :sunniness, :planted_from, :finished,
|
||||
:finished_at
|
||||
)
|
||||
end
|
||||
|
||||
def plantings
|
||||
@@ -132,6 +87,6 @@ class PlantingsController < ApplicationController
|
||||
Planting
|
||||
end
|
||||
p = p.current unless @show_all
|
||||
p.includes(:owner, :crop, :garden).order(:created_at).paginate(page: params[:page])
|
||||
p.joins(:owner, :crop, :garden).order(:created_at).paginate(page: params[:page])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -30,8 +30,7 @@ class PostsController < ApplicationController
|
||||
end
|
||||
|
||||
# GET /posts/1/edit
|
||||
def edit
|
||||
end
|
||||
def edit; end
|
||||
|
||||
# POST /posts
|
||||
# POST /posts.json
|
||||
|
||||
@@ -1,67 +1,40 @@
|
||||
class ProductsController < ApplicationController
|
||||
before_action :authenticate_member!
|
||||
load_and_authorize_resource
|
||||
respond_to :html
|
||||
responders :flash
|
||||
|
||||
# GET /products
|
||||
def index
|
||||
@products = Product.all
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
end
|
||||
respond_with @products
|
||||
end
|
||||
|
||||
# GET /products/1
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.html # show.html.erb
|
||||
end
|
||||
respond_with @product
|
||||
end
|
||||
|
||||
# GET /products/new
|
||||
def new
|
||||
@product = Product.new
|
||||
|
||||
respond_to do |format|
|
||||
format.html # new.html.erb
|
||||
end
|
||||
respond_with @product
|
||||
end
|
||||
|
||||
# GET /products/1/edit
|
||||
def edit
|
||||
respond_with @product
|
||||
end
|
||||
|
||||
# POST /products
|
||||
def create
|
||||
@product = Product.new(product_params)
|
||||
|
||||
respond_to do |format|
|
||||
if @product.save
|
||||
format.html { redirect_to @product, notice: 'Product was successfully created.' }
|
||||
else
|
||||
format.html { render action: "new" }
|
||||
end
|
||||
end
|
||||
@product = Product.create(product_params)
|
||||
respond_with @product
|
||||
end
|
||||
|
||||
# PUT /products/1
|
||||
def update
|
||||
respond_to do |format|
|
||||
if @product.update(product_params)
|
||||
format.html { redirect_to @product, notice: 'Product was successfully updated.' }
|
||||
else
|
||||
format.html { render action: "edit" }
|
||||
end
|
||||
end
|
||||
@product.update(product_params)
|
||||
respond_with @product
|
||||
end
|
||||
|
||||
# DELETE /products/1
|
||||
def destroy
|
||||
@product.destroy
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to products_url }
|
||||
end
|
||||
respond_with @product
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -35,6 +35,14 @@ class RegistrationsController < Devise::RegistrationsController
|
||||
render "edit"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @member.destroy_with_password(params.require(:member)[:current_password])
|
||||
redirect_to root_path
|
||||
else
|
||||
render "edit"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# check if we need the current password to update fields
|
||||
|
||||
@@ -1,67 +1,40 @@
|
||||
class RolesController < ApplicationController
|
||||
before_action :authenticate_member!
|
||||
load_and_authorize_resource
|
||||
respond_to :html
|
||||
responders :flash
|
||||
|
||||
# GET /roles
|
||||
def index
|
||||
@roles = Role.all
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
end
|
||||
respond_with @roles
|
||||
end
|
||||
|
||||
# GET /roles/1
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.html # show.html.erb
|
||||
end
|
||||
respond_with @role
|
||||
end
|
||||
|
||||
# GET /roles/new
|
||||
def new
|
||||
@role = Role.new
|
||||
|
||||
respond_to do |format|
|
||||
format.html # new.html.erb
|
||||
end
|
||||
respond_with @role
|
||||
end
|
||||
|
||||
# GET /roles/1/edit
|
||||
def edit
|
||||
respond_with @role
|
||||
end
|
||||
|
||||
# POST /roles
|
||||
def create
|
||||
@role = Role.new(role_params)
|
||||
|
||||
respond_to do |format|
|
||||
if @role.save
|
||||
format.html { redirect_to @role, notice: 'Role was successfully created.' }
|
||||
else
|
||||
format.html { render action: "new" }
|
||||
end
|
||||
end
|
||||
@role = Role.create(role_params)
|
||||
respond_with @role
|
||||
end
|
||||
|
||||
# PUT /roles/1
|
||||
def update
|
||||
respond_to do |format|
|
||||
if @role.update(role_params)
|
||||
format.html { redirect_to @role, notice: 'Role was successfully updated.' }
|
||||
else
|
||||
format.html { render action: "edit" }
|
||||
end
|
||||
end
|
||||
@role.update(role_params)
|
||||
respond_with @role
|
||||
end
|
||||
|
||||
# DELETE /roles/1
|
||||
def destroy
|
||||
@role.destroy
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to roles_url }
|
||||
end
|
||||
respond_with @role
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -2,6 +2,7 @@ class ScientificNamesController < ApplicationController
|
||||
before_action :authenticate_member!, except: [:index, :show]
|
||||
load_and_authorize_resource
|
||||
respond_to :html, :json
|
||||
responders :flash
|
||||
|
||||
# GET /scientific_names
|
||||
# GET /scientific_names.json
|
||||
@@ -25,8 +26,7 @@ class ScientificNamesController < ApplicationController
|
||||
end
|
||||
|
||||
# GET /scientific_names/1/edit
|
||||
def edit
|
||||
end
|
||||
def edit; end
|
||||
|
||||
# POST /scientific_names
|
||||
# POST /scientific_names.json
|
||||
@@ -34,14 +34,14 @@ class ScientificNamesController < ApplicationController
|
||||
@scientific_name = ScientificName.new(scientific_name_params)
|
||||
@scientific_name.creator = current_member
|
||||
|
||||
flash[:notice] = 'Scientific name was successfully created.' if @scientific_name.save
|
||||
@scientific_name.save
|
||||
respond_with(@scientific_name.crop)
|
||||
end
|
||||
|
||||
# PUT /scientific_names/1
|
||||
# PUT /scientific_names/1.json
|
||||
def update
|
||||
flash[:notice] = 'Scientific name was successfully updated.' if @scientific_name.update(scientific_name_params)
|
||||
@scientific_name.update(scientific_name_params)
|
||||
respond_with(@scientific_name.crop)
|
||||
end
|
||||
|
||||
|
||||
@@ -33,8 +33,7 @@ class SeedsController < ApplicationController
|
||||
end
|
||||
|
||||
# GET /seeds/1/edit
|
||||
def edit
|
||||
end
|
||||
def edit; end
|
||||
|
||||
# POST /seeds
|
||||
# POST /seeds.json
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
class ShopController < ApplicationController
|
||||
respond_to :html
|
||||
def index
|
||||
@products = Product.all
|
||||
@order_item = OrderItem.new
|
||||
@@ -11,15 +12,8 @@ class ShopController < ApplicationController
|
||||
|
||||
@order = nil
|
||||
@most_recent_item = nil
|
||||
if current_member
|
||||
@order = current_member.current_order
|
||||
if @order
|
||||
@most_recent_item = @order.order_items.first
|
||||
end
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.haml
|
||||
end
|
||||
return unless current_member
|
||||
@order = current_member.current_order
|
||||
@most_recent_item = @order.order_items.first if @order
|
||||
end
|
||||
end
|
||||
|
||||
@@ -55,6 +55,7 @@ module ApplicationHelper
|
||||
# Falls back to Gravatar
|
||||
#
|
||||
def avatar_uri(member, size = 150)
|
||||
return unless member
|
||||
if member.preferred_avatar_uri.present?
|
||||
# Some avatars support different sizes
|
||||
# http://graph.facebook.com/12345678/picture?width=150&height=150
|
||||
@@ -93,11 +94,13 @@ module ApplicationHelper
|
||||
end
|
||||
end
|
||||
|
||||
def title(type, owner, crop)
|
||||
def title(type, owner, crop, planting)
|
||||
if owner
|
||||
t(".title.owner_#{type}", owner: owner.login_name)
|
||||
elsif crop
|
||||
t(".title.crop_#{type}", crop: crop.name)
|
||||
elsif planting
|
||||
t(".title.planting_#{type}", planting: planting.to_s)
|
||||
else
|
||||
t(".title.default")
|
||||
end
|
||||
|
||||
@@ -5,7 +5,7 @@ module CropsHelper
|
||||
seeds = member.seeds.select { |seed| seed.crop.name == crop.name }
|
||||
|
||||
seeds.each do |seed|
|
||||
total_quantity = total_quantity + seed.quantity if seed.quantity
|
||||
total_quantity += seed.quantity if seed.quantity
|
||||
end
|
||||
|
||||
if !seeds.any?
|
||||
|
||||
@@ -21,13 +21,14 @@ module GardensHelper
|
||||
if plantings.blank?
|
||||
"None"
|
||||
else
|
||||
output = ""
|
||||
plantings.first(2).each do |planting|
|
||||
output = '<ul class="plantings">'
|
||||
plantings.each do |planting|
|
||||
output += "<li>"
|
||||
output += planting.quantity.nil? ? "0 " : "#{planting.quantity} "
|
||||
output += link_to planting.crop.name, planting.crop
|
||||
output += ", planted on #{planting.planted_at}</li>"
|
||||
end
|
||||
output += '</ul>'
|
||||
output.html_safe
|
||||
end
|
||||
end
|
||||
|
||||
@@ -89,8 +89,8 @@ class Ability
|
||||
can :destroy, Garden, owner_id: member.id
|
||||
|
||||
can :create, Planting
|
||||
can :update, Planting, garden: { owner_id: member.id }
|
||||
can :destroy, Planting, garden: { owner_id: member.id }
|
||||
can :update, Planting, garden: { owner_id: member.id }, crop: { approval_status: 'approved' }
|
||||
can :destroy, Planting, garden: { owner_id: member.id }, crop: { approval_status: 'approved' }
|
||||
|
||||
can :create, Harvest
|
||||
can :update, Harvest, owner_id: member.id
|
||||
|
||||
@@ -2,4 +2,6 @@ class AlternateName < ActiveRecord::Base
|
||||
after_commit { |an| an.crop.__elasticsearch__.index_document if an.crop && ENV['GROWSTUFF_ELASTICSEARCH'] == "true" }
|
||||
belongs_to :crop
|
||||
belongs_to :creator, class_name: 'Member'
|
||||
validates :name, presence: true
|
||||
validates :crop, presence: true
|
||||
end
|
||||
|
||||
@@ -6,6 +6,7 @@ module PhotoCapable
|
||||
has_and_belongs_to_many :photos # rubocop:disable Rails/HasAndBelongsToMany
|
||||
|
||||
before_destroy :remove_from_list
|
||||
scope :has_photos, -> { includes(:photos).where.not(photos: { id: nil }) }
|
||||
end
|
||||
|
||||
def remove_from_list
|
||||
|
||||
@@ -12,7 +12,7 @@ class Crop < ActiveRecord::Base
|
||||
has_many :photos, through: :plantings
|
||||
has_many :seeds
|
||||
has_many :harvests
|
||||
has_many :plant_parts, -> { uniq }, through: :harvests
|
||||
has_many :plant_parts, -> { uniq.reorder("plant_parts.name") }, through: :harvests
|
||||
belongs_to :creator, class_name: 'Member'
|
||||
belongs_to :requester, class_name: 'Member'
|
||||
|
||||
@@ -21,24 +21,27 @@ class Crop < ActiveRecord::Base
|
||||
has_and_belongs_to_many :posts # rubocop:disable Rails/HasAndBelongsToMany
|
||||
before_destroy { |crop| crop.posts.clear }
|
||||
|
||||
default_scope { order("lower(name) asc") }
|
||||
default_scope { order("lower(crops.name) asc") }
|
||||
scope :recent, lambda {
|
||||
where(approval_status: "approved").reorder("created_at desc")
|
||||
approved.reorder("created_at desc")
|
||||
}
|
||||
scope :toplevel, lambda {
|
||||
where(approval_status: "approved", parent_id: nil)
|
||||
approved.where(parent_id: nil)
|
||||
}
|
||||
scope :popular, lambda {
|
||||
where(approval_status: "approved").reorder("plantings_count desc, lower(name) asc")
|
||||
approved.reorder("plantings_count desc, lower(name) asc")
|
||||
}
|
||||
scope :randomized, lambda {
|
||||
# ok on sqlite and psql, but not on mysql
|
||||
where(approval_status: "approved").reorder('random()')
|
||||
approved.reorder('random()')
|
||||
}
|
||||
scope :pending_approval, -> { where(approval_status: "pending") }
|
||||
scope :approved, -> { where(approval_status: "approved") }
|
||||
scope :rejected, -> { where(approval_status: "rejected") }
|
||||
|
||||
scope :interesting, -> { approved.has_photos }
|
||||
scope :has_photos, -> { includes(:photos).where.not(photos: { id: nil }) }
|
||||
|
||||
## Wikipedia urls are only necessary when approving a crop
|
||||
validates :en_wikipedia_url,
|
||||
format: {
|
||||
@@ -198,81 +201,6 @@ class Crop < ActiveRecord::Base
|
||||
["already in database", "not edible", "not enough information", "other"]
|
||||
end
|
||||
|
||||
# Crop.interesting
|
||||
# returns a list of interesting crops, for use on the homepage etc
|
||||
def self.interesting
|
||||
howmany = 12 # max number to find
|
||||
interesting_crops = []
|
||||
Crop.includes(:photos).randomized.each do |c|
|
||||
break if interesting_crops.size == howmany
|
||||
next unless c.interesting?
|
||||
interesting_crops.push(c)
|
||||
end
|
||||
interesting_crops
|
||||
end
|
||||
|
||||
# Crop.create_from_csv(row)
|
||||
# used by db/seeds.rb and rake growstuff:import_crops
|
||||
# CSV fields:
|
||||
# - name (required)
|
||||
# - en_wikipedia_url (required)
|
||||
# - parent (name, optional)
|
||||
# - scientific name (optional, can be picked up from parent if it has one)
|
||||
|
||||
def self.create_from_csv(row)
|
||||
name, en_wikipedia_url, parent, scientific_names, alternate_names = row
|
||||
|
||||
cropbot = Member.find_by(login_name: 'cropbot')
|
||||
raise "cropbot account not found: run rake db:seed" unless cropbot
|
||||
|
||||
crop = Crop.find_or_create_by(name: name)
|
||||
crop.update_attributes(
|
||||
en_wikipedia_url: en_wikipedia_url,
|
||||
creator_id: cropbot.id
|
||||
)
|
||||
|
||||
if parent
|
||||
parent = Crop.find_by(name: parent)
|
||||
if parent
|
||||
crop.update_attributes(parent_id: parent.id)
|
||||
else
|
||||
logger.warn("Warning: parent crop #{parent} not found")
|
||||
end
|
||||
end
|
||||
|
||||
crop.add_scientific_names_from_csv(scientific_names)
|
||||
crop.add_alternate_names_from_csv(alternate_names)
|
||||
end
|
||||
|
||||
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(/,\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 if names_to_add.empty?
|
||||
raise "cropbot account not found: run rake db:seed" unless cropbot
|
||||
|
||||
add_names_to_list(names_to_add, 'scientific')
|
||||
end
|
||||
|
||||
def add_alternate_names_from_csv(alternate_names)
|
||||
# i.e. we actually passed something in, which isn't a given
|
||||
return if alternate_names.blank?
|
||||
|
||||
cropbot = Member.find_by!(login_name: 'cropbot')
|
||||
names_to_add = alternate_names.split(/,\s*/)
|
||||
add_names_to_list(names_to_add, 'alternate')
|
||||
rescue
|
||||
raise "cropbot account not found: run rake db:seed" unless cropbot
|
||||
end
|
||||
|
||||
def rejection_explanation
|
||||
return rejection_notes if reason_for_rejection == "other"
|
||||
reason_for_rejection
|
||||
@@ -320,34 +248,11 @@ class Crop < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def self.case_insensitive_name(name)
|
||||
where(["lower(name) = :value", { value: name.downcase }])
|
||||
where(["lower(crops.name) = :value", { value: name.downcase }])
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def add_names_to_list(names_to_add, list_name)
|
||||
names_to_add.each do |n|
|
||||
if name_already_exists(list_name, n)
|
||||
logger.warn("Warning: skipping duplicate #{list_name} name #{n} for #{self}")
|
||||
else
|
||||
create_crop_in_list(list_name, n)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def create_crop_in_list(list_name, name)
|
||||
cropbot = Member.find_by(login_name: 'cropbot')
|
||||
create_hash = {
|
||||
creator_id: cropbot.id.to_s,
|
||||
name: name
|
||||
}
|
||||
send("#{list_name}_names").create(create_hash)
|
||||
end
|
||||
|
||||
def name_already_exists(list_name, name)
|
||||
send("#{list_name}_names").exists?(name: name)
|
||||
end
|
||||
|
||||
def count_uses_of_property(col_name)
|
||||
plantings.unscoped
|
||||
.where(crop_id: id)
|
||||
@@ -357,7 +262,6 @@ class Crop < ActiveRecord::Base
|
||||
end
|
||||
|
||||
# Custom validations
|
||||
|
||||
def approval_status_cannot_be_changed_again
|
||||
previous = previous_changes.include?(:approval_status) ? previous_changes.approval_status : {}
|
||||
return unless previous.include?(:rejected) || previous.include?(:approved)
|
||||
|
||||
70
app/models/csv_importer.rb
Normal file
70
app/models/csv_importer.rb
Normal file
@@ -0,0 +1,70 @@
|
||||
class CsvImporter
|
||||
# used by db/seeds.rb and rake growstuff:import_crops
|
||||
# CSV fields:
|
||||
# - name (required)
|
||||
# - en_wikipedia_url (required)
|
||||
# - parent (name, optional)
|
||||
# - scientific name (optional, can be picked up from parent if it has one)
|
||||
def import_crop(row)
|
||||
name, en_wikipedia_url, parent_name, scientific_names, alternate_names = row
|
||||
|
||||
@crop = Crop.find_or_create_by(name: name)
|
||||
@crop.update_attributes(
|
||||
en_wikipedia_url: en_wikipedia_url,
|
||||
creator_id: cropbot.id
|
||||
)
|
||||
|
||||
add_parent(parent_name) if parent_name
|
||||
add_scientific_names(scientific_names)
|
||||
add_alternate_names(alternate_names)
|
||||
@crop.save!
|
||||
@crop
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def add_parent(parent_name)
|
||||
parent = Crop.find_by(name: parent_name)
|
||||
if parent
|
||||
@crop.update_attributes(parent_id: parent.id)
|
||||
else
|
||||
@crop.logger.warn("Warning: parent crop #{parent_name} not found")
|
||||
end
|
||||
end
|
||||
|
||||
def add_scientific_names(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(/,\s*/)
|
||||
elsif @crop.parent && !@crop.parent.scientific_names.empty? # pick up from parent
|
||||
names_to_add = @crop.parent.scientific_names.map(&:name)
|
||||
else
|
||||
@crop.logger.warn("Warning: no scientific name (not even on parent crop) for #{self}")
|
||||
end
|
||||
|
||||
return if names_to_add.empty?
|
||||
|
||||
names_to_add.each do |name|
|
||||
sciname = ScientificName.find_by(name: name, crop: @crop)
|
||||
sciname = ScientificName.create!(name: name, crop: @crop, creator: cropbot) unless sciname
|
||||
@crop.scientific_names << sciname
|
||||
end
|
||||
end
|
||||
|
||||
def add_alternate_names(alternate_names)
|
||||
# i.e. we actually passed something in, which isn't a given
|
||||
return if alternate_names.blank?
|
||||
alternate_names.split(/,\s*/).each do |name|
|
||||
altname = AlternateName.find_by(name: name, crop: @crop)
|
||||
altname = AlternateName.create! name: name, crop: @crop, creator: cropbot unless altname
|
||||
@crop.alternate_names << altname
|
||||
end
|
||||
end
|
||||
|
||||
def cropbot
|
||||
@cropbot = Member.find_by!(login_name: 'cropbot') unless @cropbot
|
||||
@cropbot
|
||||
rescue
|
||||
raise "cropbot account not found: run rake db:seed"
|
||||
end
|
||||
end
|
||||
@@ -4,8 +4,8 @@ class Garden < ActiveRecord::Base
|
||||
include PhotoCapable
|
||||
friendly_id :garden_slug, use: [:slugged, :finders]
|
||||
|
||||
belongs_to :owner, class_name: 'Member', foreign_key: 'owner_id'
|
||||
has_many :plantings, -> { order(created_at: :desc) }, dependent: :destroy
|
||||
belongs_to :owner, class_name: 'Member', foreign_key: 'owner_id', counter_cache: true
|
||||
has_many :plantings, dependent: :destroy
|
||||
has_many :crops, through: :plantings
|
||||
|
||||
# set up geocoding
|
||||
@@ -14,7 +14,7 @@ class Garden < ActiveRecord::Base
|
||||
after_validation :empty_unwanted_geocodes
|
||||
after_save :mark_inactive_garden_plantings_as_finished
|
||||
|
||||
default_scope { order("lower(name) asc") }
|
||||
default_scope { joins(:owner).order("lower(name) asc") }
|
||||
scope :active, -> { where(active: true) }
|
||||
scope :inactive, -> { where(active: false) }
|
||||
|
||||
@@ -62,7 +62,7 @@ class Garden < ActiveRecord::Base
|
||||
unique_plantings = []
|
||||
seen_crops = []
|
||||
|
||||
plantings.each do |p|
|
||||
plantings.includes(:garden, :crop, :owner, :harvests).each do |p|
|
||||
unless seen_crops.include?(p.crop)
|
||||
unique_plantings.push(p)
|
||||
seen_crops.push(p.crop)
|
||||
|
||||
@@ -5,12 +5,11 @@ class Harvest < ActiveRecord::Base
|
||||
friendly_id :harvest_slug, use: [:slugged, :finders]
|
||||
|
||||
belongs_to :crop
|
||||
belongs_to :owner, class_name: 'Member'
|
||||
belongs_to :owner, class_name: 'Member', counter_cache: true
|
||||
belongs_to :plant_part
|
||||
belongs_to :planting
|
||||
|
||||
default_scope { order('created_at DESC') }
|
||||
|
||||
default_scope { joins(:owner).order(created_at: :desc) }
|
||||
validates :crop, approved: true
|
||||
|
||||
validates :crop, presence: { message: "must be present and exist in our database" }
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
class Member < ActiveRecord::Base
|
||||
acts_as_paranoid # implements soft deletion
|
||||
before_destroy :newsletter_unsubscribe
|
||||
include Geocodable
|
||||
extend FriendlyId
|
||||
|
||||
@@ -7,7 +9,6 @@ class Member < ActiveRecord::Base
|
||||
has_many :posts, foreign_key: 'author_id'
|
||||
has_many :comments, foreign_key: 'author_id'
|
||||
has_many :forums, foreign_key: 'owner_id'
|
||||
|
||||
has_many :gardens, foreign_key: 'owner_id'
|
||||
has_many :plantings, foreign_key: 'owner_id'
|
||||
|
||||
@@ -27,14 +28,19 @@ class Member < ActiveRecord::Base
|
||||
|
||||
has_many :photos
|
||||
|
||||
has_many :requested_crops, class_name: Crop, foreign_key: 'requester_id'
|
||||
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") }
|
||||
scope :recently_signed_in, -> { reorder('updated_at DESC') }
|
||||
scope :recently_joined, -> { reorder("confirmed_at desc") }
|
||||
|
||||
scope :confirmed, -> { where.not(confirmed_at: nil) }
|
||||
scope :located, -> { where.not(location: '').where.not(latitude: nil).where.not(longitude: nil) }
|
||||
scope :recently_signed_in, -> { reorder(updated_at: :desc) }
|
||||
scope :recently_joined, -> { reorder(confirmed_at: :desc) }
|
||||
scope :wants_newsletter, -> { where(newsletter: true) }
|
||||
scope :interesting, -> { confirmed.located.recently_signed_in.has_plantings }
|
||||
|
||||
scope :has_plantings, -> { joins(:plantings).group("members.id") }
|
||||
|
||||
has_many :follows, class_name: "Follow", foreign_key: "follower_id"
|
||||
has_many :followed, through: :follows
|
||||
@@ -183,14 +189,6 @@ class Member < ActiveRecord::Base
|
||||
sets
|
||||
end
|
||||
|
||||
def interesting?
|
||||
# we assume we're being passed something from
|
||||
# Member.confirmed.located as those are required for
|
||||
# interestingness, as well.
|
||||
return true if plantings.present?
|
||||
false
|
||||
end
|
||||
|
||||
def self.login_name_or_email(login)
|
||||
where(["lower(login_name) = :value OR lower(email) = :value", { value: login.downcase }])
|
||||
end
|
||||
@@ -199,16 +197,6 @@ class Member < ActiveRecord::Base
|
||||
where(["lower(login_name) = :value", { value: login.downcase }])
|
||||
end
|
||||
|
||||
def self.interesting
|
||||
howmany = 12 # max number to find
|
||||
interesting_members = []
|
||||
Member.confirmed.located.recently_signed_in.each do |m|
|
||||
break if interesting_members.size == howmany
|
||||
interesting_members.push(m) if m.interesting?
|
||||
end
|
||||
interesting_members
|
||||
end
|
||||
|
||||
def self.nearest_to(place)
|
||||
nearby_members = []
|
||||
if place
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class Order < ActiveRecord::Base
|
||||
belongs_to :member
|
||||
belongs_to :member, with_deleted: true
|
||||
|
||||
has_many :order_items, dependent: :destroy
|
||||
|
||||
@@ -64,7 +64,7 @@ class Order < ActiveRecord::Base
|
||||
if args[:for]
|
||||
case args[:by]
|
||||
when "member"
|
||||
member = Member.find_by(login_name: args[:for])
|
||||
member = Member.with_deleted.find_by(login_name: args[:for])
|
||||
return member.orders if member
|
||||
when "order_id"
|
||||
order = Order.find_by(id: args[:for])
|
||||
|
||||
@@ -8,7 +8,11 @@ class Photo < ActiveRecord::Base
|
||||
|
||||
before_destroy { all_associations.clear }
|
||||
|
||||
default_scope { order("created_at desc") }
|
||||
default_scope { joins(:owner).order(created_at: :desc) }
|
||||
|
||||
def associations?
|
||||
plantings.any? || harvests.any? || gardens.any? || seeds.any?
|
||||
end
|
||||
|
||||
def all_associations
|
||||
associations = []
|
||||
@@ -30,7 +34,7 @@ class Photo < ActiveRecord::Base
|
||||
licenses = flickr.photos.licenses.getInfo
|
||||
license = licenses.find { |l| l.id == info.license }
|
||||
{
|
||||
title: info.title || "Untitled",
|
||||
title: calculate_title(info),
|
||||
license_name: license.name,
|
||||
license_url: license.url,
|
||||
thumbnail_url: FlickRaw.url_q(info),
|
||||
@@ -39,6 +43,16 @@ class Photo < ActiveRecord::Base
|
||||
}
|
||||
end
|
||||
|
||||
def calculate_title(info)
|
||||
if id && title # already has a title saved
|
||||
title
|
||||
elsif info.title # use title from flickr
|
||||
info.title
|
||||
else
|
||||
'untitled'
|
||||
end
|
||||
end
|
||||
|
||||
def set_flickr_metadata
|
||||
update_attributes(flickr_metadata)
|
||||
end
|
||||
|
||||
@@ -6,12 +6,19 @@ 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
|
||||
has_many :harvests, dependent: :destroy
|
||||
|
||||
default_scope { order("created_at desc") }
|
||||
default_scope { joins(:owner).order(created_at: :desc) }
|
||||
scope :finished, -> { where(finished: true) }
|
||||
scope :current, -> { where(finished: false) }
|
||||
|
||||
scope :interesting, -> { has_photos.one_per_owner }
|
||||
scope :one_per_owner, lambda {
|
||||
joins("JOIN members m ON (m.id=plantings.owner_id)
|
||||
LEFT OUTER JOIN plantings p2
|
||||
ON (m.id=p2.owner_id AND plantings.id < p2.id)").where("p2 IS NULL")
|
||||
}
|
||||
|
||||
delegate :name,
|
||||
:en_wikipedia_url,
|
||||
:default_scientific_name,
|
||||
@@ -19,11 +26,9 @@ class Planting < ActiveRecord::Base
|
||||
to: :crop,
|
||||
prefix: true
|
||||
|
||||
default_scope { order("created_at desc") }
|
||||
|
||||
validates :crop, approved: true
|
||||
|
||||
validates :crop, presence: { message: "must be present and exist in our database" }
|
||||
validates :garden, presence: true
|
||||
validates :crop, presence: true
|
||||
validates :crop, approved: { message: "must be present and exist in our database" }
|
||||
|
||||
validates :quantity,
|
||||
numericality: {
|
||||
@@ -58,6 +63,11 @@ class Planting < ActiveRecord::Base
|
||||
|
||||
validate :finished_must_be_after_planted
|
||||
|
||||
delegate :days_until_finished, to: :predict
|
||||
delegate :days_until_mature, to: :predict
|
||||
delegate :percentage_grown, to: :predict
|
||||
delegate :start_to_finish_diff, to: :predict
|
||||
|
||||
# check that any finished_at date occurs after planted_at
|
||||
def finished_must_be_after_planted
|
||||
return unless planted_at && finished_at # only check if we have both
|
||||
@@ -86,73 +96,17 @@ class Planting < ActiveRecord::Base
|
||||
photos.first
|
||||
end
|
||||
|
||||
def interesting?
|
||||
photos.present?
|
||||
def planted?
|
||||
planted_at.present? && planted_at <= Date.current
|
||||
end
|
||||
|
||||
def calculate_days_before_maturity(planting, crop)
|
||||
p_crop = Planting.where(crop_id: crop).where.not(id: planting)
|
||||
differences = p_crop.collect do |p|
|
||||
if p.finished && !p.finished_at.nil?
|
||||
(p.finished_at - p.planted_at).to_i
|
||||
end
|
||||
end
|
||||
|
||||
if differences.compact.empty?
|
||||
nil
|
||||
else
|
||||
differences.compact.sum / differences.compact.size
|
||||
end
|
||||
def calc_and_set_days_before_maturity
|
||||
self.days_before_maturity = predict.predict_days_before_maturity
|
||||
end
|
||||
|
||||
def planted?(current_date = Date.current)
|
||||
planted_at.present? && current_date.to_date >= planted_at
|
||||
end
|
||||
private
|
||||
|
||||
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)
|
||||
|
||||
days = (current_date.to_date - planted_at.to_date).to_i
|
||||
|
||||
return 0 if current_date < planted_at
|
||||
return 100 if days > days_before_maturity
|
||||
percent = (days / days_before_maturity * 100).to_i
|
||||
|
||||
if percent >= 100
|
||||
percent = 100
|
||||
end
|
||||
|
||||
percent
|
||||
end
|
||||
|
||||
# return a list of interesting plantings, for the homepage etc.
|
||||
# we can't do this via a scope (as far as we know) so sadly we have to
|
||||
# do it this way.
|
||||
def Planting.interesting(howmany = 12, require_photo = true)
|
||||
interesting_plantings = []
|
||||
seen_owners = Hash.new(false) # keep track of which owners we've seen already
|
||||
|
||||
Planting.includes(:photos).each do |p|
|
||||
break if interesting_plantings.size == howmany # got enough yet?
|
||||
if require_photo
|
||||
next unless p.photos.present? # skip those without photos, if required
|
||||
end
|
||||
next if seen_owners[p.owner] # skip if we already have one from this owner
|
||||
seen_owners[p.owner] = true # we've seen this owner
|
||||
interesting_plantings.push(p)
|
||||
end
|
||||
|
||||
interesting_plantings
|
||||
def predict
|
||||
PlantingPredictions.new(self)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -36,12 +36,10 @@ class Post < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
default_scope { order("created_at desc") }
|
||||
default_scope { joins(:author).order(created_at: :desc) }
|
||||
|
||||
validates :subject,
|
||||
format: {
|
||||
with: /\S/
|
||||
},
|
||||
presence: true,
|
||||
length: { maximum: 255 }
|
||||
|
||||
def author_date_subject
|
||||
|
||||
@@ -8,6 +8,7 @@ class Product < ActiveRecord::Base
|
||||
greater_than_or_equal_to: 0
|
||||
},
|
||||
allow_nil: true
|
||||
validates :min_price, presence: true
|
||||
|
||||
def to_s
|
||||
name
|
||||
|
||||
@@ -2,4 +2,6 @@ class ScientificName < ActiveRecord::Base
|
||||
after_commit { |sn| sn.crop.__elasticsearch__.index_document if sn.crop && ENV['GROWSTUFF_ELASTICSEARCH'] == "true" }
|
||||
belongs_to :crop
|
||||
belongs_to :creator, class_name: 'Member'
|
||||
validates :name, presence: true
|
||||
validates :crop, presence: true
|
||||
end
|
||||
|
||||
@@ -4,11 +4,13 @@ class Seed < ActiveRecord::Base
|
||||
friendly_id :seed_slug, use: [:slugged, :finders]
|
||||
|
||||
belongs_to :crop
|
||||
belongs_to :owner, class_name: 'Member', foreign_key: 'owner_id'
|
||||
belongs_to :owner, class_name: 'Member', foreign_key: 'owner_id', counter_cache: true
|
||||
|
||||
default_scope { order("created_at desc") }
|
||||
default_scope { joins(:owner).order(created_at: :desc) }
|
||||
|
||||
validates :crop, approved: true
|
||||
delegate :name, to: :crop
|
||||
delegate :default_photo, to: :crop
|
||||
|
||||
validates :crop, presence: { message: "must be present and exist in our database" }
|
||||
validates :quantity,
|
||||
@@ -30,8 +32,9 @@ class Seed < ActiveRecord::Base
|
||||
},
|
||||
allow_nil: true
|
||||
|
||||
scope :tradable, -> { where("tradable_to != 'nowhere'") }
|
||||
|
||||
scope :tradable, -> { where.not(tradable_to: 'nowhere') }
|
||||
scope :interesting, -> { tradable.has_location }
|
||||
scope :has_location, -> { joins(:owner).where.not("members.location": nil) }
|
||||
TRADABLE_TO_VALUES = %w(nowhere locally nationally internationally).freeze
|
||||
validates :tradable_to, inclusion: { in: TRADABLE_TO_VALUES,
|
||||
message: "You may only trade seed nowhere, "\
|
||||
@@ -77,27 +80,6 @@ class Seed < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
def interesting?
|
||||
# assuming we're passed something that's already known to be tradable
|
||||
# eg. from Seed.tradable scope
|
||||
return false if owner.location.blank? # don't want unspecified locations
|
||||
true
|
||||
end
|
||||
|
||||
# Seed.interesting
|
||||
# returns a list of interesting seeds, for use on the homepage etc
|
||||
def self.interesting
|
||||
howmany = 12 # max number to find
|
||||
interesting_seeds = []
|
||||
|
||||
Seed.tradable.each do |s|
|
||||
break if interesting_seeds.size == howmany
|
||||
interesting_seeds.push(s) if s.interesting?
|
||||
end
|
||||
|
||||
interesting_seeds
|
||||
end
|
||||
|
||||
def seed_slug
|
||||
"#{owner.login_name}-#{crop}".downcase.tr(' ', '-')
|
||||
end
|
||||
|
||||
58
app/services/planting_predictions.rb
Normal file
58
app/services/planting_predictions.rb
Normal file
@@ -0,0 +1,58 @@
|
||||
class PlantingPredictions
|
||||
def initialize(planting)
|
||||
@planting = planting
|
||||
end
|
||||
|
||||
def days_until_finished
|
||||
return 0 if @planting.finished?
|
||||
days = (@planting.finished_at - Date.current).to_i
|
||||
days.positive? ? days : 0
|
||||
end
|
||||
|
||||
def days_until_mature
|
||||
days = ((@planting.planted_at + @planting.days_before_maturity) - Date.current).to_i
|
||||
days.positive? ? days : 0
|
||||
end
|
||||
|
||||
def percentage_grown
|
||||
return nil unless @planting.days_before_maturity && @planting.planted?
|
||||
|
||||
days = (Date.current - @planting.planted_at.to_date).to_i
|
||||
|
||||
return 0 if Date.current < @planting.planted_at
|
||||
return 100 if days > @planting.days_before_maturity
|
||||
percent = (days / @planting.days_before_maturity * 100).to_i
|
||||
|
||||
percent = 100 if percent >= 100
|
||||
|
||||
percent
|
||||
end
|
||||
|
||||
def start_to_finish_diff
|
||||
(@planting.finished_at - @planting.planted_at).to_i if @planting.finished_at && @planting.planted_at
|
||||
end
|
||||
|
||||
def predict_days_before_maturity
|
||||
# calculate the number of days, from planted_at, until maturity
|
||||
if @planting.planted_at && @planting.finished_at
|
||||
start_to_finish_diff
|
||||
elsif @planting.crop_id
|
||||
plantings = other_finished_plantings_same_crop
|
||||
PlantingPredictions.mean_days_until_maturity(plantings)
|
||||
end
|
||||
end
|
||||
|
||||
def self.mean_days_until_maturity(plantings)
|
||||
## Given a set of finished plantings, calculate the average/mean time from start to finish
|
||||
differences = plantings.collect(&:start_to_finish_diff)
|
||||
differences.compact.sum / differences.compact.size unless differences.compact.empty?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def other_finished_plantings_same_crop
|
||||
Planting.where(crop_id: @planting.crop_id)
|
||||
.where.not(id: @planting.id)
|
||||
.where.not(finished_at: nil)
|
||||
end
|
||||
end
|
||||
@@ -5,6 +5,7 @@
|
||||
%ul#admin_links
|
||||
%li= link_to "Account types", account_types_path
|
||||
%li= link_to "Alternate names", alternate_names_path
|
||||
%li= link_to "Scientific names", scientific_names_path
|
||||
%li= link_to "Products", products_path
|
||||
%li= link_to "Roles", roles_path
|
||||
%li= link_to "Forums", forums_path
|
||||
|
||||
@@ -18,7 +18,9 @@
|
||||
|
||||
- @orders.each do |order|
|
||||
%tr
|
||||
%td= link_to order.member.login_name, order.member
|
||||
%td
|
||||
= link_to order.member.login_name, order.member
|
||||
= "(deleted)" if order.member.deleted_at
|
||||
%td= order.id
|
||||
%td
|
||||
- if order.completed_at
|
||||
|
||||
@@ -6,7 +6,10 @@
|
||||
.col-md-11
|
||||
.comment-meta
|
||||
Posted by
|
||||
= link_to comment.author.login_name, member_path(comment.author)
|
||||
- if comment.author
|
||||
= link_to comment.author.login_name, member_path(comment.author)
|
||||
- else
|
||||
Member Deleted
|
||||
on
|
||||
= comment.created_at
|
||||
- if comment.updated_at > comment.created_at
|
||||
|
||||
@@ -90,8 +90,7 @@
|
||||
- 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.
|
||||
volunteer crop wranglers 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) && @crop.requester
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
- if can? :wrangle, Crop
|
||||
= 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)
|
||||
- if @num_requested_crops && @num_requested_crops.positive?
|
||||
= link_to(I18n.t('crops.requested.link', number_crops: @num_requested_crops), requested_crops_path)
|
||||
|
||||
%p
|
||||
#{ENV['GROWSTUFF_SITE_NAME']} tracks who's growing what, where.
|
||||
@@ -23,10 +23,10 @@
|
||||
= submit_tag "Show", class: 'btn btn-primary'
|
||||
|
||||
.pagination
|
||||
= will_paginate @paginated_crops
|
||||
= will_paginate @crops
|
||||
|
||||
.row
|
||||
- @paginated_crops.each do |crop|
|
||||
- @crops.each do |crop|
|
||||
.col-md-2.six-across
|
||||
= render partial: "thumbnail", locals: { crop: crop }
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
= link_to 'New Crop', new_crop_path, class: 'btn btn-primary'
|
||||
|
||||
.pagination
|
||||
= will_paginate @paginated_crops
|
||||
= will_paginate @crops
|
||||
|
||||
|
||||
%ul.list-inline
|
||||
|
||||
@@ -7,5 +7,5 @@
|
||||
%item
|
||||
%title= crop.name
|
||||
%pubdate= crop.created_at.to_s(:rfc822)
|
||||
%link= post_url(crop)
|
||||
%guid= post_url(crop)
|
||||
%link= crop_url(crop)
|
||||
%guid= crop_url(crop)
|
||||
|
||||
12
app/views/devise/registrations/_delete.html.haml
Normal file
12
app/views/devise/registrations/_delete.html.haml
Normal file
@@ -0,0 +1,12 @@
|
||||
= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :delete, class: 'form-horizontal' }) do |f|
|
||||
%br/
|
||||
= devise_error_messages!
|
||||
|
||||
.form-group
|
||||
= f.label :current_password, "Password required to delete", class: 'control-label col-md-2'
|
||||
.col-md-4
|
||||
= f.password_field :current_password, class: 'form-control', id: 'current_pw_for_delete'
|
||||
|
||||
.form-group
|
||||
.form-actions.col-md-offset-2.col-md-8
|
||||
= f.submit "Delete", class: 'btn btn-primary'
|
||||
@@ -13,6 +13,9 @@
|
||||
%li
|
||||
%a{ href: '#password', role: 'tab', 'data-toggle': 'tab' }
|
||||
Password
|
||||
%li
|
||||
%a{ href: '#delete', role: 'tab', 'data-toggle': 'tab' }
|
||||
Delete Account
|
||||
|
||||
.tab-content
|
||||
.tab-pane.active#profile
|
||||
@@ -23,3 +26,5 @@
|
||||
= render partial: 'edit_apps'
|
||||
.tab-pane#password
|
||||
= render partial: 'edit_password'
|
||||
.tab-pane#delete
|
||||
= render partial: 'delete'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.panel.panel-success
|
||||
.panel-heading
|
||||
%h3.panel-title
|
||||
= link_to display_garden_name(garden), garden
|
||||
= link_to display_garden_name(garden), garden_path(garden)
|
||||
- if can? :edit, garden
|
||||
%a.pull-right{ href: edit_garden_path(garden), role: "button", id: "edit_garden_glyphicon" }
|
||||
%span.glyphicon.glyphicon-pencil{ title: "Edit" }
|
||||
@@ -14,7 +14,7 @@
|
||||
.col-md-8
|
||||
%dl.dl-horizontal
|
||||
%dt Name :
|
||||
%dd= link_to display_garden_name(garden), garden
|
||||
%dd= link_to display_garden_name(garden), garden_path(garden)
|
||||
%dt Location :
|
||||
%dd
|
||||
- if garden.location.blank?
|
||||
@@ -29,11 +29,9 @@
|
||||
%b
|
||||
= localize_plural(garden.plantings, Planting)
|
||||
= ":"
|
||||
= display_garden_plantings(garden.plantings.current)
|
||||
= display_garden_plantings(garden.plantings.current.includes(:crop).first(2))
|
||||
- if garden.plantings.size > 2
|
||||
%br
|
||||
= link_to "See more plantings >>", garden_path(garden)
|
||||
.panel-footer
|
||||
%dt Description
|
||||
%dd
|
||||
= display_garden_description(garden)
|
||||
%dd= display_garden_description(garden)
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
%p.btn-group
|
||||
- if can? :edit, @garden
|
||||
- if @garden.active
|
||||
= link_to "Plant something", new_planting_path(garden_id: @garden.id), class: 'btn btn-primary'
|
||||
= link_to new_planting_path(garden_id: @garden.id), class: 'btn btn-primary' do
|
||||
%span.glyphicon.glyphicon-grain{ title: "Plant" }
|
||||
Plant something
|
||||
= link_to "Mark as inactive", garden_path(@garden, garden: { active: 0 }),
|
||||
method: :put, class: 'btn btn-default',
|
||||
data: { confirm: 'All plantings associated with this garden will be marked as finished. Are you sure?' }
|
||||
@@ -23,12 +25,14 @@
|
||||
= link_to "Mark as active", garden_path(@garden, garden: { active: 1 }),
|
||||
method: :put,
|
||||
class: 'btn btn-default'
|
||||
= link_to 'Edit garden', edit_garden_path(@garden), class: 'btn btn-default'
|
||||
= link_to edit_garden_path(@garden), class: 'btn btn-default', id: 'edit_garden_link' do
|
||||
%span.glyphicon.glyphicon-pencil{ title: "Edit garden" }
|
||||
- if can?(:destroy, @garden)
|
||||
= link_to 'Delete garden', @garden,
|
||||
= link_to @garden,
|
||||
method: :delete,
|
||||
data: { confirm: 'All plantings associated with this garden will also be deleted. Are you sure?' },
|
||||
class: 'btn btn-default'
|
||||
class: 'btn btn-default', id: 'delete_garden_link' do
|
||||
%span.glyphicon.glyphicon-trash{ title: "Delete" }
|
||||
|
||||
- unless @garden.active
|
||||
.alert.alert-warning
|
||||
@@ -49,35 +53,23 @@
|
||||
Why not
|
||||
= link_to 'tell us more.', edit_garden_path(@garden)
|
||||
|
||||
- if !@garden.photos.empty? || (can?(:edit, @garden) && can?(:create, Photo))
|
||||
.row-fluid
|
||||
%h3 Photos
|
||||
%p= localize_plural(@garden.photos, Photo)
|
||||
.row-fluid
|
||||
%ul.thumbnails
|
||||
- @garden.photos.each do |p|
|
||||
.col-md-2.six-across
|
||||
= render partial: 'photos/thumbnail', locals: { photo: p }
|
||||
.row-fluid
|
||||
- if can?(:create, Photo) && can?(:edit, @garden)
|
||||
%p
|
||||
= link_to "Add photo", new_photo_path(type: "garden", id: @garden.id), class: 'btn btn-primary'
|
||||
|
||||
.row-fluid
|
||||
%h3 What's planted here?
|
||||
- if @garden.plantings.current.empty?
|
||||
%p Nothing is currently planted here.
|
||||
%h3 What's planted here?
|
||||
.row
|
||||
- if @current_plantings.size.positive?
|
||||
- @current_plantings.each do |planting|
|
||||
.col-xs-12.col-md-6
|
||||
= render partial: "plantings/card", locals: { planting: planting }
|
||||
- else
|
||||
.col-md-12
|
||||
%p Nothing is currently planted here.
|
||||
%h3 Previously planted in this garden
|
||||
.row
|
||||
- if @finished_plantings.size.positive?
|
||||
- @finished_plantings.each do |planting|
|
||||
.col-xs-6.col-md-2
|
||||
= render partial: "plantings/thumbnail", locals: { planting: planting }
|
||||
- else
|
||||
- @garden.plantings.current.each.with_index do |planting_current, _|
|
||||
= render partial: "plantings/thumbnail", locals: { planting: planting_current }
|
||||
|
||||
.row-fluid
|
||||
%h3 Previously planted in this garden
|
||||
- if @garden.plantings.finished.empty?
|
||||
%p Nothing has been planted here.
|
||||
- else
|
||||
- @garden.plantings.finished.each.with_index do |planting_finished|
|
||||
= render partial: "plantings/thumbnail", locals: { planting: planting_finished }
|
||||
.col-md-3
|
||||
%h4 About this garden
|
||||
%p
|
||||
@@ -107,9 +99,24 @@
|
||||
- @garden.owner.gardens.inactive.each do |othergarden|
|
||||
%li
|
||||
- if @garden == othergarden
|
||||
= @garden
|
||||
= @garden.name
|
||||
- else
|
||||
= link_to othergarden, garden_path(othergarden)
|
||||
|
||||
- if can? :create, @garden
|
||||
= link_to 'Add New Garden', new_garden_path, class: 'btn btn-default btn-xs'
|
||||
- if @garden.owner == current_member
|
||||
%p
|
||||
= link_to new_garden_path, class: 'btn btn-default btn-xs' do
|
||||
Add New Garden
|
||||
|
||||
- if can?(:edit, @garden) && can?(:create, Photo)
|
||||
%p
|
||||
= link_to new_photo_path(type: "garden", id: @garden.id),
|
||||
class: 'btn btn-primary' do
|
||||
%span.glyphicon.glyphicon-camera{ title: "Add Photo" }
|
||||
Add Photo
|
||||
- if @garden.photos.size.positive?
|
||||
%h3= localize_plural(@garden.photos, Photo)
|
||||
.row
|
||||
- @garden.photos.includes(:owner).each do |photo|
|
||||
.col-xs-6
|
||||
= render partial: 'photos/thumbnail', locals: { photo: photo }
|
||||
15
app/views/harvests/_nav.haml
Normal file
15
app/views/harvests/_nav.haml
Normal file
@@ -0,0 +1,15 @@
|
||||
%p
|
||||
- if can? :create, Harvest
|
||||
- if @planting && @planting.owner == current_member
|
||||
= link_to 'Add harvest', new_planting_harvest_path(planting: @planting), class: 'btn btn-primary'
|
||||
- elsif @owner
|
||||
%p
|
||||
- if @owner == current_member
|
||||
= link_to 'Add harvest', new_harvest_path, class: 'btn btn-primary'
|
||||
= link_to "View everyone's harvests", harvests_path, class: 'btn btn-default'
|
||||
- else # everyone's harvests
|
||||
= link_to 'Add harvest', new_harvest_path, class: 'btn btn-primary'
|
||||
- if current_member
|
||||
= link_to 'View your harvests', harvests_by_owner_path(owner: current_member.slug), class: 'btn btn-default'
|
||||
- else
|
||||
= render partial: 'shared/signin_signup', locals: { to: 'track your harvests' }
|
||||
@@ -1,4 +1,4 @@
|
||||
- content_for :title, title('harvests', @owner, @crop)
|
||||
- content_for :title, title('harvests', @owner, @crop, @planting)
|
||||
|
||||
- if @owner
|
||||
= link_to "View #{@owner}'s profile >>", member_path(@owner)
|
||||
@@ -7,20 +7,7 @@
|
||||
#{ENV['GROWSTUFF_SITE_NAME']} helps you track what you're
|
||||
harvesting from your home garden and see how productive it is.
|
||||
|
||||
%p
|
||||
- if can? :create, Harvest
|
||||
- if @owner
|
||||
%p
|
||||
- if @owner == current_member
|
||||
= link_to 'Add harvest', new_harvest_path, class: 'btn btn-primary'
|
||||
= link_to "View everyone's harvests", harvests_path, class: 'btn btn-default'
|
||||
- else # everyone's harvests
|
||||
= link_to 'Add harvest', new_harvest_path, class: 'btn btn-primary'
|
||||
- if current_member
|
||||
= link_to 'View your harvests', harvests_by_owner_path(owner: current_member.slug), class: 'btn btn-default'
|
||||
- else
|
||||
= render partial: 'shared/signin_signup', locals: { to: 'track your harvests' }
|
||||
|
||||
= render "nav"
|
||||
.pagination
|
||||
= page_entries_info @harvests
|
||||
= will_paginate @harvests
|
||||
|
||||
@@ -3,18 +3,18 @@
|
||||
- cache cache_key_for(Crop, 'interesting'), expires_in: 1.day do
|
||||
%h2= t('.our_crops')
|
||||
.hidden-xs
|
||||
- Crop.interesting.first(8).each do |c|
|
||||
- Crop.interesting.includes(:scientific_names, :photos).first(8).each do |c|
|
||||
.col-md-3
|
||||
= render partial: 'crops/thumbnail', locals: { crop: c }
|
||||
.visible-xs
|
||||
- Crop.interesting.first(3).each do |c|
|
||||
- Crop.interesting.includes(:scientific_names, :photos).first(3).each do |c|
|
||||
.col-md-3
|
||||
= render partial: 'crops/thumbnail', locals: { crop: c }
|
||||
|
||||
.col-md-4.hidden-xs
|
||||
- cache cache_key_for(Planting) do
|
||||
%h2= t('.recently_planted')
|
||||
= render partial: 'plantings/list', locals: { plantings: Planting.interesting.first(6) }
|
||||
= render partial: 'plantings/list', locals: { plantings: Planting.includes(:owner, :photos).interesting.first(6) }
|
||||
|
||||
.row
|
||||
.col-md-12
|
||||
|
||||
@@ -1,28 +1,21 @@
|
||||
- seeds = Seed.interesting.first(6)
|
||||
- if seeds.present?
|
||||
- cache cache_key_for(Seed, 'interesting'), expires_in: 1.day do
|
||||
%h2= t('.title')
|
||||
- cache cache_key_for(Seed) do
|
||||
%table.table.table-striped
|
||||
%tr
|
||||
%th= t('.owner')
|
||||
%th= t('.crop')
|
||||
%th.hidden-xs.hidden-sm= t('.description')
|
||||
%th= t('.trade_to')
|
||||
%th= t('.from')
|
||||
%th
|
||||
|
||||
- seeds.each do |seed|
|
||||
%tr
|
||||
%td= link_to seed.owner.login_name, seed.owner
|
||||
%td= link_to seed.crop.name, seed.crop
|
||||
%td.hidden-xs.hidden-sm= truncate(seed.description, length: 40, separator: ' ')
|
||||
%td= seed.tradable? ? seed.tradable_to : ''
|
||||
%td
|
||||
- if seed.tradable? && seed.owner.location.blank?
|
||||
= t('.unspecified')
|
||||
- elsif seed.tradable?
|
||||
= truncate(seed.owner.location, length: 25, separator: ', ')
|
||||
%td= link_to t('.details'), seed, class: 'btn btn-default btn-xs'
|
||||
|
||||
%p.text-right
|
||||
= link_to "#{t('.view_all')} »", seeds_path
|
||||
.row
|
||||
.col-md-8
|
||||
- Seed.includes(:owner, crop: :photos).interesting.first(6).each do |seed|
|
||||
.col-md-3
|
||||
.thumbnail
|
||||
- cache cache_key_for(Crop, seed.id) do
|
||||
= link_to image_tag((seed.default_photo ? seed.default_photo.thumbnail_url : 'placeholder_150.png'),
|
||||
alt: seed.crop.name, class: 'img'),
|
||||
seed
|
||||
.seedinfo
|
||||
= link_to seed.crop.name, seed
|
||||
.trade-to
|
||||
%p= seed.owner.location
|
||||
%p
|
||||
Will trade to:
|
||||
%br/
|
||||
#{seed.tradable_to}
|
||||
%p.text-right
|
||||
= link_to "#{t('.view_all')} »", seeds_path
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
= link_to image_tag(avatar_uri(member, 150),
|
||||
alt: '',
|
||||
class: 'img img-responsive avatar'),
|
||||
member_path(member)
|
||||
- if member
|
||||
= link_to image_tag(avatar_uri(member, 150),
|
||||
alt: '',
|
||||
class: 'img img-responsive avatar'),
|
||||
member_path(member)
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
%p= localize_plural(g.photos, Photo)
|
||||
.row
|
||||
%ul.thumbnails
|
||||
- g.photos.each do |p|
|
||||
- g.photos.includes(:owner).each do |p|
|
||||
.col-md-2.six-across
|
||||
= render partial: 'photos/thumbnail', locals: { photo: p }
|
||||
.row
|
||||
@@ -49,7 +49,7 @@
|
||||
- unless g.featured_plantings.empty?
|
||||
- g.featured_plantings.each.with_index do |planting|
|
||||
.col-xs-12.col-lg-6
|
||||
= render partial: "plantings/thumbnail", locals: { planting: planting }
|
||||
= render partial: "plantings/card", locals: { planting: planting }
|
||||
|
||||
%p
|
||||
= link_to "More about this garden...", url_for(g)
|
||||
|
||||
@@ -18,10 +18,6 @@
|
||||
= link_to "approve or reject this request", edit_crop_url(@request)
|
||||
\.
|
||||
|
||||
%p
|
||||
Or, discuss this and other crop wrangling issues in our
|
||||
= link_to "crop wrangling forum", "http://talk.growstuff.org/c/crop-wrangling"
|
||||
|
||||
%p
|
||||
Thanks for your help!
|
||||
|
||||
|
||||
4
app/views/photos/_photo_association_delete.haml
Normal file
4
app/views/photos/_photo_association_delete.haml
Normal file
@@ -0,0 +1,4 @@
|
||||
- if can? :edit, photo
|
||||
= link_to photo_associations_path(photo_id: photo.id, type: type, id: thing.id),
|
||||
method: 'delete', class: 'btn btn-default btn-xs' do
|
||||
%span.glyphicon.glyphicon-remove{ title: "Remove link" }
|
||||
21
app/views/photos/_photo_associations.html.haml
Normal file
21
app/views/photos/_photo_associations.html.haml
Normal file
@@ -0,0 +1,21 @@
|
||||
%h4 This photo depicts:
|
||||
%ul
|
||||
- @photo.plantings.each do |planting|
|
||||
%li
|
||||
= link_to t('photos.show.planting', planting: planting.to_s, owner: planting.owner.to_s), planting_path(planting)
|
||||
= render partial: "photo_association_delete", locals: { photo: @photo, type: 'planting', thing: planting }
|
||||
|
||||
- @photo.harvests.each do |harvest|
|
||||
%li
|
||||
= link_to t('photos.show.harvest', crop: harvest.crop.name, owner: harvest.owner.to_s), harvest_path(harvest)
|
||||
= render partial: "photo_association_delete", locals: { photo: @photo, type: 'harvest', thing: harvest }
|
||||
|
||||
- @photo.gardens.each do |garden|
|
||||
%li
|
||||
= link_to t('photos.show.garden', garden: garden.to_s, owner: garden.owner.to_s), garden_path(garden)
|
||||
= render partial: "photo_association_delete", locals: { photo: @photo, type: 'garden', thing: garden }
|
||||
|
||||
- @photo.seeds.each do |seed|
|
||||
%li
|
||||
= link_to t('photos.show.seed', seed: seed.to_s, owner: seed.owner.to_s), seed_path(seed)
|
||||
= render partial: "photo_association_delete", locals: { photo: @photo, type: 'seed', thing: seed }
|
||||
@@ -1,2 +1,5 @@
|
||||
- content_for :title, "Edit Photo"
|
||||
|
||||
= form_for(@photo) do |f|
|
||||
= f.label :title
|
||||
= f.text_field :title, placeholder: "title"
|
||||
= f.submit
|
||||
|
||||
@@ -36,5 +36,5 @@
|
||||
- else
|
||||
.alert
|
||||
You must
|
||||
= link_to "connect your account to Flickr", '/auth/flickr'
|
||||
= link_to "connect your account to Flickr", '/members/auth/flickr'
|
||||
to add photos.
|
||||
|
||||
@@ -8,7 +8,19 @@
|
||||
= tag("meta", property: "og:site_name", content: ENV['GROWSTUFF_SITE_NAME'])
|
||||
|
||||
.row
|
||||
.col-md-6
|
||||
.col-md-8
|
||||
%p= image_tag(@photo.fullsize_url, alt: @photo.title, class: 'img img-responsive')
|
||||
|
||||
.col-md-4
|
||||
%p
|
||||
- if can? :destroy, @photo
|
||||
= link_to @photo, method: :delete,
|
||||
data: { confirm: 'Are you sure?' }, class: 'btn btn-default btn-xs' do
|
||||
%span.glyphicon.glyphicon-trash{ title: "Delete" }
|
||||
|
||||
- if can? :edit, @photo
|
||||
= link_to edit_photo_path(@photo), class: 'btn btn-default btn-xs' do
|
||||
%span.glyphicon.glyphicon-pencil{ title: "Edit" }
|
||||
%p
|
||||
%strong Posted by:
|
||||
= link_to @photo.owner, @photo.owner
|
||||
@@ -19,30 +31,7 @@
|
||||
- else
|
||||
= succeed "." do
|
||||
= @photo.license_name
|
||||
%p
|
||||
= link_to "View on Flickr", @photo.link_url
|
||||
|
||||
- if can? :destroy, @photo
|
||||
%p= link_to 'Delete Photo',
|
||||
@photo,
|
||||
method: :delete,
|
||||
data: { confirm: 'Are you sure?' },
|
||||
class: 'btn btn-default btn-xs'
|
||||
|
||||
.col-md-6
|
||||
- unless @photo.plantings.empty? && @photo.harvests.empty? && @photo.gardens.empty? && @photo.seeds.empty?
|
||||
%p This photo depicts:
|
||||
%ul
|
||||
- @photo.plantings.each do |p|
|
||||
%li= link_to t('.planting', planting: p.to_s, owner: p.owner.to_s), planting_path(p)
|
||||
- @photo.harvests.each do |h|
|
||||
%li= link_to t('.harvest', crop: h.crop.name, owner: h.owner.to_s), harvest_path(h)
|
||||
- @photo.gardens.each do |g|
|
||||
%li= link_to t('.garden', garden: g.to_s, owner: g.owner.to_s), garden_path(g)
|
||||
- @photo.seeds.each do |s|
|
||||
%li= link_to t('.seed', seed: s.to_s, owner: s.owner.to_s), seed_path(s)
|
||||
|
||||
.row
|
||||
.col-md-12
|
||||
%p= image_tag(@photo.fullsize_url, alt: @photo.title, class: 'img')
|
||||
|
||||
%p= link_to "View on Flickr", @photo.link_url
|
||||
- if @photo.associations?
|
||||
= render "photo_associations", locals: { photo: @photo }
|
||||
|
||||
@@ -44,11 +44,9 @@
|
||||
.row
|
||||
- plantings.first(10).each.with_index do |planting, index|
|
||||
.col-xs-12.col-lg-6
|
||||
= render partial: "plantings/thumbnail", locals: { planting: planting, index: index }
|
||||
.row
|
||||
= link_to "View all plantings >>", plantings_path
|
||||
= render partial: "plantings/card", locals: { planting: planting, index: index }
|
||||
= link_to "View all plantings >>", plantings_path
|
||||
- else
|
||||
.row
|
||||
%p No nearby plantings found
|
||||
%p No nearby plantings found
|
||||
- else
|
||||
%p No results found
|
||||
|
||||
61
app/views/plantings/_card.html.haml
Normal file
61
app/views/plantings/_card.html.haml
Normal file
@@ -0,0 +1,61 @@
|
||||
.panel.panel-success.planting-thumbnail
|
||||
.panel-heading
|
||||
%h3.panel-title
|
||||
= link_to planting.crop.name, planting_path(planting)
|
||||
- if can? :edit, planting
|
||||
%a.pull-right{ href: edit_planting_path(planting), role: "button", id: "edit_garden_glyphicon" }
|
||||
%span.glyphicon.glyphicon-pencil{ title: "Edit" }
|
||||
.panel-body
|
||||
.row
|
||||
.col-xs-12.col-md-5
|
||||
= link_to image_tag((planting.default_photo ? planting.default_photo.thumbnail_url : 'placeholder_150.png'),
|
||||
alt: planting.crop_id, class: 'img img-responsive'),
|
||||
planting
|
||||
.col-xs-12.col-md-7
|
||||
%dl.dl-horizontal.planting-attributes
|
||||
%dt Owner:
|
||||
%dd= link_to planting.owner.login_name, planting.owner
|
||||
%dt Garden:
|
||||
%dd= link_to planting.garden.name, planting.garden
|
||||
%dt Planted on:
|
||||
%dd= planting.planted_at
|
||||
- if planting.quantity
|
||||
%dt Quantity:
|
||||
%dd= display_planting_quantity(planting)
|
||||
- if planting.finished?
|
||||
%dt Finished on:
|
||||
%dd= display_finished(planting)
|
||||
%dt Sun/shade?:
|
||||
%dd
|
||||
- sunniness = planting.sunniness.blank? ? "not specified" : planting.sunniness
|
||||
= image_tag("sunniness_#{sunniness}.png", size: "25x25", alt: sunniness, title: sunniness)
|
||||
= " (#{sunniness})"
|
||||
%dt Planted from:
|
||||
%dd= display_planted_from(planting)
|
||||
|
||||
%dt Mature in:
|
||||
%dd
|
||||
= display_days_before_maturity(planting)
|
||||
days
|
||||
|
||||
%p= render partial: 'plantings/planting_progress', locals: { planting: planting }
|
||||
|
||||
= link_to 'Details', planting_path(planting),
|
||||
class: 'btn btn-default btn-xs'
|
||||
|
||||
- if can?(:edit, planting) && can?(:create, Harvest)
|
||||
= link_to 'Harvest', new_planting_harvest_path(planting),
|
||||
class: 'btn btn-default btn-xs'
|
||||
|
||||
- if can?(:edit, planting) && !planting.finished
|
||||
= link_to "Mark as finished",
|
||||
planting_path(planting, planting: { finished: 1 }),
|
||||
method: :put,
|
||||
class: 'btn btn-default btn-xs append-date'
|
||||
|
||||
- if can? :destroy, planting
|
||||
= link_to planting, method: :delete,
|
||||
data: { confirm: 'Are you sure?' },
|
||||
class: 'btn btn-default btn-xs' do
|
||||
%span.glyphicon.glyphicon-trash{ title: "Delete" }
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
Harvests:
|
||||
- if planting.harvests
|
||||
- unless planting.harvests.empty?
|
||||
Harvests:
|
||||
%ul
|
||||
- planting.harvests.each do |harvest|
|
||||
%li
|
||||
= harvest.harvested_at ? harvest.harvested_at : "undated"
|
||||
= link_to harvest, harvest_path(harvest)
|
||||
- else
|
||||
none
|
||||
= link_to "more harvests from this planting", planting_harvests_path(planting)
|
||||
|
||||
@@ -1,57 +1,11 @@
|
||||
.panel.panel-success.planting-thumbnail
|
||||
.panel-heading
|
||||
%h3.panel-title= link_to planting.crop.name, planting.crop
|
||||
.panel-body
|
||||
.row
|
||||
.col-xs-12.col-md-4
|
||||
= link_to image_tag((planting.default_photo ? planting.default_photo.thumbnail_url : 'placeholder_150.png'),
|
||||
alt: planting.crop_id, class: 'img'),
|
||||
planting
|
||||
.col-xs-7.col-md-5
|
||||
%dl.dl-horizontal.planting-attributes
|
||||
%dt Owner:
|
||||
%dd= link_to planting.owner.login_name, planting.owner
|
||||
%dt Garden:
|
||||
%dd= link_to planting.garden.name, planting.garden
|
||||
%dt Planted on:
|
||||
%dd= planting.planted_at
|
||||
%dt Quantity:
|
||||
%dd= display_planting_quantity(planting)
|
||||
%dt Finished on:
|
||||
%dd= display_finished(planting)
|
||||
%dt Sun/shade?:
|
||||
%dd
|
||||
- sunniness = planting.sunniness.blank? ? "not specified" : planting.sunniness
|
||||
= image_tag("sunniness_#{sunniness}.png", size: "25x25", alt: sunniness, title: sunniness)
|
||||
= " (#{sunniness})"
|
||||
%dt Planted from:
|
||||
%dd= display_planted_from(planting)
|
||||
.col-xs-1.col-md-3
|
||||
%ul{ style: "list-style-type:none; text-align:right" }
|
||||
%li= link_to 'Details', planting, class: 'btn btn-default btn-xs'
|
||||
- if can? :edit, planting
|
||||
%li= link_to 'Edit', edit_planting_path(planting), class: 'btn btn-default btn-xs'
|
||||
- if can? :create, Harvest
|
||||
%li= link_to 'Harvest', new_planting_harvest_path(planting), class: 'btn btn-default btn-xs'
|
||||
- unless planting.finished
|
||||
%li
|
||||
= link_to "Mark as finished",
|
||||
planting_path(planting, planting: { finished: 1 }),
|
||||
method: :put,
|
||||
class: 'btn btn-default btn-xs append-date'
|
||||
- if can? :destroy, planting
|
||||
%li
|
||||
= link_to 'Delete',
|
||||
planting, method: :delete,
|
||||
data: { confirm: 'Are you sure?' },
|
||||
class: 'btn btn-default btn-xs'
|
||||
.row
|
||||
.col-xs-12.col-md-4
|
||||
%dl
|
||||
%dt Days until maturity:
|
||||
%dd= display_days_before_maturity(planting)
|
||||
|
||||
.col-xs-12.col-md-8
|
||||
= render partial: 'plantings/planting_progress', locals: { planting: planting }
|
||||
.col-xs-12.col-md-8
|
||||
= render partial: 'plantings/planting_harvest', locals: { planting: planting }
|
||||
.thumbnail
|
||||
.planting-thumbnail
|
||||
- if planting
|
||||
= link_to image_tag((planting.default_photo ? planting.default_photo.thumbnail_url : 'placeholder_150.png'),
|
||||
alt: planting.crop.name, class: 'img'),
|
||||
planting
|
||||
.plantinginfo
|
||||
.planting-name
|
||||
= link_to planting.crop.name, planting
|
||||
%small.planting-date
|
||||
= display_finished(planting)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
- content_for :title, title('plantings', @owner, @crop)
|
||||
- content_for :title, title('plantings', @owner, @crop, @planting)
|
||||
|
||||
= render 'nav', owner: @owner, show_all: @show_all
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
- unless @plantings.empty?
|
||||
- @plantings.each.with_index do |planting|
|
||||
.col-xs-12.col-lg-6
|
||||
= render partial: "plantings/thumbnail", locals: { planting: planting }
|
||||
= render partial: "plantings/card", locals: { planting: planting }
|
||||
|
||||
.pagination
|
||||
= page_entries_info @plantings
|
||||
|
||||
@@ -10,7 +10,10 @@
|
||||
.post-meta
|
||||
%p
|
||||
Posted by
|
||||
= link_to post.author.login_name, member_path(post.author)
|
||||
- if post.author
|
||||
= link_to post.author.login_name, member_path(post.author)
|
||||
- else
|
||||
Member Deleted
|
||||
- if post.forum
|
||||
in
|
||||
= link_to post.forum, post.forum
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
= tag("meta", property: "og:url", content: request.original_url)
|
||||
= tag("meta", property: "og:site_name", content: ENV['GROWSTUFF_SITE_NAME'])
|
||||
|
||||
- unless current_member
|
||||
- if @post.author && !current_member
|
||||
.alert.alert-info
|
||||
= link_to @post.author.login_name, member_path(@post.author)
|
||||
is using
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
- content_for :title, title('seeds', @owner, @crop)
|
||||
- content_for :title, title('seeds', @owner, @crop, @planting)
|
||||
- if @owner
|
||||
= link_to "View #{@owner}'s profile >>", member_path(@owner)
|
||||
|
||||
|
||||
@@ -77,4 +77,10 @@ Growstuff::Application.configure do
|
||||
config.action_controller.action_on_unpermitted_parameters = :raise
|
||||
|
||||
config.active_job.queue_adapter = :sidekiq
|
||||
|
||||
config.after_initialize do
|
||||
Bullet.enable = true
|
||||
Bullet.rails_logger = true
|
||||
Bullet.add_footer = true
|
||||
end
|
||||
end
|
||||
|
||||
@@ -23,4 +23,8 @@ ActiveSupport::Inflector.inflections do |inflect|
|
||||
inflect.plural 'achiote', 'achiote'
|
||||
inflect.plural 'alfalfa', 'alfalfa'
|
||||
inflect.plural 'allspice', 'allspice'
|
||||
inflect.plural 'spinach', 'spinach'
|
||||
inflect.plural 'garlic', 'garlic'
|
||||
inflect.plural 'licorice', 'licorice'
|
||||
inflect.plural 'lillipilli', 'lillipillies'
|
||||
end
|
||||
|
||||
@@ -33,19 +33,26 @@ en:
|
||||
send_instructions: 'You will receive an email with instructions about how to reset your password in a few minutes.'
|
||||
updated: 'Your password was changed successfully. You are now signed in.'
|
||||
updated_not_active: 'Your password was changed successfully.'
|
||||
send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes."
|
||||
no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided."
|
||||
send_paranoid_instructions: >
|
||||
If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes.
|
||||
no_token: >
|
||||
You can't access this page without coming from a password reset email. If you do come from a password reset email,
|
||||
please make sure you used the full URL provided.
|
||||
confirmations:
|
||||
send_instructions: 'You will receive an email with instructions about how to confirm your account in a few minutes.'
|
||||
send_paranoid_instructions: 'If your email address exists in our database, you will receive an email with instructions about how to confirm your account in a few minutes.'
|
||||
send_paranoid_instructions: >
|
||||
If your email address exists in our database, you will receive an email with instructions about how to confirm your account in a few minutes.
|
||||
confirmed: 'Your account was successfully confirmed.'
|
||||
registrations:
|
||||
signed_up: 'Welcome! You have signed up successfully.'
|
||||
signed_up_but_unconfirmed: 'A message with a confirmation link has been sent to your email address. Please open the link to activate your account.'
|
||||
signed_up_but_unconfirmed: >
|
||||
A message with a confirmation link has been sent to your email address. Please open the link to activate your account.
|
||||
signed_up_but_inactive: 'You have signed up successfully. However, we could not sign you in because your account is not yet activated.'
|
||||
signed_up_but_locked: 'You have signed up successfully. However, we could not sign you in because your account is locked.'
|
||||
updated: 'You updated your account successfully.'
|
||||
update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and click on the confirm link to finalize confirming your new email address."
|
||||
update_needs_confirmation: >
|
||||
You updated your account successfully, but we need to verify your new email address. Please check your email and click on the confirm
|
||||
link to finalize confirming your new email address.
|
||||
destroyed: 'Bye! Your account was successfully cancelled. We hope to see you again soon.'
|
||||
unlocks:
|
||||
send_instructions: 'You will receive an email with instructions about how to unlock your account in a few minutes.'
|
||||
|
||||
@@ -63,13 +63,17 @@ en:
|
||||
index:
|
||||
title:
|
||||
crop_harvests: Everyone's %{crop} harvests
|
||||
planting_harvests: Harvests from %{planting}
|
||||
default: Everyone's harvests
|
||||
owner_harvests: "%{owner} harvests"
|
||||
updated: Harvest was successfully updated.
|
||||
home:
|
||||
blurb:
|
||||
already_html: Or %{sign_in} if you already have an account
|
||||
intro: "%{site_name} is a community of food gardeners. We're building an open source platform to help you learn about growing food, track what you plant and harvest, and swap seeds and produce with other gardeners near you."
|
||||
intro: >
|
||||
%{site_name} is a community of food gardeners. We're building an open source
|
||||
platform to help you learn about growing food, track what you plant and harvest,
|
||||
and swap seeds and produce with other gardeners near you.
|
||||
perks: Join now for your free garden journal, seed sharing, forums, and more.
|
||||
sign_in_linktext: sign in
|
||||
sign_up: Sign up
|
||||
@@ -97,12 +101,21 @@ en:
|
||||
api_docs_linktext: API documentation
|
||||
buy_account_linktext: buying a paid account
|
||||
creative_commons_linktext: Creative Commons license
|
||||
get_involved_body_html: We believe in collaboration, and work closely with our members and the wider food-growing community. Our team includes volunteers from all walks of life and all skill levels. To get involved, visit %{talk_link} or find more information on the %{wiki_link}.
|
||||
get_involved_body_html: >
|
||||
We believe in collaboration, and work closely with our members and the wider food-growing community.
|
||||
Our team includes volunteers from all walks of life and all skill levels. To get involved,
|
||||
visit %{talk_link} or find more information on the %{wiki_link}.
|
||||
get_involved_title: Get Involved
|
||||
github_linktext: Github
|
||||
open_data_body_html: We're building a database of crops, planting advice, seed sources, and other information that anyone can use for free, under a %{creative_commons_link}. You can use this data for research, to build apps, or for any purpose at all. Read more about our %{wiki_link} and %{api_docs_link}.
|
||||
open_data_body_html: >
|
||||
We're building a database of crops, planting advice, seed sources, and other information that anyone
|
||||
can use for free, under a %{creative_commons_link}. You can use this data for research, to build apps,
|
||||
or for any purpose at all. Read more about our %{wiki_link} and %{api_docs_link}.
|
||||
open_data_title: Open Data and APIs
|
||||
open_source_body_html: "%{site_name} is open source software, which means that we share this website's code for free with our community and the world. We believe that openness, sustainability, and social good go hand in hand. You can read more about %{why} or check out our code on %{github}."
|
||||
open_source_body_html: >
|
||||
%{site_name} is open source software, which means that we share this website's code for free with our
|
||||
community and the world. We believe that openness, sustainability, and social good go hand in hand.
|
||||
You can read more about %{why} or check out our code on %{github}.
|
||||
open_source_title: Open Source
|
||||
support_body_html: Growstuff is independent, %{ad_free} and we have no outside investment. You can support our work by %{buy_account}.
|
||||
support_title: Support Growstuff
|
||||
@@ -174,7 +187,9 @@ en:
|
||||
title: "%{site_name} Community Map"
|
||||
plantings:
|
||||
form:
|
||||
finish_helper: A planting is finished when you've harvested all of the crop, or it dies, or it's otherwise no longer growing in your garden.
|
||||
finish_helper: >
|
||||
A planting is finished when you've harvested all of the crop, or it dies, or it's otherwise
|
||||
no longer growing in your garden.
|
||||
index:
|
||||
title:
|
||||
crop_plantings: Everyone's %{crop} plantings
|
||||
@@ -188,7 +203,10 @@ en:
|
||||
default: Everyone's posts
|
||||
seeds:
|
||||
form:
|
||||
trade_help: Are you interested in trading or swapping seeds with other %{site_name} members? If you list your seeds as available for trade, other members can contact you to request seeds. You can list any conditions or other information in the description, above.
|
||||
trade_help: >
|
||||
Are you interested in trading or swapping seeds with other %{site_name} members? If you list
|
||||
your seeds as available for trade, other members can contact you to request seeds. You can
|
||||
list any conditions or other information in the description, above.
|
||||
index:
|
||||
title:
|
||||
crop_seeds: Everyone's %{crop} seeds
|
||||
|
||||
@@ -17,6 +17,7 @@ Growstuff::Application.routes.draw do
|
||||
resources :members
|
||||
|
||||
resources :photos
|
||||
delete 'photo_associations' => 'photo_associations#destroy'
|
||||
|
||||
resources :authentications, only: [:create, :destroy]
|
||||
|
||||
@@ -81,6 +82,7 @@ Growstuff::Application.routes.draw do
|
||||
root to: 'home#index'
|
||||
|
||||
get 'auth/:provider/callback' => 'authentications#create'
|
||||
get 'members/auth/:provider/callback' => 'authentications#create'
|
||||
|
||||
get '/shop' => 'shop#index'
|
||||
get '/shop/:action' => 'shop#:action'
|
||||
|
||||
@@ -4,7 +4,7 @@ class CreateCms < ActiveRecord::Migration
|
||||
when 'PostgreSQL'
|
||||
{}
|
||||
else
|
||||
{ limit: 16777215 }
|
||||
{ limit: 16_777_215 }
|
||||
end
|
||||
|
||||
# -- Sites --------------------------------------------------------------
|
||||
|
||||
15
db/migrate/20170413221549_counter_caches.rb
Normal file
15
db/migrate/20170413221549_counter_caches.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
class CounterCaches < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :members, :gardens_count, :integer
|
||||
add_column :members, :harvests_count, :integer
|
||||
add_column :members, :seeds_count, :integer
|
||||
|
||||
Member.unscoped.find_each do |member|
|
||||
Member.reset_counters(member.id, :gardens)
|
||||
Member.reset_counters(member.id, :harvests)
|
||||
Member.reset_counters(member.id, :seeds)
|
||||
Member.reset_counters(member.id, :plantings)
|
||||
say "Member #{member.login_name} counter caches updated"
|
||||
end
|
||||
end
|
||||
end
|
||||
6
db/migrate/20170520060252_add_deleted_to_members.rb
Normal file
6
db/migrate/20170520060252_add_deleted_to_members.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
class AddDeletedToMembers < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :members, :deleted_at, :datetime
|
||||
add_index :members, :deleted_at
|
||||
end
|
||||
end
|
||||
253
db/schema.rb
253
db/schema.rb
@@ -11,13 +11,13 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20170104035248) do
|
||||
ActiveRecord::Schema.define(version: 20170520060252) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
||||
create_table "account_types", force: :cascade do |t|
|
||||
t.string "name", limit: 255, null: false
|
||||
t.string "name", null: false
|
||||
t.boolean "is_paid"
|
||||
t.boolean "is_permanent_paid"
|
||||
t.datetime "created_at"
|
||||
@@ -33,31 +33,31 @@ ActiveRecord::Schema.define(version: 20170104035248) do
|
||||
end
|
||||
|
||||
create_table "alternate_names", force: :cascade do |t|
|
||||
t.string "name", limit: 255, null: false
|
||||
t.integer "crop_id", null: false
|
||||
t.integer "creator_id", null: false
|
||||
t.string "name", null: false
|
||||
t.integer "crop_id", null: false
|
||||
t.integer "creator_id", null: false
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
|
||||
create_table "authentications", force: :cascade do |t|
|
||||
t.integer "member_id", null: false
|
||||
t.string "provider", limit: 255, null: false
|
||||
t.string "uid", limit: 255
|
||||
t.string "token", limit: 255
|
||||
t.string "secret", limit: 255
|
||||
t.integer "member_id", null: false
|
||||
t.string "provider", null: false
|
||||
t.string "uid"
|
||||
t.string "token"
|
||||
t.string "secret"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "name", limit: 255
|
||||
t.string "name"
|
||||
end
|
||||
|
||||
add_index "authentications", ["member_id"], name: "index_authentications_on_member_id", using: :btree
|
||||
|
||||
create_table "comfy_cms_blocks", force: :cascade do |t|
|
||||
t.string "identifier", limit: 255, null: false
|
||||
t.string "identifier", null: false
|
||||
t.text "content"
|
||||
t.integer "blockable_id"
|
||||
t.string "blockable_type", limit: 255
|
||||
t.string "blockable_type"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
@@ -66,17 +66,17 @@ ActiveRecord::Schema.define(version: 20170104035248) do
|
||||
add_index "comfy_cms_blocks", ["identifier"], name: "index_comfy_cms_blocks_on_identifier", using: :btree
|
||||
|
||||
create_table "comfy_cms_categories", force: :cascade do |t|
|
||||
t.integer "site_id", null: false
|
||||
t.string "label", limit: 255, null: false
|
||||
t.string "categorized_type", limit: 255, null: false
|
||||
t.integer "site_id", null: false
|
||||
t.string "label", null: false
|
||||
t.string "categorized_type", null: false
|
||||
end
|
||||
|
||||
add_index "comfy_cms_categories", ["site_id", "categorized_type", "label"], name: "index_cms_categories_on_site_id_and_cat_type_and_label", unique: true, using: :btree
|
||||
|
||||
create_table "comfy_cms_categorizations", force: :cascade do |t|
|
||||
t.integer "category_id", null: false
|
||||
t.string "categorized_type", limit: 255, null: false
|
||||
t.integer "categorized_id", null: false
|
||||
t.integer "category_id", null: false
|
||||
t.string "categorized_type", null: false
|
||||
t.integer "categorized_id", null: false
|
||||
end
|
||||
|
||||
add_index "comfy_cms_categorizations", ["category_id", "categorized_type", "categorized_id"], name: "index_cms_categorizations_on_cat_id_and_catd_type_and_catd_id", unique: true, using: :btree
|
||||
@@ -84,9 +84,9 @@ ActiveRecord::Schema.define(version: 20170104035248) do
|
||||
create_table "comfy_cms_files", force: :cascade do |t|
|
||||
t.integer "site_id", null: false
|
||||
t.integer "block_id"
|
||||
t.string "label", limit: 255, null: false
|
||||
t.string "file_file_name", limit: 255, null: false
|
||||
t.string "file_content_type", limit: 255, null: false
|
||||
t.string "label", null: false
|
||||
t.string "file_file_name", null: false
|
||||
t.string "file_content_type", null: false
|
||||
t.integer "file_file_size", null: false
|
||||
t.string "description", limit: 2048
|
||||
t.integer "position", default: 0, null: false
|
||||
@@ -100,16 +100,16 @@ ActiveRecord::Schema.define(version: 20170104035248) do
|
||||
add_index "comfy_cms_files", ["site_id", "position"], name: "index_comfy_cms_files_on_site_id_and_position", using: :btree
|
||||
|
||||
create_table "comfy_cms_layouts", force: :cascade do |t|
|
||||
t.integer "site_id", null: false
|
||||
t.integer "site_id", null: false
|
||||
t.integer "parent_id"
|
||||
t.string "app_layout", limit: 255
|
||||
t.string "label", limit: 255, null: false
|
||||
t.string "identifier", limit: 255, null: false
|
||||
t.string "app_layout"
|
||||
t.string "label", null: false
|
||||
t.string "identifier", null: false
|
||||
t.text "content"
|
||||
t.text "css"
|
||||
t.text "js"
|
||||
t.integer "position", default: 0, null: false
|
||||
t.boolean "is_shared", default: false, null: false
|
||||
t.integer "position", default: 0, null: false
|
||||
t.boolean "is_shared", default: false, null: false
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
@@ -118,18 +118,18 @@ ActiveRecord::Schema.define(version: 20170104035248) do
|
||||
add_index "comfy_cms_layouts", ["site_id", "identifier"], name: "index_comfy_cms_layouts_on_site_id_and_identifier", unique: true, using: :btree
|
||||
|
||||
create_table "comfy_cms_pages", force: :cascade do |t|
|
||||
t.integer "site_id", null: false
|
||||
t.integer "site_id", null: false
|
||||
t.integer "layout_id"
|
||||
t.integer "parent_id"
|
||||
t.integer "target_page_id"
|
||||
t.string "label", limit: 255, null: false
|
||||
t.string "slug", limit: 255
|
||||
t.string "full_path", limit: 255, null: false
|
||||
t.string "label", null: false
|
||||
t.string "slug"
|
||||
t.string "full_path", null: false
|
||||
t.text "content_cache"
|
||||
t.integer "position", default: 0, null: false
|
||||
t.integer "children_count", default: 0, null: false
|
||||
t.boolean "is_published", default: true, null: false
|
||||
t.boolean "is_shared", default: false, null: false
|
||||
t.integer "position", default: 0, null: false
|
||||
t.integer "children_count", default: 0, null: false
|
||||
t.boolean "is_published", default: true, null: false
|
||||
t.boolean "is_shared", default: false, null: false
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
@@ -138,8 +138,8 @@ ActiveRecord::Schema.define(version: 20170104035248) do
|
||||
add_index "comfy_cms_pages", ["site_id", "full_path"], name: "index_comfy_cms_pages_on_site_id_and_full_path", using: :btree
|
||||
|
||||
create_table "comfy_cms_revisions", force: :cascade do |t|
|
||||
t.string "record_type", limit: 255, null: false
|
||||
t.integer "record_id", null: false
|
||||
t.string "record_type", null: false
|
||||
t.integer "record_id", null: false
|
||||
t.text "data"
|
||||
t.datetime "created_at"
|
||||
end
|
||||
@@ -147,24 +147,24 @@ ActiveRecord::Schema.define(version: 20170104035248) do
|
||||
add_index "comfy_cms_revisions", ["record_type", "record_id", "created_at"], name: "index_cms_revisions_on_rtype_and_rid_and_created_at", using: :btree
|
||||
|
||||
create_table "comfy_cms_sites", force: :cascade do |t|
|
||||
t.string "label", limit: 255, null: false
|
||||
t.string "identifier", limit: 255, null: false
|
||||
t.string "hostname", limit: 255, null: false
|
||||
t.string "path", limit: 255
|
||||
t.string "locale", limit: 255, default: "en", null: false
|
||||
t.boolean "is_mirrored", default: false, null: false
|
||||
t.string "label", null: false
|
||||
t.string "identifier", null: false
|
||||
t.string "hostname", null: false
|
||||
t.string "path"
|
||||
t.string "locale", default: "en", null: false
|
||||
t.boolean "is_mirrored", default: false, null: false
|
||||
end
|
||||
|
||||
add_index "comfy_cms_sites", ["hostname"], name: "index_comfy_cms_sites_on_hostname", using: :btree
|
||||
add_index "comfy_cms_sites", ["is_mirrored"], name: "index_comfy_cms_sites_on_is_mirrored", using: :btree
|
||||
|
||||
create_table "comfy_cms_snippets", force: :cascade do |t|
|
||||
t.integer "site_id", null: false
|
||||
t.string "label", limit: 255, null: false
|
||||
t.string "identifier", limit: 255, null: false
|
||||
t.integer "site_id", null: false
|
||||
t.string "label", null: false
|
||||
t.string "identifier", null: false
|
||||
t.text "content"
|
||||
t.integer "position", default: 0, null: false
|
||||
t.boolean "is_shared", default: false, null: false
|
||||
t.integer "position", default: 0, null: false
|
||||
t.boolean "is_shared", default: false, null: false
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
@@ -181,16 +181,16 @@ ActiveRecord::Schema.define(version: 20170104035248) do
|
||||
end
|
||||
|
||||
create_table "crops", force: :cascade do |t|
|
||||
t.string "name", limit: 255, null: false
|
||||
t.string "en_wikipedia_url", limit: 255
|
||||
t.string "name", null: false
|
||||
t.string "en_wikipedia_url"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "slug", limit: 255
|
||||
t.string "slug"
|
||||
t.integer "parent_id"
|
||||
t.integer "plantings_count", default: 0
|
||||
t.integer "plantings_count", default: 0
|
||||
t.integer "creator_id"
|
||||
t.integer "requester_id"
|
||||
t.string "approval_status", limit: 255, default: "approved"
|
||||
t.string "approval_status", default: "approved"
|
||||
t.text "reason_for_rejection"
|
||||
t.text "request_notes"
|
||||
t.text "rejection_notes"
|
||||
@@ -216,29 +216,29 @@ ActiveRecord::Schema.define(version: 20170104035248) do
|
||||
end
|
||||
|
||||
create_table "forums", force: :cascade do |t|
|
||||
t.string "name", limit: 255, null: false
|
||||
t.text "description", null: false
|
||||
t.integer "owner_id", null: false
|
||||
t.string "name", null: false
|
||||
t.text "description", null: false
|
||||
t.integer "owner_id", null: false
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "slug", limit: 255
|
||||
t.string "slug"
|
||||
end
|
||||
|
||||
add_index "forums", ["slug"], name: "index_forums_on_slug", unique: true, using: :btree
|
||||
|
||||
create_table "gardens", force: :cascade do |t|
|
||||
t.string "name", limit: 255, null: false
|
||||
t.string "name", null: false
|
||||
t.integer "owner_id"
|
||||
t.string "slug", limit: 255, null: false
|
||||
t.string "slug", null: false
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.text "description"
|
||||
t.boolean "active", default: true
|
||||
t.string "location", limit: 255
|
||||
t.boolean "active", default: true
|
||||
t.string "location"
|
||||
t.float "latitude"
|
||||
t.float "longitude"
|
||||
t.decimal "area"
|
||||
t.string "area_unit", limit: 255
|
||||
t.string "area_unit"
|
||||
end
|
||||
|
||||
add_index "gardens", ["owner_id"], name: "index_gardens_on_owner_id", using: :btree
|
||||
@@ -252,17 +252,17 @@ ActiveRecord::Schema.define(version: 20170104035248) do
|
||||
add_index "gardens_photos", ["garden_id", "photo_id"], name: "index_gardens_photos_on_garden_id_and_photo_id", using: :btree
|
||||
|
||||
create_table "harvests", force: :cascade do |t|
|
||||
t.integer "crop_id", null: false
|
||||
t.integer "owner_id", null: false
|
||||
t.integer "crop_id", null: false
|
||||
t.integer "owner_id", null: false
|
||||
t.date "harvested_at"
|
||||
t.decimal "quantity"
|
||||
t.string "unit", limit: 255
|
||||
t.string "unit"
|
||||
t.text "description"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "slug", limit: 255
|
||||
t.string "slug"
|
||||
t.decimal "weight_quantity"
|
||||
t.string "weight_unit", limit: 255
|
||||
t.string "weight_unit"
|
||||
t.integer "plant_part_id"
|
||||
t.float "si_weight"
|
||||
t.integer "planting_id"
|
||||
@@ -291,41 +291,46 @@ ActiveRecord::Schema.define(version: 20170104035248) do
|
||||
add_index "likes", ["member_id"], name: "index_likes_on_member_id", using: :btree
|
||||
|
||||
create_table "members", force: :cascade do |t|
|
||||
t.string "email", limit: 255, default: "", null: false
|
||||
t.string "encrypted_password", limit: 255, default: "", null: false
|
||||
t.string "reset_password_token", limit: 255
|
||||
t.string "email", default: "", null: false
|
||||
t.string "encrypted_password", default: "", null: false
|
||||
t.string "reset_password_token"
|
||||
t.datetime "reset_password_sent_at"
|
||||
t.datetime "remember_created_at"
|
||||
t.integer "sign_in_count", default: 0
|
||||
t.integer "sign_in_count", default: 0
|
||||
t.datetime "current_sign_in_at"
|
||||
t.datetime "last_sign_in_at"
|
||||
t.string "current_sign_in_ip", limit: 255
|
||||
t.string "last_sign_in_ip", limit: 255
|
||||
t.string "confirmation_token", limit: 255
|
||||
t.string "current_sign_in_ip"
|
||||
t.string "last_sign_in_ip"
|
||||
t.string "confirmation_token"
|
||||
t.datetime "confirmed_at"
|
||||
t.datetime "confirmation_sent_at"
|
||||
t.string "unconfirmed_email", limit: 255
|
||||
t.integer "failed_attempts", default: 0
|
||||
t.string "unlock_token", limit: 255
|
||||
t.string "unconfirmed_email"
|
||||
t.integer "failed_attempts", default: 0
|
||||
t.string "unlock_token"
|
||||
t.datetime "locked_at"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "login_name", limit: 255
|
||||
t.string "slug", limit: 255
|
||||
t.string "login_name"
|
||||
t.string "slug"
|
||||
t.boolean "tos_agreement"
|
||||
t.boolean "show_email"
|
||||
t.string "location", limit: 255
|
||||
t.string "location"
|
||||
t.float "latitude"
|
||||
t.float "longitude"
|
||||
t.boolean "send_notification_email", default: true
|
||||
t.boolean "send_notification_email", default: true
|
||||
t.text "bio"
|
||||
t.integer "plantings_count"
|
||||
t.boolean "newsletter"
|
||||
t.boolean "send_planting_reminder", default: true
|
||||
t.string "preferred_avatar_uri", limit: 255
|
||||
t.boolean "send_planting_reminder", default: true
|
||||
t.string "preferred_avatar_uri"
|
||||
t.integer "gardens_count"
|
||||
t.integer "harvests_count"
|
||||
t.integer "seeds_count"
|
||||
t.datetime "deleted_at"
|
||||
end
|
||||
|
||||
add_index "members", ["confirmation_token"], name: "index_members_on_confirmation_token", unique: true, using: :btree
|
||||
add_index "members", ["deleted_at"], name: "index_members_on_deleted_at", using: :btree
|
||||
add_index "members", ["email"], name: "index_members_on_email", unique: true, using: :btree
|
||||
add_index "members", ["reset_password_token"], name: "index_members_on_reset_password_token", unique: true, using: :btree
|
||||
add_index "members", ["slug"], name: "index_members_on_slug", unique: true, using: :btree
|
||||
@@ -338,10 +343,10 @@ ActiveRecord::Schema.define(version: 20170104035248) do
|
||||
|
||||
create_table "notifications", force: :cascade do |t|
|
||||
t.integer "sender_id"
|
||||
t.integer "recipient_id", null: false
|
||||
t.string "subject", limit: 255
|
||||
t.integer "recipient_id", null: false
|
||||
t.string "subject"
|
||||
t.text "body"
|
||||
t.boolean "read", default: false
|
||||
t.boolean "read", default: false
|
||||
t.integer "post_id"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
@@ -361,9 +366,9 @@ ActiveRecord::Schema.define(version: 20170104035248) do
|
||||
t.datetime "updated_at"
|
||||
t.datetime "completed_at"
|
||||
t.integer "member_id"
|
||||
t.string "paypal_express_token", limit: 255
|
||||
t.string "paypal_express_payer_id", limit: 255
|
||||
t.string "referral_code", limit: 255
|
||||
t.string "paypal_express_token"
|
||||
t.string "paypal_express_payer_id"
|
||||
t.string "referral_code"
|
||||
end
|
||||
|
||||
create_table "orders_products", id: false, force: :cascade do |t|
|
||||
@@ -372,16 +377,16 @@ ActiveRecord::Schema.define(version: 20170104035248) do
|
||||
end
|
||||
|
||||
create_table "photos", force: :cascade do |t|
|
||||
t.integer "owner_id", null: false
|
||||
t.string "thumbnail_url", limit: 255, null: false
|
||||
t.string "fullsize_url", limit: 255, null: false
|
||||
t.integer "owner_id", null: false
|
||||
t.string "thumbnail_url", null: false
|
||||
t.string "fullsize_url", null: false
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "title", limit: 255, null: false
|
||||
t.string "license_name", limit: 255, null: false
|
||||
t.string "license_url", limit: 255
|
||||
t.string "link_url", limit: 255, null: false
|
||||
t.string "flickr_photo_id", limit: 255
|
||||
t.string "title", null: false
|
||||
t.string "license_name", null: false
|
||||
t.string "license_url"
|
||||
t.string "link_url", null: false
|
||||
t.string "flickr_photo_id"
|
||||
end
|
||||
|
||||
create_table "photos_plantings", id: false, force: :cascade do |t|
|
||||
@@ -397,25 +402,25 @@ ActiveRecord::Schema.define(version: 20170104035248) do
|
||||
add_index "photos_seeds", ["seed_id", "photo_id"], name: "index_photos_seeds_on_seed_id_and_photo_id", using: :btree
|
||||
|
||||
create_table "plant_parts", force: :cascade do |t|
|
||||
t.string "name", limit: 255
|
||||
t.string "name"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "slug", limit: 255
|
||||
t.string "slug"
|
||||
end
|
||||
|
||||
create_table "plantings", force: :cascade do |t|
|
||||
t.integer "garden_id", null: false
|
||||
t.integer "crop_id", null: false
|
||||
t.integer "garden_id", null: false
|
||||
t.integer "crop_id", null: false
|
||||
t.date "planted_at"
|
||||
t.integer "quantity"
|
||||
t.text "description"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "slug", limit: 255
|
||||
t.string "sunniness", limit: 255
|
||||
t.string "planted_from", limit: 255
|
||||
t.string "slug"
|
||||
t.string "sunniness"
|
||||
t.string "planted_from"
|
||||
t.integer "owner_id"
|
||||
t.boolean "finished", default: false
|
||||
t.boolean "finished", default: false
|
||||
t.date "finished_at"
|
||||
t.integer "days_before_maturity"
|
||||
end
|
||||
@@ -423,12 +428,12 @@ ActiveRecord::Schema.define(version: 20170104035248) do
|
||||
add_index "plantings", ["slug"], name: "index_plantings_on_slug", unique: true, using: :btree
|
||||
|
||||
create_table "posts", force: :cascade do |t|
|
||||
t.integer "author_id", null: false
|
||||
t.string "subject", limit: 255, null: false
|
||||
t.text "body", null: false
|
||||
t.integer "author_id", null: false
|
||||
t.string "subject", null: false
|
||||
t.text "body", null: false
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "slug", limit: 255
|
||||
t.string "slug"
|
||||
t.integer "forum_id"
|
||||
end
|
||||
|
||||
@@ -436,9 +441,9 @@ ActiveRecord::Schema.define(version: 20170104035248) do
|
||||
add_index "posts", ["slug"], name: "index_posts_on_slug", unique: true, using: :btree
|
||||
|
||||
create_table "products", force: :cascade do |t|
|
||||
t.string "name", limit: 255, null: false
|
||||
t.text "description", null: false
|
||||
t.integer "min_price", null: false
|
||||
t.string "name", null: false
|
||||
t.text "description", null: false
|
||||
t.integer "min_price", null: false
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.integer "account_type_id"
|
||||
@@ -447,38 +452,38 @@ ActiveRecord::Schema.define(version: 20170104035248) do
|
||||
end
|
||||
|
||||
create_table "roles", force: :cascade do |t|
|
||||
t.string "name", limit: 255, null: false
|
||||
t.string "name", null: false
|
||||
t.text "description"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "slug", limit: 255
|
||||
t.string "slug"
|
||||
end
|
||||
|
||||
add_index "roles", ["slug"], name: "index_roles_on_slug", unique: true, using: :btree
|
||||
|
||||
create_table "scientific_names", force: :cascade do |t|
|
||||
t.string "name", limit: 255, null: false
|
||||
t.integer "crop_id", null: false
|
||||
t.string "name", null: false
|
||||
t.integer "crop_id", null: false
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.integer "creator_id"
|
||||
end
|
||||
|
||||
create_table "seeds", force: :cascade do |t|
|
||||
t.integer "owner_id", null: false
|
||||
t.integer "crop_id", null: false
|
||||
t.integer "owner_id", null: false
|
||||
t.integer "crop_id", null: false
|
||||
t.text "description"
|
||||
t.integer "quantity"
|
||||
t.date "plant_before"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "tradable_to", limit: 255, default: "nowhere"
|
||||
t.string "slug", limit: 255
|
||||
t.string "tradable_to", default: "nowhere"
|
||||
t.string "slug"
|
||||
t.integer "days_until_maturity_min"
|
||||
t.integer "days_until_maturity_max"
|
||||
t.text "organic", default: "unknown"
|
||||
t.text "gmo", default: "unknown"
|
||||
t.text "heirloom", default: "unknown"
|
||||
t.text "organic", default: "unknown"
|
||||
t.text "gmo", default: "unknown"
|
||||
t.text "heirloom", default: "unknown"
|
||||
end
|
||||
|
||||
add_index "seeds", ["slug"], name: "index_seeds_on_slug", unique: true, using: :btree
|
||||
|
||||
@@ -31,7 +31,7 @@ def load_crops
|
||||
Dir.glob("#{source_path}/crops*.csv").each do |crop_file|
|
||||
puts "Loading crops from #{crop_file}..."
|
||||
CSV.foreach(crop_file) do |row|
|
||||
Crop.create_from_csv(row)
|
||||
CsvImporter.new.import_crop(row)
|
||||
end
|
||||
end
|
||||
puts "Finished loading crops"
|
||||
@@ -171,7 +171,7 @@ def load_products
|
||||
Product.create!(
|
||||
name: "Seed account",
|
||||
description: "Paid account, in perpetuity",
|
||||
min_price: 15000,
|
||||
min_price: 15_000,
|
||||
account_type_id: @seed_account.id
|
||||
)
|
||||
end
|
||||
|
||||
@@ -6,7 +6,7 @@ module Geocodable
|
||||
private
|
||||
|
||||
def empty_unwanted_geocodes
|
||||
return unless self.location.blank?
|
||||
return unless location.blank?
|
||||
self.latitude = nil
|
||||
self.longitude = nil
|
||||
end
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user