Compare commits

..
Author SHA1 Message Date
dependabot[bot] 1d7abb8dc2 Bump json from 2.21.1 to 2.21.2 (#4730)
Bumps [json](https://github.com/ruby/json) from 2.21.1 to 2.21.2.
- [Release notes](https://github.com/ruby/json/releases)
- [Changelog](https://github.com/ruby/json/blob/master/CHANGES.md)
- [Commits](https://github.com/ruby/json/compare/v2.21.1...v2.21.2)

---
updated-dependencies:
- dependency-name: json
  dependency-version: 2.21.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-09 22:31:00 +09:30
dependabot[bot] 24e4d96395 Bump js-yaml from 4.3.0 to 4.3.1 (#4729)
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.3.0 to 4.3.1.
- [Changelog](https://github.com/nodeca/js-yaml/blob/4.3.1/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/4.3.0...4.3.1)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 4.3.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-08 13:33:52 +09:30
dependabot[bot] a95eb6ec63 Bump fast-uri from 3.1.4 to 3.1.5 (#4727)
Bumps [fast-uri](https://github.com/fastify/fast-uri) from 3.1.4 to 3.1.5.
- [Release notes](https://github.com/fastify/fast-uri/releases)
- [Commits](https://github.com/fastify/fast-uri/compare/v3.1.4...v3.1.5)

---
updated-dependencies:
- dependency-name: fast-uri
  dependency-version: 3.1.5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-07 21:22:32 +09:30
dependabot[bot] e6292689c7 Bump dalli from 5.0.5 to 5.0.6 (#4728)
Bumps [dalli](https://github.com/petergoldstein/dalli) from 5.0.5 to 5.0.6.
- [Release notes](https://github.com/petergoldstein/dalli/releases)
- [Changelog](https://github.com/petergoldstein/dalli/blob/main/CHANGELOG.md)
- [Commits](https://github.com/petergoldstein/dalli/compare/v5.0.5...v5.0.6)

---
updated-dependencies:
- dependency-name: dalli
  dependency-version: 5.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-07 21:22:12 +09:30
dependabot[bot] cb1eeb677b Bump scout_apm from 6.2.0 to 6.2.1 (#4725)
Bumps [scout_apm](https://github.com/scoutapp/scout_apm_ruby) from 6.2.0 to 6.2.1.
- [Changelog](https://github.com/scoutapp/scout_apm_ruby/blob/master/CHANGELOG.markdown)
- [Commits](https://github.com/scoutapp/scout_apm_ruby/compare/v6.2.0...v6.2.1)

---
updated-dependencies:
- dependency-name: scout_apm
  dependency-version: 6.2.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-05 18:41:52 +09:30
dependabot[bot] dc76c546f5 Bump oj from 3.17.4 to 3.17.5 (#4726)
Bumps [oj](https://github.com/ohler55/oj) from 3.17.4 to 3.17.5.
- [Release notes](https://github.com/ohler55/oj/releases)
- [Changelog](https://github.com/ohler55/oj/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/ohler55/oj/compare/v3.17.4...v3.17.5)

---
updated-dependencies:
- dependency-name: oj
  dependency-version: 3.17.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-05 18:41:37 +09:30
dependabot[bot] 8cba6c35b8 Bump ip-address from 10.2.0 to 10.4.0 (#4723)
Bumps [ip-address](https://github.com/beaugunderson/ip-address) from 10.2.0 to 10.4.0.
- [Release notes](https://github.com/beaugunderson/ip-address/releases)
- [Commits](https://github.com/beaugunderson/ip-address/compare/v10.2.0...v10.4.0)

---
updated-dependencies:
- dependency-name: ip-address
  dependency-version: 10.4.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-05 18:41:24 +09:30
dependabot[bot] 4d3464f647 Bump icalendar from 2.12.3 to 2.12.4 (#4724)
Bumps [icalendar](https://github.com/icalendar/icalendar) from 2.12.3 to 2.12.4.
- [Changelog](https://github.com/icalendar/icalendar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/icalendar/icalendar/compare/v2.12.3...v2.12.4)

---
updated-dependencies:
- dependency-name: icalendar
  dependency-version: 2.12.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-04 19:11:50 +09:30
dependabot[bot] 3d15439af7 Bump aws-sdk-s3 from 1.228.1 to 1.228.2 (#4721)
Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.228.1 to 1.228.2.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-version: 1.228.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-03 22:49:12 +09:30
dependabot[bot] 53201d629f Bump docker/login-action from 4.5.2 to 4.6.0 (#4722)
Bumps [docker/login-action](https://github.com/docker/login-action) from 4.5.2 to 4.6.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v4.5.2...v4.6.0)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: 4.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-03 19:33:00 +09:30
dependabot[bot] 9385189ff7 Bump docker/login-action from 4 to 4.5.2 (#4720)
Bumps [docker/login-action](https://github.com/docker/login-action) from 4 to 4.5.2.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v4...v4.5.2)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: 4.5.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-31 17:20:16 +09:30
dependabot[bot] ff2e917980 Bump msgpack from 1.8.3 to 1.8.4 (#4717)
Bumps [msgpack](https://github.com/msgpack/msgpack-ruby) from 1.8.3 to 1.8.4.
- [Changelog](https://github.com/msgpack/msgpack-ruby/blob/master/ChangeLog)
- [Commits](https://github.com/msgpack/msgpack-ruby/compare/v1.8.3...v1.8.4)

---
updated-dependencies:
- dependency-name: msgpack
  dependency-version: 1.8.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-30 22:31:07 +09:30
dependabot[bot] 3b711f05a4 Bump sitemap_generator from 7.1.0 to 7.1.1 (#4715)
Bumps [sitemap_generator](https://github.com/kjvarga/sitemap_generator) from 7.1.0 to 7.1.1.
- [Changelog](https://github.com/kjvarga/sitemap_generator/blob/master/CHANGES.md)
- [Commits](https://github.com/kjvarga/sitemap_generator/compare/v7.1.0...v7.1.1)

---
updated-dependencies:
- dependency-name: sitemap_generator
  dependency-version: 7.1.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-30 21:09:59 +09:30
dependabot[bot] 88bf539b1c Bump rails from 8.0.5 to 8.0.5.1 (#4719)
Bumps [rails](https://github.com/rails/rails) from 8.0.5 to 8.0.5.1.
- [Release notes](https://github.com/rails/rails/releases)
- [Commits](https://github.com/rails/rails/compare/v8.0.5...v8.0.5.1)

---
updated-dependencies:
- dependency-name: rails
  dependency-version: 8.0.5.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-30 17:55:13 +09:30
dependabot[bot] 0b4915ec13 Bump haml from 7.2.0 to 7.2.2 (#4716)
Bumps [haml](https://github.com/haml/haml) from 7.2.0 to 7.2.2.
- [Release notes](https://github.com/haml/haml/releases)
- [Changelog](https://github.com/haml/haml/blob/main/CHANGELOG.md)
- [Commits](https://github.com/haml/haml/compare/v7.2.0...v7.2.2)

---
updated-dependencies:
- dependency-name: haml
  dependency-version: 7.2.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-29 18:16:34 +09:30
dependabot[bot] 6d8038d406 Bump actions/setup-node from 6 to 7 (#4703)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 6 to 7.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-26 14:27:48 +09:30
dependabot[bot] 479f5be290 Bump js-yaml from 4.2.0 to 4.3.0 (#4713)
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.2.0 to 4.3.0.
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/4.2.0...4.3.0)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 4.3.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-25 01:29:54 +09:30
dependabot[bot] 401d34d59a Bump ws from 8.20.0 to 8.21.1 (#4699)
Bumps [ws](https://github.com/websockets/ws) from 8.20.0 to 8.21.1.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/8.20.0...8.21.1)

---
updated-dependencies:
- dependency-name: ws
  dependency-version: 8.21.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-24 21:41:14 +09:30
dependabot[bot]andDaniel O'Connor 8c5e2b9e4d Bump systeminformation from 5.31.6 to 5.31.17 (#4706)
Bumps [systeminformation](https://github.com/sebhildebrandt/systeminformation) from 5.31.6 to 5.31.17.
- [Release notes](https://github.com/sebhildebrandt/systeminformation/releases)
- [Changelog](https://github.com/sebhildebrandt/systeminformation/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sebhildebrandt/systeminformation/compare/v5.31.6...v5.31.17)

---
updated-dependencies:
- dependency-name: systeminformation
  dependency-version: 5.31.17
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Daniel O'Connor <daniel.oconnor@gmail.com>
2026-07-24 21:29:38 +09:30
dependabot[bot] 7cb32f9620 Bump rails-html-sanitizer from 1.7.0 to 1.7.1 (#4712)
Bumps [rails-html-sanitizer](https://github.com/rails/rails-html-sanitizer) from 1.7.0 to 1.7.1.
- [Release notes](https://github.com/rails/rails-html-sanitizer/releases)
- [Changelog](https://github.com/rails/rails-html-sanitizer/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rails/rails-html-sanitizer/compare/v1.7.0...v1.7.1)

---
updated-dependencies:
- dependency-name: rails-html-sanitizer
  dependency-version: 1.7.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-24 21:28:07 +09:30
dependabot[bot] 2ba21529af Bump aws-sdk-s3 from 1.228.0 to 1.228.1 (#4711)
Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.228.0 to 1.228.1.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-version: 1.228.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-24 21:27:42 +09:30
dependabot[bot] fe48c2f6d1 Bump fast-uri from 3.1.2 to 3.1.4 (#4714)
Bumps [fast-uri](https://github.com/fastify/fast-uri) from 3.1.2 to 3.1.4.
- [Release notes](https://github.com/fastify/fast-uri/releases)
- [Commits](https://github.com/fastify/fast-uri/compare/v3.1.2...v3.1.4)

---
updated-dependencies:
- dependency-name: fast-uri
  dependency-version: 3.1.4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-24 21:24:43 +09:30
dependabot[bot] 514d590148 Bump websocket-driver from 0.8.1 to 0.8.2 (#4710)
Bumps [websocket-driver](https://github.com/faye/websocket-driver-ruby) from 0.8.1 to 0.8.2.
- [Changelog](https://github.com/faye/websocket-driver-ruby/blob/main/CHANGELOG.md)
- [Commits](https://github.com/faye/websocket-driver-ruby/compare/0.8.1...0.8.2)

---
updated-dependencies:
- dependency-name: websocket-driver
  dependency-version: 0.8.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-24 18:31:20 +09:30
dependabot[bot] 32fa1acc84 Bump aws-sdk-s3 from 1.227.0 to 1.228.0 (#4709)
Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.227.0 to 1.228.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-version: 1.228.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-18 00:13:52 +09:30
dependabot[bot] 8e9f891819 Bump percy-capybara from 5.0.0 to 5.0.1 (#4704)
Bumps [percy-capybara](https://github.com/percy/percy-capybara) from 5.0.0 to 5.0.1.
- [Release notes](https://github.com/percy/percy-capybara/releases)
- [Commits](https://github.com/percy/percy-capybara/compare/v5.0.0...5.0.1)

---
updated-dependencies:
- dependency-name: percy-capybara
  dependency-version: 5.0.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-17 00:10:46 +09:30
dependabot[bot] 33ecb69a45 Bump websocket-driver from 0.8.0 to 0.8.1 (#4707)
Bumps [websocket-driver](https://github.com/faye/websocket-driver-ruby) from 0.8.0 to 0.8.1.
- [Changelog](https://github.com/faye/websocket-driver-ruby/blob/main/CHANGELOG.md)
- [Commits](https://github.com/faye/websocket-driver-ruby/compare/0.8.0...0.8.1)

---
updated-dependencies:
- dependency-name: websocket-driver
  dependency-version: 0.8.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-17 00:10:07 +09:30
dependabot[bot] 217638854a Bump loofah from 2.25.1 to 2.25.2 (#4708)
Bumps [loofah](https://github.com/flavorjones/loofah) from 2.25.1 to 2.25.2.
- [Release notes](https://github.com/flavorjones/loofah/releases)
- [Changelog](https://github.com/flavorjones/loofah/blob/main/CHANGELOG.md)
- [Commits](https://github.com/flavorjones/loofah/compare/v2.25.1...v2.25.2)

---
updated-dependencies:
- dependency-name: loofah
  dependency-version: 2.25.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-17 00:09:37 +09:30
dependabot[bot] 659df0fc25 Bump oj from 3.17.3 to 3.17.4 (#4705)
Bumps [oj](https://github.com/ohler55/oj) from 3.17.3 to 3.17.4.
- [Release notes](https://github.com/ohler55/oj/releases)
- [Changelog](https://github.com/ohler55/oj/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/ohler55/oj/compare/v3.17.3...v3.17.4)

---
updated-dependencies:
- dependency-name: oj
  dependency-version: 3.17.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-17 00:08:21 +09:30
dependabot[bot] 98b79d6725 Bump haml_lint from 0.75.0 to 0.76.0 (#4702)
Bumps [haml_lint](https://github.com/sds/haml-lint) from 0.75.0 to 0.76.0.
- [Release notes](https://github.com/sds/haml-lint/releases)
- [Changelog](https://github.com/sds/haml-lint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sds/haml-lint/compare/v0.75.0...v0.76.0)

---
updated-dependencies:
- dependency-name: haml_lint
  dependency-version: 0.76.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-14 18:40:56 +09:30
dependabot[bot] d3198e283a Bump haml-rails from 3.0.0 to 3.1.0 (#4697)
Bumps [haml-rails](https://github.com/haml/haml-rails) from 3.0.0 to 3.1.0.
- [Changelog](https://github.com/haml/haml-rails/blob/master/CHANGELOG.md)
- [Commits](https://github.com/haml/haml-rails/compare/v3.0.0...v3.1.0)

---
updated-dependencies:
- dependency-name: haml-rails
  dependency-version: 3.1.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-13 22:30:41 +09:30
dependabot[bot] 6a318e45e9 Bump rubocop-rails from 2.35.5 to 2.36.0 (#4700)
Bumps [rubocop-rails](https://github.com/rubocop/rubocop-rails) from 2.35.5 to 2.36.0.
- [Release notes](https://github.com/rubocop/rubocop-rails/releases)
- [Changelog](https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop-rails/compare/v2.35.5...v2.36.0)

---
updated-dependencies:
- dependency-name: rubocop-rails
  dependency-version: 2.36.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-13 18:43:53 +09:30
dependabot[bot] 28d75ca782 Bump selenium-webdriver from 4.45.0 to 4.46.0 (#4701)
Bumps [selenium-webdriver](https://github.com/SeleniumHQ/selenium) from 4.45.0 to 4.46.0.
- [Release notes](https://github.com/SeleniumHQ/selenium/releases)
- [Changelog](https://github.com/SeleniumHQ/selenium/blob/trunk/rb/CHANGES)
- [Commits](https://github.com/SeleniumHQ/selenium/compare/selenium-4.45.0...selenium-4.46.0)

---
updated-dependencies:
- dependency-name: selenium-webdriver
  dependency-version: 4.46.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-13 18:43:40 +09:30
dependabot[bot] ab2aa2d60b Bump terser from 1.2.7 to 1.2.8 (#4696)
Bumps [terser](https://github.com/ahorek/terser-ruby) from 1.2.7 to 1.2.8.
- [Release notes](https://github.com/ahorek/terser-ruby/releases)
- [Changelog](https://github.com/ahorek/terser-ruby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ahorek/terser-ruby/compare/1.2.7...1.2.8)

---
updated-dependencies:
- dependency-name: terser
  dependency-version: 1.2.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-12 13:47:22 +09:30
dependabot[bot] a9cab1a366 Bump aws-sdk-s3 from 1.226.0 to 1.227.0 (#4698)
Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.226.0 to 1.227.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-version: 1.227.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-12 13:47:03 +09:30
Daniel O'Connor 0215c2baee Merge branch 'mainline' into dev 2026-07-10 19:17:42 +09:30
Cesy f41d0e0829 Merge pull request #4695 from Growstuff/dependabot/bundler/rubocop-1.88.2 2026-07-08 14:20:17 +01:00
dependabot[bot] 81139a5d8e Bump rubocop from 1.88.1 to 1.88.2
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.88.1 to 1.88.2.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.88.1...v1.88.2)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-version: 1.88.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-08 07:04:56 +00:00
dependabot[bot] 2805df545a Bump haml_lint from 0.74.0 to 0.75.0 (#4694)
Bumps [haml_lint](https://github.com/sds/haml-lint) from 0.74.0 to 0.75.0.
- [Release notes](https://github.com/sds/haml-lint/releases)
- [Changelog](https://github.com/sds/haml-lint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sds/haml-lint/compare/v0.74.0...v0.75.0)

---
updated-dependencies:
- dependency-name: haml_lint
  dependency-version: 0.75.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-07 18:03:48 +09:30
Cesy 0dc05fa541 Merge pull request #4693 from Growstuff/dependabot/bundler/sitemap_generator-7.1.0 2026-07-06 18:32:07 +01:00
dependabot[bot] a7fe8157d0 Bump sitemap_generator from 7.0.3 to 7.1.0
Bumps [sitemap_generator](https://github.com/kjvarga/sitemap_generator) from 7.0.3 to 7.1.0.
- [Changelog](https://github.com/kjvarga/sitemap_generator/blob/master/CHANGES.md)
- [Commits](https://github.com/kjvarga/sitemap_generator/compare/v7.0.3...v7.1.0)

---
updated-dependencies:
- dependency-name: sitemap_generator
  dependency-version: 7.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-06 07:04:57 +00:00
dependabot[bot] 7bb1452239 Bump sitemap_generator from 7.0.2 to 7.0.3 (#4692)
Bumps [sitemap_generator](https://github.com/kjvarga/sitemap_generator) from 7.0.2 to 7.0.3.
- [Changelog](https://github.com/kjvarga/sitemap_generator/blob/master/CHANGES.md)
- [Commits](https://github.com/kjvarga/sitemap_generator/compare/v7.0.2...v7.0.3)

---
updated-dependencies:
- dependency-name: sitemap_generator
  dependency-version: 7.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-04 15:38:57 +09:30
dependabot[bot] cb838d6db5 Bump rubocop from 1.88.0 to 1.88.1 (#4691)
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.88.0 to 1.88.1.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.88.0...v1.88.1)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-version: 1.88.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-02 17:48:40 +09:30
Cesy 99c2439411 Merge pull request #4690 from Growstuff/dependabot/bundler/carrierwave-3.1.3 2026-07-01 12:32:39 +01:00
dependabot[bot] 83ff017d88 Bump carrierwave from 3.0.7 to 3.1.3
Bumps [carrierwave](https://github.com/carrierwaveuploader/carrierwave) from 3.0.7 to 3.1.3.
- [Release notes](https://github.com/carrierwaveuploader/carrierwave/releases)
- [Changelog](https://github.com/carrierwaveuploader/carrierwave/blob/master/CHANGELOG.md)
- [Commits](https://github.com/carrierwaveuploader/carrierwave/compare/v3.0.7...v3.1.3)

---
updated-dependencies:
- dependency-name: carrierwave
  dependency-version: 3.1.3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-01 09:03:40 +00:00
Cesy fe4e7050fa Merge pull request #4689 from Growstuff/dependabot/bundler/sitemap_generator-7.0.2
Bump sitemap_generator from 6.3.0 to 7.0.2
2026-07-01 10:02:42 +01:00
dependabot[bot] ad08219217 Bump sitemap_generator from 6.3.0 to 7.0.2
Bumps [sitemap_generator](https://github.com/kjvarga/sitemap_generator) from 6.3.0 to 7.0.2.
- [Changelog](https://github.com/kjvarga/sitemap_generator/blob/master/CHANGES.md)
- [Commits](https://github.com/kjvarga/sitemap_generator/compare/v6.3.0...v7.0.2)

---
updated-dependencies:
- dependency-name: sitemap_generator
  dependency-version: 7.0.2
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-30 07:02:37 +00:00
Daniel O'Connor 67da779381 Block Semrush crawler in Rack Attack initializer
Added a blocklist entry for the Semrush crawler to prevent abusive requests.
2026-06-25 21:11:43 +09:30
c9b8c54b81 Fix plantings ICS feed regression and enable request spec (#4687)
* Fix plantings ICS feed regression and enable request spec

- Update `app/views/plantings/index.ics.erb` to use ActiveRecord method calls instead of hash bracket access.
- Enable `spec/requests/plantings_spec.rb` and update it to account for mirrored harvest events.
- Add `config/initializers/faraday_patch.rb` to fix Searchkick/Faraday 2.x compatibility issues.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Delete config/initializers/faraday_patch.rb

* Apply suggestion from @CloCkWeRX

* Apply suggestions from code review

Co-authored-by: Daniel O'Connor <daniel.oconnor@gmail.com>

* Apply suggestion from @CloCkWeRX

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-06-24 23:18:24 +09:30
fa7f460510 Refactor Plantings to remove Elasticsearch dependency (#4686)
* Refactor Plantings to remove Elasticsearch dependency

This commit refactors the Plantings controller, model, and views to use
ActiveRecord instead of Searchkick/Elasticsearch.

Key changes:
- Refactored `PlantingsController#index` to use an ActiveRecord-based
  `plantings` method.
- Moved `homepage_records` logic from `SearchPlantings` concern to the
  `Planting` model using ActiveRecord scopes.
- Removed `SearchPlantings` concern and deleted the file.
- Updated `home/_plantings.html.haml` and `plantings/index.rss.haml` to
  use dot notation for `Planting` object attributes.
- Updated specs to remove Searchkick-related setup and assertions.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Fix Planting.reindex

* Fix test

* Mark test pending

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-06-24 22:26:49 +09:30
6e7cf1c813 Refactor Seeds to remove Elasticsearch dependency (#4684)
* Refactor Seeds to remove Elasticsearch dependency

This commit refactors the `SeedsController` and `Seed` model to remove
dependency on Elasticsearch and Searchkick.

Key changes:
- Removed `SearchSeeds` concern from the `Seed` model.
- Reimplemented `Seed.homepage_records` using ActiveRecord.
- Refactored `SeedsController#index` to use ActiveRecord for filtering,
  eager loading, and pagination.
- Deleted `app/models/concerns/search_seeds.rb`.
- Updated relevant specs to remove Searchkick-specific tags and setup.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Remove Seed.reindex

* Remove trait

* Fix tests

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-06-24 21:54:43 +09:30
Daniel O'Connor 3edd2510d8 Merge pull request #4683 from Growstuff/refactor-harvests-remove-elasticsearch-14630838429921835504
Refactor harvests to remove Elasticsearch
2026-06-24 20:26:22 +09:30
Daniel O'Connor 0c7f270ce9 Merge pull request #4682 from Growstuff/dependabot/bundler/axe-core-rspec-4.12.0
Bump axe-core-rspec from 4.11.3 to 4.12.0
2026-06-24 18:55:38 +09:30
Cesy 169ad8125b Merge pull request #4680 from Growstuff/dependabot/github_actions/actions/cache-6
Bump actions/cache from 5 to 6
2026-06-24 09:43:59 +01:00
dependabot[bot] 43a7495d65 Bump axe-core-rspec from 4.11.3 to 4.12.0
Bumps [axe-core-rspec](https://github.com/dequelabs/axe-core-gems) from 4.11.3 to 4.12.0.
- [Release notes](https://github.com/dequelabs/axe-core-gems/releases)
- [Changelog](https://github.com/dequelabs/axe-core-gems/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/dequelabs/axe-core-gems/compare/v4.11.3...v4.12.0)

---
updated-dependencies:
- dependency-name: axe-core-rspec
  dependency-version: 4.12.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-24 07:07:13 +00:00
dependabot[bot] 68d0eb572c Bump actions/cache from 5 to 6
Bumps [actions/cache](https://github.com/actions/cache) from 5 to 6.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-24 07:02:40 +00:00
Daniel O'Connor 910e9483d5 Merge pull request #4679 from Growstuff/dev
release87
2026-06-24 01:47:22 +09:30
Daniel O'Connor c0eb49aebb Merge pull request #4678 from Growstuff/fix-photo-reindex-error-4629481995101950332
Fix NoMethodError: undefined method 'reindex' for class Photo in specs
2026-06-24 01:45:40 +09:30
google-labs-jules[bot]andCloCkWeRX abd5df606e Fix Photo.reindex errors in specs and controller
- Remove `Photo.reindex` calls from `spec/spec_helper.rb` and feature specs.
- Modify `LikesController` to conditionally call `reindex` only if the likeable object responds to it, preventing `NoMethodError` for non-indexed models like `Photo`.
- Remove unnecessary `:reindex` trait from photo factory call in `likeable_spec.rb`.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-06-23 14:22:47 +00:00
google-labs-jules[bot]andCloCkWeRX d6b9ededec Remove Photo.reindex calls from test suite
The Photo model is no longer using Searchkick/Elasticsearch, so calling
`Photo.reindex` causes a NoMethodError. This commit removes these calls
from `spec/spec_helper.rb` and feature specs, and removes the unused
`:reindex` trait from the photo factory call in `likeable_spec.rb`.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-06-23 14:00:08 +00:00
Daniel O'Connor 118e50ccfc Merge pull request #4677 from Growstuff/fix-docker-build-missing-ruby-version-8858247702805966576
Fix Docker build by copying .ruby-version before bundle install
2026-06-23 22:50:58 +09:30
google-labs-jules[bot]andCloCkWeRX 75fa206ff7 Copy .ruby-version before bundle install in Dockerfile
The Gemfile reads the .ruby-version file to determine the Ruby version.
If this file is not present during `bundle install`, the build fails.
This change ensures that .ruby-version is copied along with the Gemfile
and Gemfile.lock.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-06-23 13:06:53 +00:00
Daniel O'Connor 452b0c4eba Merge pull request #4674 from Growstuff/security-2026-06-23
Security fixes
2026-06-23 22:34:46 +09:30
Daniel O'Connor 7dd78359aa Merge pull request #4676 from Growstuff/dependabot/bundler/net-imap-0.6.4.1
Bump net-imap from 0.6.4 to 0.6.4.1
2026-06-23 22:34:33 +09:30
Daniel O'Connor 3af51f18dc Merge pull request #4675 from Growstuff/convert-photos-to-sql-4865766049333411151
Convert Photos controller to avoid elasticsearch
2026-06-23 21:51:39 +09:30
Daniel O'Connor b2248ee4ca Merge branch 'dev' into convert-photos-to-sql-4865766049333411151 2026-06-23 21:47:45 +09:30
dependabot[bot] bda4d98a1b Bump net-imap from 0.6.4 to 0.6.4.1
Bumps [net-imap](https://github.com/ruby/net-imap) from 0.6.4 to 0.6.4.1.
- [Release notes](https://github.com/ruby/net-imap/releases)
- [Commits](https://github.com/ruby/net-imap/compare/v0.6.4...v0.6.4.1)

---
updated-dependencies:
- dependency-name: net-imap
  dependency-version: 0.6.4.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-23 12:17:25 +00:00
google-labs-jules[bot]andCloCkWeRX 97e236f7e8 Convert Photos controller to plain SQL queries
- Refactored `PhotosController#index` to use ActiveRecord queries instead of Searchkick/Elasticsearch.
- Handled filtering by crop and planting via associations.
- Added eager loading for the photo owner to prevent N+1 queries.
- Decoupled the `Photo` model from Elasticsearch by removing the `SearchPhotos` concern.
- Deleted `app/models/concerns/search_photos.rb`.
- Updated controller and model specs to use standard ActiveRecord expectations.
- Cleaned up the photo factory by removing the now-obsolete `:reindex` trait.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-06-23 12:16:50 +00:00
Daniel O'Connor 92faca98fa Security fixes 2026-06-23 12:14:57 +00:00
Daniel O'Connor a9179618f5 Merge pull request #4673 from Growstuff/heroku-26
Heroku 26
2026-06-23 21:43:48 +09:30
Daniel O'Connor 217b3953ac Update docker rails version 2026-06-23 11:59:57 +00:00
Daniel O'Connor 9fe2294c7b Update to heroku-26 2026-06-23 11:54:38 +00:00
e9bbea7dfd Release 86 (#4671)
* Refactor Activity model to remove Elasticsearch integration (#4576)

* Refactor Activity model to remove Elasticsearch integration

- Removed `SearchActivities` concern and Searchkick from `Activity` model.
- Implemented `Activity.homepage_records` using ActiveRecord with `DISTINCT ON` for PostgreSQL.
- Updated `ActivitiesController#index` to use ActiveRecord queries with eager loading and pagination.
- Added `active` scope to `Activity`.
- Added unit tests for `Activity` model.
- Deleted `app/models/concerns/search_activities.rb`.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Fix NoMethodError: undefined method 'reindex' for class Activity

- Removed all calls to `Activity.reindex` in migrations, rake tasks, and spec helpers.
- These were causing failures after the removal of Searchkick from the Activity model.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Fix ambiguous column id in homepage_records query

- Updated `Activity.homepage_records` to use `activities.id` instead of `id` in the subquery.
- This resolves the `PG::AmbiguousColumn: ERROR: column reference "id" is ambiguous` error.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Fix ambiguous created_at in homepage_records query

- Use `unscoped` in the subquery for `Activity.homepage_records` to bypass the default scope from `Ownable` concern.
- This prevents the join with the `members` table in the subquery, which was causing `PG::AmbiguousColumn: ERROR: column reference "created_at" is ambiguous`.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Complete refactoring of Activity model to remove Elasticsearch

- Removed SearchActivities concern and searchkick integration.
- Updated ActivitiesController#index to use ActiveRecord queries.
- Implemented performant Activity.homepage_records using DISTINCT ON (PostgreSQL).
- Added Activity.active scope.
- Added no-op Activity.reindex (class and instance methods) for backward compatibility.
- Cleaned up leftover reindex calls in rake tasks, migrations, and spec helpers.
- Added unit tests for new Activity model logic.
- Updated factories to include no-op reindex traits.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Less eager loading

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>

* Add funding information

* Rename FUNDING.yml to .github/FUNDING.yml

* Remove deprecated config.read_encrypted_secrets from production.rb (#4603)

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>

* Add weekly harvest reminder emails and scheduled task

- Added `send_harvest_reminder` preference to Member model and settings UI.
- Implemented `harvest_in_next_week?` in PredictHarvest concern.
- Created `harvest_reminder` email with localized templates.
- Added `growstuff:send_harvest_reminders` Rake task to run weekly.
- Refactored existing and new reminder tasks to use `deliver_later` for scalability.
- Added unit tests for prediction logic and mailer.
- Fixed a bug in the existing planting reminder task where it was using an uninitialized constant `Notifier`.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Bump rubocop-capybara from 2.22.1 to 2.23.0

Bumps [rubocop-capybara](https://github.com/rubocop/rubocop-capybara) from 2.22.1 to 2.23.0.
- [Release notes](https://github.com/rubocop/rubocop-capybara/releases)
- [Changelog](https://github.com/rubocop/rubocop-capybara/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop-capybara/compare/v2.22.1...v2.23.0)

---
updated-dependencies:
- dependency-name: rubocop-capybara
  dependency-version: 2.23.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump axe-core-rspec from 4.11.2 to 4.11.3

Bumps [axe-core-rspec](https://github.com/dequelabs/axe-core-gems) from 4.11.2 to 4.11.3.
- [Release notes](https://github.com/dequelabs/axe-core-gems/releases)
- [Changelog](https://github.com/dequelabs/axe-core-gems/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/dequelabs/axe-core-gems/commits)

---
updated-dependencies:
- dependency-name: axe-core-rspec
  dependency-version: 4.11.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Fix crash during CSV export of harvests and seeds

When using Searchkick with `load: false`, search results are returned
as HashResponse objects which do not support model associations or
standard Rails URL helpers that expect model instances.

This commit updates HarvestsController and SeedsController to
conditionally load ActiveRecord objects when CSV format is requested,
ensuring that the export templates can access the necessary associations.
Similar logic was also applied to CropsController.

Additionally, a typo in the Crops CSV shaper was fixed.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Associate post with crop from crop show page

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Fix seeds_count to correctly reference size

* Change plant_before formatting method to to_fs

* Merge pull request #4612 from Growstuff/fix-crops-csv-export-11894001552728801282

Fix ArgumentError in Crops CSV export

* Fix crops csv export 11894001552728801282 (#4613)

* Fix ArgumentError in Crops CSV export

This commit fixes a crash when exporting crops to CSV, caused by
accessing ActiveRecord methods and associations on Searchkick
HashWrapper objects.

Changes:
- In CropsController#index, use `load: true` (with preloaded
  associations) when the request format is CSV or RSS.
- In app/views/crops/index.csv.shaper, use individual `csv.cell` calls
  instead of `csv.cells` to correctly handle Searchkick results and
  explicitly access attributes.
- Added a controller test to verify CSV export functionality.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Mark test pending

* Skip creator

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>

* Namespaces no longer supported in sidekiq

* Update to 3.4.9

* Merge pull request #4616 from Growstuff/rubocop-upgrade

Update rubocop_todo.yml

* Upgrade ERB

* Merge pull request #4575 from Growstuff/memoize-unread-count

Memoize unread messages count

* Prompt for updated planting rating when harvesting (#4608)

* Update planting rating when recording a harvest

- Added virtual attribute `overall_rating` to `Harvest` model.
- Updated `HarvestsController` to permit `overall_rating` and synchronize it to the associated `Planting`.
- Added a rating range field (1-5) to the harvest form.
- Added controller tests to verify that the planting rating is updated.
- Refined feature tests for harvesting.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* I have updated the system to allow for recording a planting rating when a harvest is logged. Here is a summary of the changes:

- Added a virtual attribute `overall_rating` to the `Harvest` model.
- Updated `HarvestsController` to permit `overall_rating` and synchronize it to the associated `Planting`.
- Added a rating range field (1-5) to the harvest form.
- Added controller tests to verify that the planting rating is updated correctly.
- Updated feature tests to ensure the harvest form functions as expected.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Update database.yml

* Apply suggestions from code review

Co-authored-by: Daniel O'Connor <daniel.oconnor@gmail.com>

* Adjust wording

* Change harvest modal

* Fix tests

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>

* Improve read performance with caching and memoization (#4572)

* Improve read performance with caching and memoization

- Memoize `Crop#all_companions` and `Member#unread_count` in models
- Implement instance-level memoization in `CropsHelper#crop_or_parent`
- Add Rails caching for expensive aggregate queries in `Charts::CropsController`
- Add fragment caching for high-impact sections on the crop show page

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Fix header spec failure due to memoized unread_count

- Reset `@unread_count` in `spec/views/layouts/_header_spec.rb` to ensure the updated notification count is rendered correctly.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>

* Replace Sidekiq with Solid Queue (#4619)

* Replace Sidekiq with Solid Queue

This commit transitions the background job processing from Sidekiq to
Solid Queue.

Changes:
- Replaced `sidekiq` gem with `solid_queue` in Gemfile.
- Updated `development.rb` and `production.rb` to use `:solid_queue` as
  the queue adapter.
- Added Solid Queue database tables via a new migration.
- Configured Solid Queue in `config/queue.yml` and `config/recurring.yml`.
- Integrated Solid Queue supervisor as a Puma plugin in `config/puma.rb`.
- Removed separate worker process from `Procfile`.
- Removed Sidekiq-specific configuration files.
- Updated Gemfile.lock to support both `ruby` and `x86_64-linux` platforms.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Fix regression in gemfiles

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>

* Add crops search API endpoint (#4622)

* Add crops search API endpoint

- Added GET /api/v1/crops/search endpoint.
- Updated CropSearchService to support additional search options.
- Manually updated Swagger documentation in swagger/v1/swagger.json.
- Added request specs to verify the new endpoint.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Add crops search API endpoint

- Added GET /api/v1/crops/search endpoint.
- Updated CropSearchService to support additional search options.
- Manually updated Swagger documentation in swagger/v1/swagger.json.
- Added request specs to verify the new endpoint.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>

* Revert "Replace Sidekiq with Solid Queue (#4619)" (#4620)

This reverts commit 4659ac5464.

* Bump ip-address from 10.1.0 to 10.2.0 (#4623)

Bumps [ip-address](https://github.com/beaugunderson/ip-address) from 10.1.0 to 10.2.0.
- [Commits](https://github.com/beaugunderson/ip-address/commits)

---
updated-dependencies:
- dependency-name: ip-address
  dependency-version: 10.2.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump fast-uri from 3.1.0 to 3.1.2

Bumps [fast-uri](https://github.com/fastify/fast-uri) from 3.1.0 to 3.1.2.
- [Release notes](https://github.com/fastify/fast-uri/releases)
- [Commits](https://github.com/fastify/fast-uri/compare/v3.1.0...v3.1.2)

---
updated-dependencies:
- dependency-name: fast-uri
  dependency-version: 3.1.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump friendly_id from 5.6.0 to 5.7.0 (#4625)

Bumps [friendly_id](https://github.com/norman/friendly_id) from 5.6.0 to 5.7.0.
- [Release notes](https://github.com/norman/friendly_id/releases)
- [Changelog](https://github.com/norman/friendly_id/blob/master/Changelog.md)
- [Commits](https://github.com/norman/friendly_id/compare/v5.6.0...v5.7.0)

---
updated-dependencies:
- dependency-name: friendly_id
  dependency-version: 5.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Cesy <cesy.avon@gmail.com>

* Bump aws-sdk-s3 from 1.220.0 to 1.221.0 (#4624)

Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.220.0 to 1.221.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-version: 1.221.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Allow collaborators to remove themselves from gardens (#4630)

- Update Ability to grant destroy permission to collaborators for their own record
- Add 'Leave garden' link to garden show page
- Add specs for garden collaborator permissions

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>

* Bump devise from 5.0.3 to 5.0.4 (#4629)

Bumps [devise](https://github.com/heartcombo/devise) from 5.0.3 to 5.0.4.
- [Release notes](https://github.com/heartcombo/devise/releases)
- [Changelog](https://github.com/heartcombo/devise/blob/main/CHANGELOG.md)
- [Commits](https://github.com/heartcombo/devise/compare/v5.0.3...v5.0.4)

---
updated-dependencies:
- dependency-name: devise
  dependency-version: 5.0.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump rubocop-rails from 2.34.3 to 2.35.0 (#4628)

Bumps [rubocop-rails](https://github.com/rubocop/rubocop-rails) from 2.34.3 to 2.35.0.
- [Release notes](https://github.com/rubocop/rubocop-rails/releases)
- [Changelog](https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop-rails/compare/v2.34.3...v2.35.0)

---
updated-dependencies:
- dependency-name: rubocop-rails
  dependency-version: 2.35.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Add Wikidata climate attributes and integration to gardens (#4627)

* Add Wikidata integration for garden climate data

- Add location_wikidata_id, lowest_temp_c, and highest_temp_c to gardens.
- Implement WikidataService for fetching IDs and temperature properties.
- Map P6591 to highest_temp_c and P7422 to lowest_temp_c with unit conversion.
- Automatically populate Wikidata info on garden location change.
- Add manual "Fetch Wikidata info" button and opt-in prompt to garden show page.
- Update gardens_controller to permit new attributes and handle manual fetch.
- Update db/schema.rb manually to include new columns and migration version.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Fix migration

* Improve display

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>

* Bump selenium-webdriver from 4.43.0 to 4.44.0 (#4631)

Bumps [selenium-webdriver](https://github.com/SeleniumHQ/selenium) from 4.43.0 to 4.44.0.
- [Release notes](https://github.com/SeleniumHQ/selenium/releases)
- [Changelog](https://github.com/SeleniumHQ/selenium/blob/trunk/rb/CHANGES)
- [Commits](https://github.com/SeleniumHQ/selenium/compare/selenium-4.43.0...selenium-4.44.0)

---
updated-dependencies:
- dependency-name: selenium-webdriver
  dependency-version: 4.44.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump systeminformation from 5.31.5 to 5.31.6 (#4632)

Bumps [systeminformation](https://github.com/sebhildebrandt/systeminformation) from 5.31.5 to 5.31.6.
- [Release notes](https://github.com/sebhildebrandt/systeminformation/releases)
- [Changelog](https://github.com/sebhildebrandt/systeminformation/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sebhildebrandt/systeminformation/compare/v5.31.5...v5.31.6)

---
updated-dependencies:
- dependency-name: systeminformation
  dependency-version: 5.31.6
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Ensure garden creation flash prompt is rendered as HTML (#4633)

Updated app/views/shared/_flash_messages.html.haml to use sanitize(content)
instead of = content. This ensures that HTML content in flash messages,
such as the prompt to add an activity after creating a garden, is
correctly rendered even if its html_safe status is lost during session
serialization.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>

* Bump aws-sdk-s3 from 1.221.0 to 1.222.0 (#4636)

Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.221.0 to 1.222.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-version: 1.222.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump rubocop from 1.86.1 to 1.86.2 (#4634)

Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.86.1 to 1.86.2.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.86.1...v1.86.2)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-version: 1.86.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump icalendar from 2.12.2 to 2.12.3 (#4635)

Bumps [icalendar](https://github.com/icalendar/icalendar) from 2.12.2 to 2.12.3.
- [Changelog](https://github.com/icalendar/icalendar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/icalendar/icalendar/compare/v2.12.2...v2.12.3)

---
updated-dependencies:
- dependency-name: icalendar
  dependency-version: 2.12.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump faraday from 2.14.1 to 2.14.2 (#4641)

Bumps [faraday](https://github.com/lostisland/faraday) from 2.14.1 to 2.14.2.
- [Release notes](https://github.com/lostisland/faraday/releases)
- [Changelog](https://github.com/lostisland/faraday/blob/main/CHANGELOG.md)
- [Commits](https://github.com/lostisland/faraday/compare/v2.14.1...v2.14.2)

---
updated-dependencies:
- dependency-name: faraday
  dependency-version: 2.14.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump oj from 3.17.0 to 3.17.1 (#4640)

Bumps [oj](https://github.com/ohler55/oj) from 3.17.0 to 3.17.1.
- [Release notes](https://github.com/ohler55/oj/releases)
- [Changelog](https://github.com/ohler55/oj/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/ohler55/oj/compare/v3.17.0...v3.17.1)

---
updated-dependencies:
- dependency-name: oj
  dependency-version: 3.17.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump rubocop-rails from 2.35.0 to 2.35.1 (#4642)

Bumps [rubocop-rails](https://github.com/rubocop/rubocop-rails) from 2.35.0 to 2.35.1.
- [Release notes](https://github.com/rubocop/rubocop-rails/releases)
- [Changelog](https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop-rails/compare/v2.35.0...v2.35.1)

---
updated-dependencies:
- dependency-name: rubocop-rails
  dependency-version: 2.35.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump rubocop-rails from 2.35.1 to 2.35.2 (#4643)

Bumps [rubocop-rails](https://github.com/rubocop/rubocop-rails) from 2.35.1 to 2.35.2.
- [Release notes](https://github.com/rubocop/rubocop-rails/releases)
- [Changelog](https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop-rails/compare/v2.35.1...v2.35.2)

---
updated-dependencies:
- dependency-name: rubocop-rails
  dependency-version: 2.35.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump dalli from 5.0.2 to 5.0.4 (#4639)

Bumps [dalli](https://github.com/petergoldstein/dalli) from 5.0.2 to 5.0.4.
- [Changelog](https://github.com/petergoldstein/dalli/blob/main/CHANGELOG.md)
- [Commits](https://github.com/petergoldstein/dalli/compare/v5.0.2...v5.0.4)

---
updated-dependencies:
- dependency-name: dalli
  dependency-version: 5.0.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump aws-sdk-s3 from 1.222.0 to 1.224.0 (#4645)

Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.222.0 to 1.224.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-version: 1.224.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump bullet from 8.1.1 to 8.1.2 (#4646)

Bumps [bullet](https://github.com/flyerhzm/bullet) from 8.1.1 to 8.1.2.
- [Changelog](https://github.com/flyerhzm/bullet/blob/main/CHANGELOG.md)
- [Commits](https://github.com/flyerhzm/bullet/compare/8.1.1...8.1.2)

---
updated-dependencies:
- dependency-name: bullet
  dependency-version: 8.1.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump puma from 8.0.1 to 8.0.2 (#4649)

Bumps [puma](https://github.com/puma/puma) from 8.0.1 to 8.0.2.
- [Release notes](https://github.com/puma/puma/releases)
- [Changelog](https://github.com/puma/puma/blob/main/History.md)
- [Commits](https://github.com/puma/puma/compare/v8.0.1...v8.0.2)

---
updated-dependencies:
- dependency-name: puma
  dependency-version: 8.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump rubocop-rails from 2.35.2 to 2.35.3 (#4648)

Bumps [rubocop-rails](https://github.com/rubocop/rubocop-rails) from 2.35.2 to 2.35.3.
- [Release notes](https://github.com/rubocop/rubocop-rails/releases)
- [Changelog](https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop-rails/compare/v2.35.2...v2.35.3)

---
updated-dependencies:
- dependency-name: rubocop-rails
  dependency-version: 2.35.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump dalli from 5.0.4 to 5.0.5 (#4647)

Bumps [dalli](https://github.com/petergoldstein/dalli) from 5.0.4 to 5.0.5.
- [Changelog](https://github.com/petergoldstein/dalli/blob/main/CHANGELOG.md)
- [Commits](https://github.com/petergoldstein/dalli/compare/v5.0.4...v5.0.5)

---
updated-dependencies:
- dependency-name: dalli
  dependency-version: 5.0.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump msgpack from 1.8.0 to 1.8.1 (#4650)

Bumps [msgpack](https://github.com/msgpack/msgpack-ruby) from 1.8.0 to 1.8.1.
- [Changelog](https://github.com/msgpack/msgpack-ruby/blob/master/ChangeLog)
- [Commits](https://github.com/msgpack/msgpack-ruby/compare/v1.8.0...v1.8.1)

---
updated-dependencies:
- dependency-name: msgpack
  dependency-version: 1.8.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump oj from 3.17.1 to 3.17.3 (#4655)

Bumps [oj](https://github.com/ohler55/oj) from 3.17.1 to 3.17.3.
- [Release notes](https://github.com/ohler55/oj/releases)
- [Changelog](https://github.com/ohler55/oj/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/ohler55/oj/compare/v3.17.1...v3.17.3)

---
updated-dependencies:
- dependency-name: oj
  dependency-version: 3.17.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump bullet from 8.1.2 to 8.1.3 (#4654)

Bumps [bullet](https://github.com/flyerhzm/bullet) from 8.1.2 to 8.1.3.
- [Changelog](https://github.com/flyerhzm/bullet/blob/main/CHANGELOG.md)
- [Commits](https://github.com/flyerhzm/bullet/compare/8.1.2...8.1.3)

---
updated-dependencies:
- dependency-name: bullet
  dependency-version: 8.1.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump aws-sdk-s3 from 1.224.0 to 1.225.0 (#4653)

Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.224.0 to 1.225.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-version: 1.225.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump rubocop from 1.86.2 to 1.87.0 (#4652)

Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.86.2 to 1.87.0.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.86.2...v1.87.0)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-version: 1.87.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump discard from 1.4.0 to 2.0.0 (#4651)

Bumps [discard](https://github.com/jhawthorn/discard) from 1.4.0 to 2.0.0.
- [Changelog](https://github.com/jhawthorn/discard/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jhawthorn/discard/compare/v1.4.0...v2.0.0)

---
updated-dependencies:
- dependency-name: discard
  dependency-version: 2.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump rubocop-rails from 2.35.3 to 2.35.4 (#4658)

Bumps [rubocop-rails](https://github.com/rubocop/rubocop-rails) from 2.35.3 to 2.35.4.
- [Release notes](https://github.com/rubocop/rubocop-rails/releases)
- [Changelog](https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop-rails/compare/v2.35.3...v2.35.4)

---
updated-dependencies:
- dependency-name: rubocop-rails
  dependency-version: 2.35.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump rubocop-rspec from 3.9.0 to 3.10.2

Bumps [rubocop-rspec](https://github.com/rubocop/rubocop-rspec) from 3.9.0 to 3.10.2.
- [Release notes](https://github.com/rubocop/rubocop-rspec/releases)
- [Changelog](https://github.com/rubocop/rubocop-rspec/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop-rspec/compare/v3.9.0...v3.10.2)

---
updated-dependencies:
- dependency-name: rubocop-rspec
  dependency-version: 3.10.2
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump rubocop from 1.87.0 to 1.88.0 (#4663)

Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.87.0 to 1.88.0.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.87.0...v1.88.0)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-version: 1.88.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump selenium-webdriver from 4.44.0 to 4.45.0 (#4662)

Bumps [selenium-webdriver](https://github.com/SeleniumHQ/selenium) from 4.44.0 to 4.45.0.
- [Release notes](https://github.com/SeleniumHQ/selenium/releases)
- [Changelog](https://github.com/SeleniumHQ/selenium/blob/trunk/rb/CHANGES)
- [Commits](https://github.com/SeleniumHQ/selenium/compare/selenium-4.44.0...selenium-4.45.0)

---
updated-dependencies:
- dependency-name: selenium-webdriver
  dependency-version: 4.45.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump aws-sdk-s3 from 1.225.0 to 1.225.1 (#4661)

Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.225.0 to 1.225.1.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-version: 1.225.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump msgpack from 1.8.1 to 1.8.3 (#4660)

Bumps [msgpack](https://github.com/msgpack/msgpack-ruby) from 1.8.1 to 1.8.3.
- [Changelog](https://github.com/msgpack/msgpack-ruby/blob/master/ChangeLog)
- [Commits](https://github.com/msgpack/msgpack-ruby/compare/v1.8.1...v1.8.3)

---
updated-dependencies:
- dependency-name: msgpack
  dependency-version: 1.8.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump aws-sdk-s3 from 1.225.1 to 1.226.0 (#4666)

Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.225.1 to 1.226.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-version: 1.226.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump js-yaml from 4.1.1 to 4.2.0 (#4664)

Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.1.1 to 4.2.0.
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/commits)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 4.2.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump actions/checkout from 6 to 7 (#4667)

Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump faraday from 2.14.2 to 2.14.3 (#4665)

Bumps [faraday](https://github.com/lostisland/faraday) from 2.14.2 to 2.14.3.
- [Release notes](https://github.com/lostisland/faraday/releases)
- [Changelog](https://github.com/lostisland/faraday/blob/main/CHANGELOG.md)
- [Commits](https://github.com/lostisland/faraday/compare/v2.14.2...v2.14.3)

---
updated-dependencies:
- dependency-name: faraday
  dependency-version: 2.14.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump rubocop-rails from 2.35.4 to 2.35.5

Bumps [rubocop-rails](https://github.com/rubocop/rubocop-rails) from 2.35.4 to 2.35.5.
- [Release notes](https://github.com/rubocop/rubocop-rails/releases)
- [Changelog](https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop-rails/compare/v2.35.4...v2.35.5)

---
updated-dependencies:
- dependency-name: rubocop-rails
  dependency-version: 2.35.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump rubocop-capybara from 2.23.0 to 3.0.0

Bumps [rubocop-capybara](https://github.com/rubocop/rubocop-capybara) from 2.23.0 to 3.0.0.
- [Release notes](https://github.com/rubocop/rubocop-capybara/releases)
- [Changelog](https://github.com/rubocop/rubocop-capybara/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop-capybara/compare/v2.23.0...v3.0.0)

---
updated-dependencies:
- dependency-name: rubocop-capybara
  dependency-version: 3.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump haml_lint from 0.73.0 to 0.74.0

Bumps [haml_lint](https://github.com/sds/haml-lint) from 0.73.0 to 0.74.0.
- [Release notes](https://github.com/sds/haml-lint/releases)
- [Changelog](https://github.com/sds/haml-lint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sds/haml-lint/compare/v0.73.0...v0.74.0)

---
updated-dependencies:
- dependency-name: haml_lint
  dependency-version: 0.74.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Upgrade to Rails 8.0 (#4621)

* Upgrade application to Rails 8.0

- Updated Gemfile to rails ~> 8.0.0 and updated Gemfile.lock
- Set config.load_defaults 8.0 in config/application.rb
- Configured YAML as default_column_serializer for ActiveRecord serialization compatibility
- Added Faraday 2.x error constant compatibility shim in config/initializers/faraday_patch.rb
- Added Active Storage migrations and verified with db:migrate
- Added Rails 8 bin/dev and bin/rubocop scripts
- Maintained Ruby 3.4.9 compatibility in .ruby-version and Gemfile.lock

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Delete db/migrate/20241117032507_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb

* Delete db/migrate/20241117032505_add_service_name_to_active_storage_blobs.active_storage.rb

* Delete db/migrate/20241117032506_create_active_storage_variant_records.active_storage.rb

* Delete config/initializers/faraday_patch.rb

* Update schema

* Fix conflicts

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Cesy <cesy.avon@gmail.com>
2026-06-23 21:10:53 +09:30
867c8b27fb Upgrade to Rails 8.0 (#4621)
* Upgrade application to Rails 8.0

- Updated Gemfile to rails ~> 8.0.0 and updated Gemfile.lock
- Set config.load_defaults 8.0 in config/application.rb
- Configured YAML as default_column_serializer for ActiveRecord serialization compatibility
- Added Faraday 2.x error constant compatibility shim in config/initializers/faraday_patch.rb
- Added Active Storage migrations and verified with db:migrate
- Added Rails 8 bin/dev and bin/rubocop scripts
- Maintained Ruby 3.4.9 compatibility in .ruby-version and Gemfile.lock

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Delete db/migrate/20241117032507_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb

* Delete db/migrate/20241117032505_add_service_name_to_active_storage_blobs.active_storage.rb

* Delete db/migrate/20241117032506_create_active_storage_variant_records.active_storage.rb

* Delete config/initializers/faraday_patch.rb

* Update schema

* Fix conflicts

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-06-23 20:43:40 +09:30
Cesy c76a7f9b7d Merge pull request #4670 from Growstuff/dependabot/bundler/haml_lint-0.74.0
Bump haml_lint from 0.73.0 to 0.74.0
2026-06-23 10:04:48 +01:00
dependabot[bot] f6bfe339fa Bump haml_lint from 0.73.0 to 0.74.0
Bumps [haml_lint](https://github.com/sds/haml-lint) from 0.73.0 to 0.74.0.
- [Release notes](https://github.com/sds/haml-lint/releases)
- [Changelog](https://github.com/sds/haml-lint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sds/haml-lint/compare/v0.73.0...v0.74.0)

---
updated-dependencies:
- dependency-name: haml_lint
  dependency-version: 0.74.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-23 08:54:48 +00:00
Cesy c4a004c5a8 Merge pull request #4669 from Growstuff/dependabot/bundler/rubocop-capybara-3.0.0
Bump rubocop-capybara from 2.23.0 to 3.0.0
2026-06-23 09:52:15 +01:00
dependabot[bot] 60f498b064 Bump rubocop-capybara from 2.23.0 to 3.0.0
Bumps [rubocop-capybara](https://github.com/rubocop/rubocop-capybara) from 2.23.0 to 3.0.0.
- [Release notes](https://github.com/rubocop/rubocop-capybara/releases)
- [Changelog](https://github.com/rubocop/rubocop-capybara/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop-capybara/compare/v2.23.0...v3.0.0)

---
updated-dependencies:
- dependency-name: rubocop-capybara
  dependency-version: 3.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-23 08:44:35 +00:00
Cesy 45c8d42a33 Merge pull request #4668 from Growstuff/dependabot/bundler/rubocop-rails-2.35.5
Bump rubocop-rails from 2.35.4 to 2.35.5
2026-06-23 09:42:07 +01:00
dependabot[bot] b35216e5ce Bump rubocop-rails from 2.35.4 to 2.35.5
Bumps [rubocop-rails](https://github.com/rubocop/rubocop-rails) from 2.35.4 to 2.35.5.
- [Release notes](https://github.com/rubocop/rubocop-rails/releases)
- [Changelog](https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop-rails/compare/v2.35.4...v2.35.5)

---
updated-dependencies:
- dependency-name: rubocop-rails
  dependency-version: 2.35.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-22 07:06:43 +00:00
dependabot[bot] e4c9bc585c Bump faraday from 2.14.2 to 2.14.3 (#4665)
Bumps [faraday](https://github.com/lostisland/faraday) from 2.14.2 to 2.14.3.
- [Release notes](https://github.com/lostisland/faraday/releases)
- [Changelog](https://github.com/lostisland/faraday/blob/main/CHANGELOG.md)
- [Commits](https://github.com/lostisland/faraday/compare/v2.14.2...v2.14.3)

---
updated-dependencies:
- dependency-name: faraday
  dependency-version: 2.14.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-22 06:59:36 +09:30
dependabot[bot] bd89bb987f Bump actions/checkout from 6 to 7 (#4667)
Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-21 18:05:48 +09:30
dependabot[bot] 84c74aff4f Bump js-yaml from 4.1.1 to 4.2.0 (#4664)
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.1.1 to 4.2.0.
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/commits)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 4.2.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-17 22:11:02 +09:30
dependabot[bot] c52447fab7 Bump aws-sdk-s3 from 1.225.1 to 1.226.0 (#4666)
Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.225.1 to 1.226.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-version: 1.226.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-17 22:10:38 +09:30
dependabot[bot] f7082bcf54 Bump msgpack from 1.8.1 to 1.8.3 (#4660)
Bumps [msgpack](https://github.com/msgpack/msgpack-ruby) from 1.8.1 to 1.8.3.
- [Changelog](https://github.com/msgpack/msgpack-ruby/blob/master/ChangeLog)
- [Commits](https://github.com/msgpack/msgpack-ruby/compare/v1.8.1...v1.8.3)

---
updated-dependencies:
- dependency-name: msgpack
  dependency-version: 1.8.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-16 18:42:02 +09:30
dependabot[bot] 2f839b0f22 Bump aws-sdk-s3 from 1.225.0 to 1.225.1 (#4661)
Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.225.0 to 1.225.1.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-version: 1.225.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-16 18:41:34 +09:30
dependabot[bot] 4a522d3967 Bump selenium-webdriver from 4.44.0 to 4.45.0 (#4662)
Bumps [selenium-webdriver](https://github.com/SeleniumHQ/selenium) from 4.44.0 to 4.45.0.
- [Release notes](https://github.com/SeleniumHQ/selenium/releases)
- [Changelog](https://github.com/SeleniumHQ/selenium/blob/trunk/rb/CHANGES)
- [Commits](https://github.com/SeleniumHQ/selenium/compare/selenium-4.44.0...selenium-4.45.0)

---
updated-dependencies:
- dependency-name: selenium-webdriver
  dependency-version: 4.45.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-16 18:41:15 +09:30
dependabot[bot] 05c3348324 Bump rubocop from 1.87.0 to 1.88.0 (#4663)
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.87.0 to 1.88.0.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.87.0...v1.88.0)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-version: 1.88.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-16 18:41:01 +09:30
Cesy 51360a0c7c Merge pull request #4657 from Growstuff/dependabot/bundler/rubocop-rspec-3.10.2
Bump rubocop-rspec from 3.9.0 to 3.10.2
2026-06-10 09:13:23 +01:00
dependabot[bot] 3db100b75f Bump rubocop-rspec from 3.9.0 to 3.10.2
Bumps [rubocop-rspec](https://github.com/rubocop/rubocop-rspec) from 3.9.0 to 3.10.2.
- [Release notes](https://github.com/rubocop/rubocop-rspec/releases)
- [Changelog](https://github.com/rubocop/rubocop-rspec/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop-rspec/compare/v3.9.0...v3.10.2)

---
updated-dependencies:
- dependency-name: rubocop-rspec
  dependency-version: 3.10.2
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-08 12:37:30 +00:00
dependabot[bot] 1ddbecb22a Bump rubocop-rails from 2.35.3 to 2.35.4 (#4658)
Bumps [rubocop-rails](https://github.com/rubocop/rubocop-rails) from 2.35.3 to 2.35.4.
- [Release notes](https://github.com/rubocop/rubocop-rails/releases)
- [Changelog](https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop-rails/compare/v2.35.3...v2.35.4)

---
updated-dependencies:
- dependency-name: rubocop-rails
  dependency-version: 2.35.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-08 22:06:01 +09:30
dependabot[bot] 884b5bc3f6 Bump discard from 1.4.0 to 2.0.0 (#4651)
Bumps [discard](https://github.com/jhawthorn/discard) from 1.4.0 to 2.0.0.
- [Changelog](https://github.com/jhawthorn/discard/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jhawthorn/discard/compare/v1.4.0...v2.0.0)

---
updated-dependencies:
- dependency-name: discard
  dependency-version: 2.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-08 22:04:46 +09:30
dependabot[bot] 11b15420ed Bump rubocop from 1.86.2 to 1.87.0 (#4652)
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.86.2 to 1.87.0.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.86.2...v1.87.0)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-version: 1.87.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-07 23:14:10 +09:30
dependabot[bot] 5540a86952 Bump aws-sdk-s3 from 1.224.0 to 1.225.0 (#4653)
Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.224.0 to 1.225.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-version: 1.225.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-07 22:20:23 +09:30
dependabot[bot] ccba9a7611 Bump bullet from 8.1.2 to 8.1.3 (#4654)
Bumps [bullet](https://github.com/flyerhzm/bullet) from 8.1.2 to 8.1.3.
- [Changelog](https://github.com/flyerhzm/bullet/blob/main/CHANGELOG.md)
- [Commits](https://github.com/flyerhzm/bullet/compare/8.1.2...8.1.3)

---
updated-dependencies:
- dependency-name: bullet
  dependency-version: 8.1.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-07 22:19:47 +09:30
dependabot[bot] 393994e3e4 Bump oj from 3.17.1 to 3.17.3 (#4655)
Bumps [oj](https://github.com/ohler55/oj) from 3.17.1 to 3.17.3.
- [Release notes](https://github.com/ohler55/oj/releases)
- [Changelog](https://github.com/ohler55/oj/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/ohler55/oj/compare/v3.17.1...v3.17.3)

---
updated-dependencies:
- dependency-name: oj
  dependency-version: 3.17.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-07 22:19:28 +09:30
dependabot[bot] 2ff98315a6 Bump msgpack from 1.8.0 to 1.8.1 (#4650)
Bumps [msgpack](https://github.com/msgpack/msgpack-ruby) from 1.8.0 to 1.8.1.
- [Changelog](https://github.com/msgpack/msgpack-ruby/blob/master/ChangeLog)
- [Commits](https://github.com/msgpack/msgpack-ruby/compare/v1.8.0...v1.8.1)

---
updated-dependencies:
- dependency-name: msgpack
  dependency-version: 1.8.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-03 13:08:09 +09:30
dependabot[bot] 4d2bc77731 Bump dalli from 5.0.4 to 5.0.5 (#4647)
Bumps [dalli](https://github.com/petergoldstein/dalli) from 5.0.4 to 5.0.5.
- [Changelog](https://github.com/petergoldstein/dalli/blob/main/CHANGELOG.md)
- [Commits](https://github.com/petergoldstein/dalli/compare/v5.0.4...v5.0.5)

---
updated-dependencies:
- dependency-name: dalli
  dependency-version: 5.0.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-29 10:52:43 +09:30
dependabot[bot] a32d7d11c9 Bump rubocop-rails from 2.35.2 to 2.35.3 (#4648)
Bumps [rubocop-rails](https://github.com/rubocop/rubocop-rails) from 2.35.2 to 2.35.3.
- [Release notes](https://github.com/rubocop/rubocop-rails/releases)
- [Changelog](https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop-rails/compare/v2.35.2...v2.35.3)

---
updated-dependencies:
- dependency-name: rubocop-rails
  dependency-version: 2.35.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-29 10:52:16 +09:30
dependabot[bot] 5c0746f136 Bump puma from 8.0.1 to 8.0.2 (#4649)
Bumps [puma](https://github.com/puma/puma) from 8.0.1 to 8.0.2.
- [Release notes](https://github.com/puma/puma/releases)
- [Changelog](https://github.com/puma/puma/blob/main/History.md)
- [Commits](https://github.com/puma/puma/compare/v8.0.1...v8.0.2)

---
updated-dependencies:
- dependency-name: puma
  dependency-version: 8.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-29 10:51:39 +09:30
dependabot[bot] 38736211ec Bump bullet from 8.1.1 to 8.1.2 (#4646)
Bumps [bullet](https://github.com/flyerhzm/bullet) from 8.1.1 to 8.1.2.
- [Changelog](https://github.com/flyerhzm/bullet/blob/main/CHANGELOG.md)
- [Commits](https://github.com/flyerhzm/bullet/compare/8.1.1...8.1.2)

---
updated-dependencies:
- dependency-name: bullet
  dependency-version: 8.1.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-29 03:04:12 +09:30
dependabot[bot] 2dc5dbac7d Bump aws-sdk-s3 from 1.222.0 to 1.224.0 (#4645)
Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.222.0 to 1.224.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-version: 1.224.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-25 13:23:23 +09:30
dependabot[bot] ee6d5cd84a Bump dalli from 5.0.2 to 5.0.4 (#4639)
Bumps [dalli](https://github.com/petergoldstein/dalli) from 5.0.2 to 5.0.4.
- [Changelog](https://github.com/petergoldstein/dalli/blob/main/CHANGELOG.md)
- [Commits](https://github.com/petergoldstein/dalli/compare/v5.0.2...v5.0.4)

---
updated-dependencies:
- dependency-name: dalli
  dependency-version: 5.0.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-20 13:09:42 +09:30
dependabot[bot] f1524c2b0c Bump rubocop-rails from 2.35.1 to 2.35.2 (#4643)
Bumps [rubocop-rails](https://github.com/rubocop/rubocop-rails) from 2.35.1 to 2.35.2.
- [Release notes](https://github.com/rubocop/rubocop-rails/releases)
- [Changelog](https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop-rails/compare/v2.35.1...v2.35.2)

---
updated-dependencies:
- dependency-name: rubocop-rails
  dependency-version: 2.35.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-20 13:09:26 +09:30
dependabot[bot] a6cb1cbb36 Bump rubocop-rails from 2.35.0 to 2.35.1 (#4642)
Bumps [rubocop-rails](https://github.com/rubocop/rubocop-rails) from 2.35.0 to 2.35.1.
- [Release notes](https://github.com/rubocop/rubocop-rails/releases)
- [Changelog](https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop-rails/compare/v2.35.0...v2.35.1)

---
updated-dependencies:
- dependency-name: rubocop-rails
  dependency-version: 2.35.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-19 19:54:54 +09:30
dependabot[bot] c0f6720a1e Bump oj from 3.17.0 to 3.17.1 (#4640)
Bumps [oj](https://github.com/ohler55/oj) from 3.17.0 to 3.17.1.
- [Release notes](https://github.com/ohler55/oj/releases)
- [Changelog](https://github.com/ohler55/oj/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/ohler55/oj/compare/v3.17.0...v3.17.1)

---
updated-dependencies:
- dependency-name: oj
  dependency-version: 3.17.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-19 18:41:08 +09:30
dependabot[bot] 04ea628f00 Bump faraday from 2.14.1 to 2.14.2 (#4641)
Bumps [faraday](https://github.com/lostisland/faraday) from 2.14.1 to 2.14.2.
- [Release notes](https://github.com/lostisland/faraday/releases)
- [Changelog](https://github.com/lostisland/faraday/blob/main/CHANGELOG.md)
- [Commits](https://github.com/lostisland/faraday/compare/v2.14.1...v2.14.2)

---
updated-dependencies:
- dependency-name: faraday
  dependency-version: 2.14.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-19 12:30:01 +09:30
dependabot[bot] cabac926cc Bump icalendar from 2.12.2 to 2.12.3 (#4635)
Bumps [icalendar](https://github.com/icalendar/icalendar) from 2.12.2 to 2.12.3.
- [Changelog](https://github.com/icalendar/icalendar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/icalendar/icalendar/compare/v2.12.2...v2.12.3)

---
updated-dependencies:
- dependency-name: icalendar
  dependency-version: 2.12.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-15 12:59:47 +09:30
dependabot[bot] 0d375f6146 Bump rubocop from 1.86.1 to 1.86.2 (#4634)
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.86.1 to 1.86.2.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.86.1...v1.86.2)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-version: 1.86.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-15 12:59:37 +09:30
dependabot[bot] be9e5ed6bf Bump aws-sdk-s3 from 1.221.0 to 1.222.0 (#4636)
Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.221.0 to 1.222.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-version: 1.222.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-15 12:42:57 +09:30
Daniel O'Connorandgoogle-labs-jules[bot] c8ea225b10 Ensure garden creation flash prompt is rendered as HTML (#4633)
Updated app/views/shared/_flash_messages.html.haml to use sanitize(content)
instead of = content. This ensures that HTML content in flash messages,
such as the prompt to add an activity after creating a garden, is
correctly rendered even if its html_safe status is lost during session
serialization.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-05-14 12:35:18 +09:30
dependabot[bot] a8b7c73111 Bump systeminformation from 5.31.5 to 5.31.6 (#4632)
Bumps [systeminformation](https://github.com/sebhildebrandt/systeminformation) from 5.31.5 to 5.31.6.
- [Release notes](https://github.com/sebhildebrandt/systeminformation/releases)
- [Changelog](https://github.com/sebhildebrandt/systeminformation/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sebhildebrandt/systeminformation/compare/v5.31.5...v5.31.6)

---
updated-dependencies:
- dependency-name: systeminformation
  dependency-version: 5.31.6
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-14 11:37:29 +09:30
dependabot[bot] 61810dbee3 Bump selenium-webdriver from 4.43.0 to 4.44.0 (#4631)
Bumps [selenium-webdriver](https://github.com/SeleniumHQ/selenium) from 4.43.0 to 4.44.0.
- [Release notes](https://github.com/SeleniumHQ/selenium/releases)
- [Changelog](https://github.com/SeleniumHQ/selenium/blob/trunk/rb/CHANGES)
- [Commits](https://github.com/SeleniumHQ/selenium/compare/selenium-4.43.0...selenium-4.44.0)

---
updated-dependencies:
- dependency-name: selenium-webdriver
  dependency-version: 4.44.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-13 22:39:08 +09:30
1467ec9364 Add Wikidata climate attributes and integration to gardens (#4627)
* Add Wikidata integration for garden climate data

- Add location_wikidata_id, lowest_temp_c, and highest_temp_c to gardens.
- Implement WikidataService for fetching IDs and temperature properties.
- Map P6591 to highest_temp_c and P7422 to lowest_temp_c with unit conversion.
- Automatically populate Wikidata info on garden location change.
- Add manual "Fetch Wikidata info" button and opt-in prompt to garden show page.
- Update gardens_controller to permit new attributes and handle manual fetch.
- Update db/schema.rb manually to include new columns and migration version.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Fix migration

* Improve display

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-05-12 18:07:35 +09:30
dependabot[bot] 37452a5513 Bump rubocop-rails from 2.34.3 to 2.35.0 (#4628)
Bumps [rubocop-rails](https://github.com/rubocop/rubocop-rails) from 2.34.3 to 2.35.0.
- [Release notes](https://github.com/rubocop/rubocop-rails/releases)
- [Changelog](https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop-rails/compare/v2.34.3...v2.35.0)

---
updated-dependencies:
- dependency-name: rubocop-rails
  dependency-version: 2.35.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-12 17:23:59 +09:30
dependabot[bot] e70297a83e Bump devise from 5.0.3 to 5.0.4 (#4629)
Bumps [devise](https://github.com/heartcombo/devise) from 5.0.3 to 5.0.4.
- [Release notes](https://github.com/heartcombo/devise/releases)
- [Changelog](https://github.com/heartcombo/devise/blob/main/CHANGELOG.md)
- [Commits](https://github.com/heartcombo/devise/compare/v5.0.3...v5.0.4)

---
updated-dependencies:
- dependency-name: devise
  dependency-version: 5.0.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-12 17:23:46 +09:30
Daniel O'Connorandgoogle-labs-jules[bot] d7a50f86b5 Allow collaborators to remove themselves from gardens (#4630)
- Update Ability to grant destroy permission to collaborators for their own record
- Add 'Leave garden' link to garden show page
- Add specs for garden collaborator permissions

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-05-12 17:23:24 +09:30
dependabot[bot] ca7f56683c Bump aws-sdk-s3 from 1.220.0 to 1.221.0 (#4624)
Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.220.0 to 1.221.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-version: 1.221.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-10 10:38:49 +09:30
dependabot[bot]andCesy 0c00b866da Bump friendly_id from 5.6.0 to 5.7.0 (#4625)
Bumps [friendly_id](https://github.com/norman/friendly_id) from 5.6.0 to 5.7.0.
- [Release notes](https://github.com/norman/friendly_id/releases)
- [Changelog](https://github.com/norman/friendly_id/blob/master/Changelog.md)
- [Commits](https://github.com/norman/friendly_id/compare/v5.6.0...v5.7.0)

---
updated-dependencies:
- dependency-name: friendly_id
  dependency-version: 5.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Cesy <cesy.avon@gmail.com>
2026-05-10 10:38:23 +09:30
Cesy f50da4e0e0 Merge pull request #4626 from Growstuff/dependabot/npm_and_yarn/fast-uri-3.1.2 2026-05-09 06:46:38 +01:00
dependabot[bot] 31285b2bde Bump fast-uri from 3.1.0 to 3.1.2
Bumps [fast-uri](https://github.com/fastify/fast-uri) from 3.1.0 to 3.1.2.
- [Release notes](https://github.com/fastify/fast-uri/releases)
- [Commits](https://github.com/fastify/fast-uri/compare/v3.1.0...v3.1.2)

---
updated-dependencies:
- dependency-name: fast-uri
  dependency-version: 3.1.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-08 23:25:42 +00:00
dependabot[bot] ec5873fc88 Bump ip-address from 10.1.0 to 10.2.0 (#4623)
Bumps [ip-address](https://github.com/beaugunderson/ip-address) from 10.1.0 to 10.2.0.
- [Commits](https://github.com/beaugunderson/ip-address/commits)

---
updated-dependencies:
- dependency-name: ip-address
  dependency-version: 10.2.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-07 13:26:51 +09:30
Daniel O'Connor 555d5ddf15 Revert "Replace Sidekiq with Solid Queue (#4619)" (#4620)
This reverts commit 4659ac5464.
2026-05-04 18:15:17 +09:30
5ada7e7f77 Add crops search API endpoint (#4622)
* Add crops search API endpoint

- Added GET /api/v1/crops/search endpoint.
- Updated CropSearchService to support additional search options.
- Manually updated Swagger documentation in swagger/v1/swagger.json.
- Added request specs to verify the new endpoint.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Add crops search API endpoint

- Added GET /api/v1/crops/search endpoint.
- Updated CropSearchService to support additional search options.
- Manually updated Swagger documentation in swagger/v1/swagger.json.
- Added request specs to verify the new endpoint.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-05-04 18:12:36 +09:30
4659ac5464 Replace Sidekiq with Solid Queue (#4619)
* Replace Sidekiq with Solid Queue

This commit transitions the background job processing from Sidekiq to
Solid Queue.

Changes:
- Replaced `sidekiq` gem with `solid_queue` in Gemfile.
- Updated `development.rb` and `production.rb` to use `:solid_queue` as
  the queue adapter.
- Added Solid Queue database tables via a new migration.
- Configured Solid Queue in `config/queue.yml` and `config/recurring.yml`.
- Integrated Solid Queue supervisor as a Puma plugin in `config/puma.rb`.
- Removed separate worker process from `Procfile`.
- Removed Sidekiq-specific configuration files.
- Updated Gemfile.lock to support both `ruby` and `x86_64-linux` platforms.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Fix regression in gemfiles

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-05-03 15:29:03 +09:30
3d63d12908 Improve read performance with caching and memoization (#4572)
* Improve read performance with caching and memoization

- Memoize `Crop#all_companions` and `Member#unread_count` in models
- Implement instance-level memoization in `CropsHelper#crop_or_parent`
- Add Rails caching for expensive aggregate queries in `Charts::CropsController`
- Add fragment caching for high-impact sections on the crop show page

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Fix header spec failure due to memoized unread_count

- Reset `@unread_count` in `spec/views/layouts/_header_spec.rb` to ensure the updated notification count is rendered correctly.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-05-03 14:47:59 +09:30
035210197f Prompt for updated planting rating when harvesting (#4608)
* Update planting rating when recording a harvest

- Added virtual attribute `overall_rating` to `Harvest` model.
- Updated `HarvestsController` to permit `overall_rating` and synchronize it to the associated `Planting`.
- Added a rating range field (1-5) to the harvest form.
- Added controller tests to verify that the planting rating is updated.
- Refined feature tests for harvesting.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* I have updated the system to allow for recording a planting rating when a harvest is logged. Here is a summary of the changes:

- Added a virtual attribute `overall_rating` to the `Harvest` model.
- Updated `HarvestsController` to permit `overall_rating` and synchronize it to the associated `Planting`.
- Added a rating range field (1-5) to the harvest form.
- Added controller tests to verify that the planting rating is updated correctly.
- Updated feature tests to ensure the harvest form functions as expected.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Update database.yml

* Apply suggestions from code review

Co-authored-by: Daniel O'Connor <daniel.oconnor@gmail.com>

* Adjust wording

* Change harvest modal

* Fix tests

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-05-03 14:47:00 +09:30
Daniel O'Connor 8a8fd6eabd Merge pull request #4575 from Growstuff/memoize-unread-count
Memoize unread messages count
2026-05-02 16:46:26 +09:30
Daniel O'Connor fe9fdd9147 Upgrade ERB (#4617) 2026-05-02 16:46:02 +09:30
Daniel O'Connor ee7b9ab39f Upgrade ERB 2026-05-02 07:03:30 +00:00
Daniel O'Connor 6aadb4d805 Merge pull request #4616 from Growstuff/rubocop-upgrade
Update rubocop_todo.yml
2026-05-02 16:28:50 +09:30
Daniel O'Connor a42682a59e Merge pull request #4614 from Growstuff/upgrade-ruby
Update to Ruby 3.4.9
2026-05-02 16:19:54 +09:30
Daniel O'Connor 6294c54139 Merge pull request #4615 from Growstuff/fix-sidekiq
Namespaces no longer supported in sidekiq
2026-05-02 16:07:59 +09:30
Daniel O'Connor c168e8e4c9 Update to 3.4.9 2026-05-02 06:36:27 +00:00
Daniel O'Connor 6ac438a07f Namespaces no longer supported in sidekiq 2026-05-02 06:35:23 +00:00
Daniel O'Connor 2380c662fe Merge pull request #4604 from Growstuff/harvest-reminders-16703221337897327633
Add Harvest Reminder Emails and Scheduled Task
2026-05-02 15:46:09 +09:30
4589839c64 Fix crops csv export 11894001552728801282 (#4613)
* Fix ArgumentError in Crops CSV export

This commit fixes a crash when exporting crops to CSV, caused by
accessing ActiveRecord methods and associations on Searchkick
HashWrapper objects.

Changes:
- In CropsController#index, use `load: true` (with preloaded
  associations) when the request format is CSV or RSS.
- In app/views/crops/index.csv.shaper, use individual `csv.cell` calls
  instead of `csv.cells` to correctly handle Searchkick results and
  explicitly access attributes.
- Added a controller test to verify CSV export functionality.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Mark test pending

* Skip creator

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-05-02 15:39:36 +09:30
Daniel O'Connor 1f6f3c4dfd Merge pull request #4612 from Growstuff/fix-crops-csv-export-11894001552728801282
Fix ArgumentError in Crops CSV export
2026-05-02 15:31:10 +09:30
Daniel O'Connor 5a7f41537f Change plant_before formatting method to to_fs 2026-05-02 14:47:43 +09:30
Daniel O'Connor 1281795c97 Merge pull request #4609 from Growstuff/fix-csv-export-crash-4991917409830119333
Fix crash during CSV export of harvests and seeds
2026-05-02 14:42:39 +09:30
Daniel O'Connor c219d447cc Merge branch 'dev' into fix-csv-export-crash-4991917409830119333 2026-05-02 14:41:31 +09:30
Daniel O'Connor 1e3f86a349 Merge pull request #4611 from Growstuff/CloCkWeRX-patch-2
Fix seeds_count to correctly reference size
2026-05-02 14:17:51 +09:30
Daniel O'Connor 680afe02cc Merge pull request #4610 from Growstuff/associate-post-with-crop-5945795316503813050
Associate post with crop from crop show page
2026-05-02 13:42:01 +09:30
Daniel O'Connor 914cfe99c8 Fix seeds_count to correctly reference size 2026-05-02 13:39:34 +09:30
google-labs-jules[bot]andCloCkWeRX 4643fbd92e Associate post with crop from crop show page
Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-05-01 11:35:58 +00:00
google-labs-jules[bot]andCloCkWeRX 5ac709ffd1 Fix crash during CSV export of harvests and seeds
When using Searchkick with `load: false`, search results are returned
as HashResponse objects which do not support model associations or
standard Rails URL helpers that expect model instances.

This commit updates HarvestsController and SeedsController to
conditionally load ActiveRecord objects when CSV format is requested,
ensuring that the export templates can access the necessary associations.
Similar logic was also applied to CropsController.

Additionally, a typo in the Crops CSV shaper was fixed.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-05-01 11:30:22 +00:00
Daniel O'Connor 9833801a42 Merge pull request #4606 from Growstuff/dependabot/bundler/axe-core-rspec-4.11.3
Bump axe-core-rspec from 4.11.2 to 4.11.3
2026-05-01 18:17:28 +09:30
dependabot[bot] 4d1e8aede6 Bump axe-core-rspec from 4.11.2 to 4.11.3
Bumps [axe-core-rspec](https://github.com/dequelabs/axe-core-gems) from 4.11.2 to 4.11.3.
- [Release notes](https://github.com/dequelabs/axe-core-gems/releases)
- [Changelog](https://github.com/dequelabs/axe-core-gems/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/dequelabs/axe-core-gems/commits)

---
updated-dependencies:
- dependency-name: axe-core-rspec
  dependency-version: 4.11.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-01 07:49:38 +00:00
Daniel O'Connoranddependabot[bot] 24f41350a9 Bump rubocop-capybara from 2.22.1 to 2.23.0 (#4605)
Bumps [rubocop-capybara](https://github.com/rubocop/rubocop-capybara) from 2.22.1 to 2.23.0.
- [Release notes](https://github.com/rubocop/rubocop-capybara/releases)
- [Changelog](https://github.com/rubocop/rubocop-capybara/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop-capybara/compare/v2.22.1...v2.23.0)

---
updated-dependencies:
- dependency-name: rubocop-capybara
  dependency-version: 2.23.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-30 17:38:16 +09:30
dependabot[bot] 503ba716bb Bump rubocop-capybara from 2.22.1 to 2.23.0
Bumps [rubocop-capybara](https://github.com/rubocop/rubocop-capybara) from 2.22.1 to 2.23.0.
- [Release notes](https://github.com/rubocop/rubocop-capybara/releases)
- [Changelog](https://github.com/rubocop/rubocop-capybara/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop-capybara/compare/v2.22.1...v2.23.0)

---
updated-dependencies:
- dependency-name: rubocop-capybara
  dependency-version: 2.23.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-30 07:04:07 +00:00
google-labs-jules[bot]andCloCkWeRX e423e6ac79 Add weekly harvest reminder emails and scheduled task
- Added `send_harvest_reminder` preference to Member model and settings UI.
- Implemented `harvest_in_next_week?` in PredictHarvest concern.
- Created `harvest_reminder` email with localized templates.
- Added `growstuff:send_harvest_reminders` Rake task to run weekly.
- Refactored existing and new reminder tasks to use `deliver_later` for scalability.
- Added unit tests for prediction logic and mailer.
- Fixed a bug in the existing planting reminder task where it was using an uninitialized constant `Notifier`.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-04-30 04:09:26 +00:00
Daniel O'Connorandgoogle-labs-jules[bot] e63089e03b Remove deprecated config.read_encrypted_secrets from production.rb (#4603)
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-04-30 12:54:17 +09:30
Daniel O'Connor 6ce347af82 Rename FUNDING.yml to .github/FUNDING.yml 2026-04-28 18:11:48 +09:30
Daniel O'Connor 64af597dec Add funding information 2026-04-28 18:10:50 +09:30
7160f50ac1 Refactor Activity model to remove Elasticsearch integration (#4576)
* Refactor Activity model to remove Elasticsearch integration

- Removed `SearchActivities` concern and Searchkick from `Activity` model.
- Implemented `Activity.homepage_records` using ActiveRecord with `DISTINCT ON` for PostgreSQL.
- Updated `ActivitiesController#index` to use ActiveRecord queries with eager loading and pagination.
- Added `active` scope to `Activity`.
- Added unit tests for `Activity` model.
- Deleted `app/models/concerns/search_activities.rb`.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Fix NoMethodError: undefined method 'reindex' for class Activity

- Removed all calls to `Activity.reindex` in migrations, rake tasks, and spec helpers.
- These were causing failures after the removal of Searchkick from the Activity model.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Fix ambiguous column id in homepage_records query

- Updated `Activity.homepage_records` to use `activities.id` instead of `id` in the subquery.
- This resolves the `PG::AmbiguousColumn: ERROR: column reference "id" is ambiguous` error.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Fix ambiguous created_at in homepage_records query

- Use `unscoped` in the subquery for `Activity.homepage_records` to bypass the default scope from `Ownable` concern.
- This prevents the join with the `members` table in the subquery, which was causing `PG::AmbiguousColumn: ERROR: column reference "created_at" is ambiguous`.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Complete refactoring of Activity model to remove Elasticsearch

- Removed SearchActivities concern and searchkick integration.
- Updated ActivitiesController#index to use ActiveRecord queries.
- Implemented performant Activity.homepage_records using DISTINCT ON (PostgreSQL).
- Added Activity.active scope.
- Added no-op Activity.reindex (class and instance methods) for backward compatibility.
- Cleaned up leftover reindex calls in rake tasks, migrations, and spec helpers.
- Added unit tests for new Activity model logic.
- Updated factories to include no-op reindex traits.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Less eager loading

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-04-28 17:51:01 +09:30
Daniel O'Connor 6784c6460d Merge pull request #4600 from Growstuff/dev
Release 85
2026-04-28 14:48:45 +09:30
Daniel O'Connor e748da9a1f Merge pull request #4601 from Growstuff/links-wrong
Fix links further
2026-04-28 13:34:11 +09:30
Daniel O'Connor 4ac0dcb05b Merge branch 'dev' of https://github.com/Growstuff/growstuff into links-wrong 2026-04-28 04:03:44 +00:00
Daniel O'Connor 60390fcc06 Fix links further 2026-04-28 04:03:27 +00:00
Daniel O'Connor 55e6d99979 Merge pull request #4599 from Growstuff/links-wrong
Fix various breadcrumb links to avoid passing ?owner, which doesn't actually filter
2026-04-28 13:23:36 +09:30
Daniel O'Connor dfac51ee97 Merge pull request #4595 from Growstuff/optimize-harvests-caching-memoization-9176733581563564983
Optimize Harvests with memoization and fragment caching
2026-04-28 13:20:01 +09:30
Daniel O'Connor f24ca80394 Fix various breadcrumb links to avoid passing ?owner, which doesn't actually filter 2026-04-28 03:46:47 +00:00
Daniel O'Connor 7360bc968b Merge pull request #4596 from Growstuff/flickr-tag-filtering-3395495860406820072
Add Flickr tag filtering for adding photos
2026-04-28 13:04:40 +09:30
Daniel O'Connor f680a6b25d Merge pull request #4597 from Growstuff/memoize-plantings-8206863373400530940
Memoize Planting-related methods for performance optimization
2026-04-28 13:04:17 +09:30
Daniel O'Connor 22638371c2 Update _harvests.html.haml 2026-04-28 13:01:02 +09:30
google-labs-jules[bot]andCloCkWeRX 50ab6f39ee Optimize Harvests with memoization and caching
- Memoize display methods in `Harvest` model.
- Memoize calculation methods in `PredictHarvest` concern using `defined?` for nil safety.
- Add fragment caching to `app/views/harvests/_popover.html.haml`.
- Add fragment caching and query caching to `app/views/crops/_harvests.html.haml` with daily expiration for relative time strings.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-04-28 03:16:36 +00:00
google-labs-jules[bot]andCloCkWeRX 2e0c8a910d Memoize Planting-related methods for performance optimization
This commit introduces memoization to various methods in the Planting model,
PredictPlanting and PredictHarvest concerns, PlantingsHelper, and
PlantingsController.

Specifically:
- Memoized database-intensive lookups like `nearby_same_crop`, `first_harvest_date`,
  and `last_harvest_date`.
- Memoized calculated fields like `finish_predicted_at`, `expected_lifespan`,
  and `age_in_days`.
- Optimized `PlantingsHelper#transplantable_gardens_by_owner` using a hash
  to cache results per planting instance within a request.
- Applied the `defined?(@variable)` pattern where appropriate to ensure
  efficient handling of `nil` results.

These changes reduce redundant database queries and expensive calculations,
particularly during view rendering where these methods are frequently accessed.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-04-28 03:07:18 +00:00
google-labs-jules[bot]andCloCkWeRX 3c70ba12ca Allow filtering Flickr photos by tag when adding photos
- Update MemberFlickr concern to support tag-based search using flickr.photos.search
- Update PhotosController to handle the 'tag' parameter
- Add tag search input field to the 'New Photo' view
- Add test case to verify tag filtering in PhotosController spec

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-04-28 02:59:21 +00:00
google-labs-jules[bot]andCloCkWeRX 0df7589feb Optimize Harvests with memoization and fragment caching
- Memoize display methods in `Harvest` model.
- Memoize calculation methods in `PredictHarvest` concern using `defined?` for nil safety.
- Add fragment caching to `app/views/harvests/_popover.html.haml`.
- Add fragment caching to `app/views/crops/_harvests.html.haml` with daily expiration for relative time strings.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-04-28 02:59:06 +00:00
Daniel O'Connor 8cdfda3660 Merge pull request #4594 from Growstuff/jules-10992479017878632568-8480ddd1
Optimize CropsHelper with caching and memoization
2026-04-28 12:03:03 +09:30
google-labs-jules[bot]andCloCkWeRX aa0ee65d78 Optimize CropsHelper with caching and memoization
- Implement instance-level memoization for `crop_or_parent` and `display_seed_availability`
- Use `Rails.cache.fetch` for `crop_jsonld_data` to improve performance of JSON-LD generation
- Optimize `display_seed_availability` to avoid redundant queries
- Fix a potential `NameError` in `crop_jsonld_data` by initializing `images` properly
- Ensure memoization keys handle non-persisted objects and nil results correctly

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-04-27 23:55:46 +00:00
Daniel O'Connor 355e9f84d5 Merge pull request #4591 from Growstuff/cache-charts-crops-data-7725540171807829398
Improve Charts::CropsController caching
2026-04-27 19:23:11 +09:30
Daniel O'Connor dce32c5e3c Merge pull request #4586 from Growstuff/dependabot/github_actions/docker/build-push-action-7
Bump docker/build-push-action from 5 to 7
2026-04-27 18:35:25 +09:30
Daniel O'Connor dbae34a958 Merge pull request #4587 from Growstuff/dependabot/github_actions/docker/setup-buildx-action-4
Bump docker/setup-buildx-action from 3 to 4
2026-04-27 18:35:06 +09:30
Daniel O'Connor 9edee8400d Merge pull request #4589 from Growstuff/dependabot/github_actions/docker/login-action-4
Bump docker/login-action from 3 to 4
2026-04-27 18:34:50 +09:30
Daniel O'Connor b775814614 Merge pull request #4593 from Growstuff/planting-photos
Try planting filtering
2026-04-27 18:17:35 +09:30
Daniel O'Connor 464017de6f Try planting filtering 2026-04-27 08:05:32 +00:00
dependabot[bot] 9184285388 Bump docker/login-action from 3 to 4
Bumps [docker/login-action](https://github.com/docker/login-action) from 3 to 4.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-27 08:00:55 +00:00
dependabot[bot] dcd701fe9d Bump docker/build-push-action from 5 to 7
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5 to 7.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v5...v7)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-27 08:00:50 +00:00
dependabot[bot] 5a462bd740 Bump docker/setup-buildx-action from 3 to 4
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-27 07:57:06 +00:00
Daniel O'Connor ecf77313dc Merge pull request #4588 from Growstuff/dependabot/github_actions/docker/metadata-action-6
Bump docker/metadata-action from 5 to 6
2026-04-27 17:24:09 +09:30
Daniel O'Connor 0ee671fddb Merge pull request #4590 from Growstuff/dependabot/bundler/puma-8.0.1
Bump puma from 8.0.0 to 8.0.1
2026-04-27 17:23:56 +09:30
Daniel O'Connor fc4276cacf Merge pull request #4592 from Growstuff/CloCkWeRX-patch-2
Ban Semrush
2026-04-27 17:19:53 +09:30
Daniel O'Connor a2bb6c7162 Ban Semrush 2026-04-27 17:19:31 +09:30
google-labs-jules[bot]andCloCkWeRX ff9d99afe5 Improve Charts::CropsController with caching and refactoring
- Added Rails.cache.fetch to `sunniness` and `planted_from` actions.
- Refactored crop loading into a `before_action :set_crop`.
- Updated specs to verify caching behavior and ensure coverage.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-04-27 07:46:08 +00:00
dependabot[bot] 1b4b8f94d1 Bump docker/metadata-action from 5 to 6
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5 to 6.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/v5...v6)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-27 07:42:38 +00:00
Daniel O'Connoranddependabot[bot] 66cc98051f Bump actions/checkout from 4 to 6 (#4585)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-27 17:11:32 +09:30
dependabot[bot] 9fe1fddac1 Bump puma from 8.0.0 to 8.0.1
Bumps [puma](https://github.com/puma/puma) from 8.0.0 to 8.0.1.
- [Release notes](https://github.com/puma/puma/releases)
- [Changelog](https://github.com/puma/puma/blob/main/History.md)
- [Commits](https://github.com/puma/puma/compare/v8.0.0...v8.0.1)

---
updated-dependencies:
- dependency-name: puma
  dependency-version: 8.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-27 07:26:19 +00:00
dependabot[bot] 1eac00705e Bump actions/checkout from 4 to 6
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-27 07:25:50 +00:00
Daniel O'Connorandgoogle-labs-jules[bot] 37e9860fdf Update member_slug lookup to 404 when not found (#4584)
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-04-27 14:19:50 +09:30
Daniel O'Connor a5ed2b988d Merge pull request #4583 from Growstuff/dev
Release 84
2026-04-27 13:56:58 +09:30
Daniel O'Connor bd637c3310 Cache what a crop is harvested for (#4582) 2026-04-27 13:32:45 +09:30
Daniel O'Connor 9abb0d02b9 Merge pull request #4581 from Growstuff/add-rack-attack-protection-3014929071908440304
Add Rack::Attack rate limiting and Fail2Ban protection
2026-04-27 13:23:17 +09:30
Daniel O'Connor 2e56f8cb2f Cache what a crop is harvested for 2026-04-27 03:52:11 +00:00
7ca689fa4a release83 (#4579)
* Ensure "mark as failed" option is available when viewing a crop

This change adds the "mark as failed" action to the crop view in two places:
1. In the "Crop Actions" button group, a new "Mark as failed" button is added if the current member has active plantings of that crop. Clicking it opens a modal to select which planting failed.
2. In the "See who's planted" list, an "Actions" dropdown is added to any plantings owned by the current member, which includes the "Mark as failed" option.

A new partial `app/views/plantings/_failed_modal.html.haml` was created to handle the planting selection modal.
`app/views/crops/_actions.html.haml` and `app/views/crops/_plantings.html.haml` were updated to include these new actions.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Admin - Members - optimise memory usage

* GBIF - optimise memory usage

* Memory usage

* Update .dockerignore to remove .ruby-version

Remove .ruby-version from .dockerignore

* Swap to modern expect style

* Swap to modern expect style

* Rubocop fixes

* Swap to modern expect style

* Merge pull request #4567 from Growstuff/memory-optimisation-3

Members - Nearest To - Memory improvements

* Merge pull request #4564 from Growstuff/memory-optimization-2149092598558110155

Memory usage optimization

* Add fragment cache for crop partials

* Add rake task to cleanup inactive members (#4574)

* Add members:cleanup_inactive rake task

This task identifies and deletes members who have not logged in for over
24 months and have no gardens, plantings, or other activity (posts,
comments, seeds, harvests, etc).

Includes support for DRY_RUN=true to preview deletions.
Added tests in spec/tasks/members_spec.rb.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Refactor activity check to Member#has_activity? and update rake task

- Added `Member#has_activity?` to encapsulate the check for gardens, plantings, and other activity.
- Updated `members:cleanup_inactive` rake task to use `Member#has_activity?`.
- Maintained `DRY_RUN` support and existing tests.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Apply suggestion from @CloCkWeRX

* Apply suggestions from code review

Co-authored-by: Daniel O'Connor <daniel.oconnor@gmail.com>

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>

* Merge pull request #4578 from Growstuff/member-inactive-delete

Delete inactive members with no activity in 3 years

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-04-27 02:22:30 +09:30
Daniel O'Connor 3127f45d0f Merge pull request #4578 from Growstuff/member-inactive-delete
Delete inactive members with no activity in 3 years
2026-04-27 02:15:17 +09:30
Daniel O'Connor 15571940f5 Add fragment cache for crop partials (#4577) 2026-04-27 01:48:35 +09:30
8e7dd25e98 Add rake task to cleanup inactive members (#4574)
* Add members:cleanup_inactive rake task

This task identifies and deletes members who have not logged in for over
24 months and have no gardens, plantings, or other activity (posts,
comments, seeds, harvests, etc).

Includes support for DRY_RUN=true to preview deletions.
Added tests in spec/tasks/members_spec.rb.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Refactor activity check to Member#has_activity? and update rake task

- Added `Member#has_activity?` to encapsulate the check for gardens, plantings, and other activity.
- Updated `members:cleanup_inactive` rake task to use `Member#has_activity?`.
- Maintained `DRY_RUN` support and existing tests.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Apply suggestion from @CloCkWeRX

* Apply suggestions from code review

Co-authored-by: Daniel O'Connor <daniel.oconnor@gmail.com>

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-04-27 01:40:54 +09:30
Daniel O'Connor 2723599f27 Add fragment cache for crop partials 2026-04-26 16:07:29 +00:00
Daniel O'Connor 98c8bdc0bb Merge pull request #4564 from Growstuff/memory-optimization-2149092598558110155
Memory usage optimization
2026-04-27 00:37:51 +09:30
Daniel O'Connor 573daa8c8a Swap to modern expect style (#4571) 2026-04-26 22:58:04 +09:30
Daniel O'Connor 5174b1236e Merge pull request #4567 from Growstuff/memory-optimisation-3
Members - Nearest To - Memory improvements
2026-04-26 22:57:01 +09:30
Daniel O'Connor 5a349f8f1b Swap to modern expect style 2026-04-26 13:21:15 +00:00
Daniel O'Connor 0d850804cf Merge pull request #4570 from Growstuff/rubocop-tweaks
Rubocop fixes
2026-04-26 22:47:46 +09:30
Daniel O'Connor 161a934811 Merge pull request #4569 from Growstuff/plant_part_spec
Rubocop: Fix no expectation errors
2026-04-26 22:44:49 +09:30
Daniel O'Connor 8cfef5ce1a Rubocop fixes 2026-04-26 13:09:00 +00:00
Daniel O'Connor 6dacb0af74 Swap to modern expect style 2026-04-26 13:03:46 +00:00
Daniel O'Connor 7e2d36f99a Swap to modern expect style 2026-04-26 12:55:58 +00:00
Daniel O'Connor 3406d9e7bc Merge pull request #4568 from Growstuff/memory-usage-4
Posts - memory usage
2026-04-26 19:05:56 +09:30
Daniel O'Connor 7a91746f73 Update .dockerignore to remove .ruby-version
Remove .ruby-version from .dockerignore
2026-04-26 19:05:41 +09:30
Daniel O'Connor 209973e72b Memory usage 2026-04-26 09:26:52 +00:00
Daniel O'Connor 4848302eab Merge pull request #4565 from Growstuff/memory-usage-1
Admin - Members - optimise memory usage
2026-04-26 18:45:12 +09:30
Daniel O'Connor 920a28a144 Merge pull request #4566 from Growstuff/memory-usage-2
GBIF - optimise memory usage
2026-04-26 18:44:58 +09:30
Daniel O'Connor fff7a14635 GBIF - optimise memory usage 2026-04-26 09:03:45 +00:00
Daniel O'Connor 0131c9b531 Admin - Members - optimise memory usage 2026-04-26 09:01:18 +00:00
Daniel O'Connor 1b091b2f6f Merge pull request #4453 from Growstuff/add-mark-as-failed-to-crop-view-13853484652230549508
Add "mark as failed" action to crop view
2026-04-26 14:44:09 +09:30
Daniel O'Connor 189067c66f Merge pull request #4563 from Growstuff/dev
Release 82
2026-04-26 14:31:31 +09:30
3b60e8f974 Implement blocking feature (#4199)
* Implement blocking feature

This commit introduces a blocking feature that allows members to block other members.

A blocked member is prevented from:
- following the blocker
- sending private messages to the blocker
- replying to the blocker's posts
- liking the blocker's content

The implementation includes:
- A new `Block` model and a corresponding database table.
- Updates to the `Member` model to include associations for blocks.
- A new `BlocksController` to handle blocking and unblocking actions.
- New routes for the `BlocksController`.
- UI changes to add block/unblock buttons to the member profile page.
- Validations in the `Follow`, `Comment`, and `Like` models to enforce the blocking rules.
- A check in the `MessagesController` to prevent sending messages to a member who has blocked the sender.
- A callback in the `Block` model to destroy the follow relationship when a block is created.
- New feature and model specs to test the blocking functionality.

* Implement blocking feature and fix failing tests

This commit introduces a blocking feature that allows members to block other members.

A blocked member is prevented from:
- following the blocker
- sending private messages to the blocker
- replying to the blocker's posts
- liking the blocker's content

The implementation includes:
- A new `Block` model and a corresponding database table.
- Updates to the `Member` model to include associations for blocks.
- A new `BlocksController` to handle blocking and unblocking actions.
- New routes for the `BlocksController`.
- UI changes to add block/unblock buttons to the member profile page.
- Validations in the `Follow`, `Comment`, and `Like` models to enforce the blocking rules.
- A check in the `MessagesController` to prevent sending messages to a member who has blocked the sender.
- A callback in the `Block` model to destroy the follow relationship when a block is created.
- New feature and model specs to test the blocking functionality.

This commit also fixes a failing test in the blocking feature. The error was caused by the validation being called even when the `member` association was `nil`. A guard has been added to the validation methods in the `Like`, `Follow`, and `Comment` models to prevent this from happening.

* Generate schema

* Fix tests

* Add permissions

* Define Block permissions in Ability model

The feature specs for member blocking were failing because the "Block"
link was not being rendered on member profiles. This was due to the
lack of explicit create and destroy permissions for the Block resource
in the Ability model, which is used by CanCanCan to authorize actions
and by the view to conditionally show links.

This change adds the necessary permissions to `member_abilities`:
- Allows members to create blocks (except for blocking themselves).
- Allows members to destroy blocks where they are the blocker.

These rules ensure that the "Block" and "Unblock" links are correctly
rendered and authorized for signed-in members.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Comment out specs for now

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: Daniel O'Connor <daniel.oconnor@gmail.com>
Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-04-26 14:22:32 +09:30
7ed3a97263 Improve test coverage of ability_spec (#4283)
* Improve test coverage of ability_spec

* Fix specs

* Rubocop

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: Daniel O'Connor <daniel.oconnor@gmail.com>
Co-authored-by: Daniel O'Connor <365751+CloCkWeRX@users.noreply.github.com>
2026-04-26 14:21:36 +09:30
2aa697a6d6 Add comprehensive test coverage for forums (#4561)
* Add comprehensive test coverage for forums

- Added `spec/controllers/forums_controller_spec.rb` to test all CRUD actions and authorization for guest, member, and admin roles.
- Added `spec/features/forums_spec.rb` to cover user-facing features such as browsing forums and creating posts from within a forum.
- Updated `spec/requests/forums_spec.rb` to cover basic request flow and JSON response formats.

Note: Tests were verified for content and logic but execution in the sandbox environment was blocked by missing infrastructure (PostgreSQL and Elasticsearch).

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Fix specs

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-04-26 14:18:28 +09:30
Daniel O'Connor ed87d23ece Merge pull request #4560 from Growstuff/fix-i18n-locale-texts-16171345716630423189
Fix Rails/I18nLocaleTexts RuboCop errors
2026-04-26 13:36:10 +09:30
Daniel O'Connor c20160e3db Merge pull request #4559 from Growstuff/update-crop-wrangling-links-4812587945321495224
Update crop wrangling guide links to GitHub wiki
2026-04-26 12:40:09 +09:30
google-labs-jules[bot]andCloCkWeRX 700cb76e3a Update crop wrangling guide links to GitHub wiki
Updated links to the crop wrangling guide in the scientific names and
alternate names forms to point to the new GitHub wiki location.
Verified that other occurrences in the codebase already use the new
URL.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-04-26 01:46:35 +00:00
Daniel O'Connor 5f834c475f Merge pull request #4557 from Growstuff/fix-rspec-expect-in-hook-16350019958417127399
Fix RSpec/ExpectInHook issues
2026-04-26 04:25:16 +09:30
google-labs-jules[bot]andCloCkWeRX 6c7903c2a5 Fix RSpec/ExpectInHook offenses
- Move expectations from `before` hooks to `it` blocks.
- Ensure controller actions are called after expectations are set in controller specs.
- Replace synchronization expectations in hooks with Capybara `find` calls.
- Remove RSpec/ExpectInHook from .rubocop_todo.yml.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-04-25 18:39:43 +00:00
Daniel O'Connor dfa963cd65 Rubocop: RSpec/EmptyExampleGroup (#4554)
* Rubocop: RSpec/EmptyExampleGroup

* Undo renaming

* Apply suggestion from @CloCkWeRX

* Apply suggestion from @CloCkWeRX
2026-04-26 03:18:50 +09:30
163289e853 Fix RSpec/IndexedLet RuboCop issues in spec files (#4556)
* Fix RSpec/IndexedLet RuboCop issues in spec files

Replace indexed let variable names with descriptive names across 11 spec files.
This improves readability and complies with the RSpec/IndexedLet rule.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Rubocop

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-04-26 03:10:03 +09:30
2001b355c4 Add Docker and CI Support (#4461)
* Add Docker, Docker Compose, and GitHub Actions CI support

- Added a production-ready `Dockerfile` based on Ruby 3.3.8-bullseye.
- Added `entrypoint.sh` to handle Rails server PID cleanup.
- Added `.dockerignore` to optimize build context.
- Added `docker-compose.yml` for local orchestration of Rails, PostgreSQL 17, and Elasticsearch 7.4.0.
- Added GitHub Actions workflow in `.github/workflows/docker-build-push.yml` to build and push the image to GHCR on pushes to the `dev` branch.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Swap to 3.4.8

* Node 22

* Apply suggestion from @CloCkWeRX

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-04-26 03:07:31 +09:30
Daniel O'Connor 6a0b09b047 Merge pull request #4555 from Growstuff/remove-old-compass-rails
Remove old compass rails
2026-04-26 03:00:37 +09:30
Daniel O'Connor 4b7e0cf5d7 Merge pull request #4553 from Growstuff/RSpec/EmptyLineAfterExample
Rubocop: RSpec/EmptyLineAfterExample
2026-04-26 02:37:58 +09:30
Daniel O'Connor a3af82d935 Merge pull request #4552 from Growstuff/Lint/SymbolConversion
Rubocop: Lint/SymbolConversion
2026-04-26 02:37:48 +09:30
Daniel O'Connor 051509b59f Merge pull request #4551 from Growstuff/Style/PercentLiteralDelimiters
Rubocop: Style/PercentLiteralDelimiters
2026-04-26 02:25:43 +09:30
Daniel O'Connor a133eddf21 Rubocop: RSpec/EmptyLineAfterExample 2026-04-25 16:52:34 +00:00
Daniel O'Connor 0577c73833 Rubocop: Lint/SymbolConversion 2026-04-25 16:48:31 +00:00
Daniel O'Connor 7522d992b4 Rubocop: Style/PercentLiteralDelimiters 2026-04-25 16:46:15 +00:00
Daniel O'Connor 83de2fe889 Regenerate 2026-04-25 16:45:00 +00:00
Daniel O'Connor bbe75df0ad Merge pull request #4550 from Growstuff/Style/FrozenStringLiteralComment
Rubocop: Style/FrozenStringLiteralComment
2026-04-24 08:41:23 +09:30
Daniel O'Connor 279cc88162 Update growstuff_markdown_spec.rb 2026-04-24 00:15:18 +09:30
Daniel O'Connor fe4dd5c185 Merge pull request #4549 from Growstuff/Rails/WhereMissing
Rubocop: Rails/WhereMissing
2026-04-24 00:13:37 +09:30
Daniel O'Connor d625eb2dbd Rubocop: Style/FrozenStringLiteralComment 2026-04-23 14:30:02 +00:00
Daniel O'Connor 2019d0e952 Rubocop: Rails/WhereMissing 2026-04-23 14:27:10 +00:00
Daniel O'Connor e7659a75a4 Merge pull request #4548 from Growstuff/RSpecRails/HaveHttpStatus
Rubocop: RSpecRails/HaveHttpStatus
2026-04-23 23:52:40 +09:30
Daniel O'Connor 4a66bdc9fe Merge pull request #4546 from Growstuff/Rails/RedundantActiveRecordAllMethod
Rubocop: Rails/RedundantActiveRecordAllMethod
2026-04-23 23:46:39 +09:30
Daniel O'Connor 8de6b083f9 Rubocop: RSpecRails/HaveHttpStatus 2026-04-23 14:13:47 +00:00
Daniel O'Connor accab7f84c Merge pull request #4545 from Growstuff/RSpecRails/InferredSpecType
Rubocop: RSpecRails/InferredSpecType
2026-04-23 23:29:17 +09:30
Daniel O'Connor 3f6dd59dfa Rubocop: Rails/RedundantActiveRecordAllMethod 2026-04-23 13:48:17 +00:00
Daniel O'Connor 0a71b44dea Merge pull request #4542 from Growstuff/RSpec/ContextMethod
Rubocop: RSpec/ContextMethod
2026-04-23 23:10:33 +09:30
Daniel O'Connor ba75afb3f5 Rubocop: RSpecRails/InferredSpecType 2026-04-23 13:39:46 +00:00
Daniel O'Connor aa1c9ceb05 Merge pull request #4543 from Growstuff/RSpec/ExpectChange
Rubocop: RSpec/ExpectChange
2026-04-23 23:02:03 +09:30
Daniel O'Connor ea5f93f929 Merge pull request #4541 from Growstuff/Lint/EmptyBlock
Rubocop: Lint/EmptyBlock
2026-04-23 22:53:40 +09:30
Daniel O'Connor 6f59635ca7 Rubocop: RSpec/ExpectChange 2026-04-23 13:23:14 +00:00
Daniel O'Connor 6736ae3142 Rubocop: RSpec/ContextMethod 2026-04-23 13:20:47 +00:00
Daniel O'Connor 8d8ee7069c Merge pull request #4540 from Growstuff/Bundler/OrderedGems
Rubocop: Bundler/OrderedGems
2026-04-23 22:46:10 +09:30
Daniel O'Connor 5d112e9134 Rubocop: Capybara/RSpec/HaveSelector (#4539)
* Rubocop: Capybara/RSpec/HaveSelector

* Rubocop: Capybara/RSpec/HaveSelector
2026-04-23 22:45:58 +09:30
Daniel O'Connor 6ba4f39b4a Rubocop: Lint/EmptyBlock 2026-04-23 13:14:39 +00:00
Daniel O'Connor a38d99ed4a Rubocop: Bundler/OrderedGems 2026-04-23 13:07:38 +00:00
Daniel O'Connor f1acb35520 Merge pull request #4537 from Growstuff/FactoryBot/SyntaxMethods
Rubocop: FactoryBot/SyntaxMethods
2026-04-23 22:29:24 +09:30
Daniel O'Connor 267560aff1 Merge pull request #4494 from Growstuff/dependabot/bundler/puma-8.0.0
Bump puma from 7.2.0 to 8.0.0
2026-04-23 22:26:31 +09:30
dependabot[bot] e862a5c5b8 Bump puma from 7.2.0 to 8.0.0
Bumps [puma](https://github.com/puma/puma) from 7.2.0 to 8.0.0.
- [Release notes](https://github.com/puma/puma/releases)
- [Changelog](https://github.com/puma/puma/blob/main/History.md)
- [Commits](https://github.com/puma/puma/compare/v7.2.0...v8.0.0)

---
updated-dependencies:
- dependency-name: puma
  dependency-version: 8.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-23 12:47:21 +00:00
Daniel O'Connor 8d9bcc4559 Merge pull request #4524 from Growstuff/dev
release81
2026-04-23 20:31:28 +09:30
Daniel O'Connor 6e7e752fed Merge pull request #4487 from Growstuff/dev
Release 80
2026-04-11 14:51:48 +09:30
google-labs-jules[bot]andCloCkWeRX 8bafba7f9d Ensure "mark as failed" option is available when viewing a crop
This change adds the "mark as failed" action to the crop view in two places:
1. In the "Crop Actions" button group, a new "Mark as failed" button is added if the current member has active plantings of that crop. Clicking it opens a modal to select which planting failed.
2. In the "See who's planted" list, an "Actions" dropdown is added to any plantings owned by the current member, which includes the "Mark as failed" option.

A new partial `app/views/plantings/_failed_modal.html.haml` was created to handle the planting selection modal.
`app/views/crops/_actions.html.haml` and `app/views/crops/_plantings.html.haml` were updated to include these new actions.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-02-22 00:08:58 +00:00
Daniel O'Connor fe032b6b49 Merge pull request #4378 from Growstuff/dev
Fix minor complaints
2025-12-02 23:00:21 +10:30
Daniel O'Connor 959f914122 Merge pull request #4377 from Growstuff/dev
Update _head.html.haml
2025-12-02 22:51:41 +10:30
Daniel O'Connor 3f8fb799d5 Merge pull request #4376 from Growstuff/dev
More site verification bits
2025-12-02 22:48:29 +10:30
Daniel O'Connor 985ad120c7 Merge pull request #4375 from Growstuff/dev
Deploy various site verification things
2025-12-02 22:42:40 +10:30
Daniel O'Connorandgoogle-labs-jules[bot] d8e1e09dfb Merge pull request #4372 from Growstuff/fix-sitemap-upload (#4373)
Fix Sitemap Upload to S3

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2025-12-02 22:23:21 +10:30
Daniel O'Connor 477baec010 Merge pull request #4371 from Growstuff/dev
Deploy various maintenance tasks to prod
2025-12-02 02:27:07 +10:30
Daniel O'Connor d5db389b23 Merge pull request #4360 from Growstuff/dev
Deploy: Missing PKFID
2025-12-01 22:22:30 +10:30
Daniel O'Connor b866a2064b Merge pull request #4358 from Growstuff/dev
Hotfix: Reduce to member login_name
2025-12-01 20:34:18 +10:30
37519de615 Release 78 (#4357)
* Check presence of version members before accessing

* Fix(specs): Initialize @version_members in crops/show view spec

The `crops/show` view spec was failing with a `NoMethodError` because
the `@version_members` instance variable was `nil`. This variable is used
in the `_history` partial, which is rendered by the `show` view.

This commit fixes the spec by initializing `@version_members` to an
empty hash in the `before` block of the spec. This ensures that the
view can render without errors during the test run.

* Remove defunct gitter

* Merge pull request #4352 from Growstuff/add-public-food-key

feat: Add Public Food Key to Crop model

* Bump rubocop-rails from 2.34.1 to 2.34.2

Bumps [rubocop-rails](https://github.com/rubocop/rubocop-rails) from 2.34.1 to 2.34.2.
- [Release notes](https://github.com/rubocop/rubocop-rails/releases)
- [Changelog](https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop-rails/compare/v2.34.1...v2.34.2)

---
updated-dependencies:
- dependency-name: rubocop-rails
  dependency-version: 2.34.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Optimize Data Improvement Page (#4356)

* feat: Add data improvement page to crops controller

This commit introduces a new data improvement page to the crops controller. The page displays tabbed lists of crops with missing data, allowing users to easily identify areas for data quality improvement.

The following data quality categories are included:
- Crops without photos
- Crops without descriptions
- Crops without a youtube video
- Crops without alternate names
- Crops without a scientific name with a wikidata id
- Crops without row spacing
- Crops without sun requirements
- Crops without height

All lists are sorted by planting count in descending order.

* refactor: Optimize data improvement page to load tab data on demand

This commit refactors the data improvement page to load data for each tab on demand, rather than loading all queries at once. This improves the performance of the page by only executing the query for the currently active tab.

The controller action now uses a `case` statement based on a `tab` URL parameter to execute the appropriate query. The view has been updated to pass this parameter when a tab is clicked.

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>

* Merge pull request #4353 from Growstuff/feat/import-australian-food-data

Add Rake Task to Import Australian Food Data

* Fix styling

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-01 20:01:31 +10:30
Daniel O'Connorandgoogle-labs-jules[bot] 8ddc717d9b Release 77 (#4345)
* Update crops_helper.rb

* feat: Add contribution links and conditional edit form

This commit introduces a series of changes to encourage user contributions for missing crop data.

On the crop show page, it adds links for logged-in users to:
- Add a description if one is not present.
- Add a YouTube video if one is not present.
- Add more attributes in the predictions section if any are missing.

On the crop edit page, the form now conditionally displays fields. For standard users, it only shows fields for attributes that are currently empty. For privileged users (wranglers), it displays all fields, allowing them to edit existing data.

* feat: Add schema.org markup to crop pages

Adds schema.org markup to the crop pages using the BioChemEntity type. The taxonomicRange attribute is used to list the scientific names of the crop, which will improve SEO.

* feat: Add Wikidata ID to scientific names

This commit introduces the ability to store and display the Wikidata ID for scientific names.

Changes include:
- A database migration to add the `wikidata_id` column to the `scientific_names` table.
- An update to the `scientific_names_controller` to permit the `wikidata_id` parameter.
- An update to the scientific name form to include a field for the Wikidata ID.
- An update to the crop show page to display a link to the Wikidata page for a scientific name.

* Delete db/migrate/20251129185029_add_wikidata_id_to_scientific_names.rb

* Update _schema_org.html.haml

* Move to crops helper

* Add more schema.org

* Specific form links

* Styling

* Render images

* Document future

* Render less on some pages

* Fix rendering

* Add version tracking to crops model (#4343)

* feat: Add version tracking to Crop model

This commit introduces version tracking for the Crop model using the PaperTrail gem.

Key changes include:
- Integrating `has_paper_trail` into the `Crop` model.
- Adding a "History" section to the crop show page to display a timeline of changes for that specific crop.
- Creating a new admin page for users with the "crop_wrangler" role to view a log of all recent crop edits, creations, and deletions.
- Fixing several N+1 query performance issues by eager-loading associated `Member` records in both the `CropsController` and the new `Admin::CropsController`.
- Refactoring view logic into a shared partial to reduce code duplication.

* Add papertrail

* Admin UI

* Add papertrail DB

* Add papertrail DB

* Rearrange

* Fix permissions

* Fix permissions

* Fix UI

* Fix UI

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: Daniel O'Connor <daniel.oconnor@gmail.com>

* Add revert functionality to admin crops page (#4346)

* feat(admin): add revert functionality to crops page

This change adds a "Revert" button to the admin crops page, allowing crop wranglers to revert changes to a previous version.

It introduces a new `Admin::VersionsController` with a `revert` action that uses `paper_trail`'s `reify` method to restore a previous version of a `Crop` object.

The view is updated to include a "Revert" button, which is guarded by a `can?(:wrangle, Crop)` check to ensure only authorized users can see it.

The controller also includes an authorization check to prevent unauthorized users from accessing the revert action directly.

A feature spec is added to test the new functionality, including the authorization logic.

* Consistent UX

* Specs

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: Daniel O'Connor <daniel.oconnor@gmail.com>

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2025-11-30 15:05:55 +10:30
352 changed files with 4776 additions and 3401 deletions

No files matched your search

+1 -1
View File
@@ -1,7 +1,7 @@
FROM mcr.microsoft.com/devcontainers/ruby:3.4-trixie
# Install Rails
RUN gem install rails:7.0.8
RUN gem install rails:8.0.5
# Default value to allow debug server to serve content over GitHub Codespace's port forwarding service
# The value is a comma-separated list of allowed domains
+30
View File
@@ -0,0 +1,30 @@
.git
.github
.devcontainer
log/*
tmp/*
!tmp/keep
node_modules
public/assets
.env
.ruby-gemset
.editorconfig
.esignore
.eslintrc.json
.haml-lint.yml
.overcommit.yml
.rspec
.rubocop.yml
.rubocop_todo.yml
.scss-lint.yml
.travis.yml
.yamllint
CODE_OF_CONDUCT.md
CONTRIBUTING.md
CONTRIBUTORS.md
LICENSE.txt
README.md
TECH.md
docker-compose.yml
Dockerfile
.dockerignore
+1
View File
@@ -0,0 +1 @@
ko_fi: jennyscottthompson
+3 -3
View File
@@ -38,7 +38,7 @@ jobs:
steps:
- name: Checkout this repo
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Configure sysctl limits
run: |
@@ -61,7 +61,7 @@ jobs:
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v5
uses: actions/cache@v6
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
@@ -74,7 +74,7 @@ jobs:
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version: '24'
+3 -3
View File
@@ -38,7 +38,7 @@ jobs:
steps:
- name: Checkout this repo
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Configure sysctl limits
run: |
@@ -61,7 +61,7 @@ jobs:
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v5
uses: actions/cache@v6
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
@@ -74,7 +74,7 @@ jobs:
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version: '24'
@@ -38,7 +38,7 @@ jobs:
steps:
- name: Checkout this repo
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Configure sysctl limits
run: |
@@ -61,7 +61,7 @@ jobs:
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v5
uses: actions/cache@v6
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
@@ -74,7 +74,7 @@ jobs:
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version: '24'
+3 -3
View File
@@ -38,7 +38,7 @@ jobs:
steps:
- name: Checkout this repo
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Configure sysctl limits
run: |
@@ -61,7 +61,7 @@ jobs:
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v5
uses: actions/cache@v6
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
@@ -74,7 +74,7 @@ jobs:
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version: '24'
+3 -3
View File
@@ -38,7 +38,7 @@ jobs:
steps:
- name: Checkout this repo
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Configure sysctl limits
run: |
@@ -61,7 +61,7 @@ jobs:
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v5
uses: actions/cache@v6
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
@@ -74,7 +74,7 @@ jobs:
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version: '24'
+3 -3
View File
@@ -38,7 +38,7 @@ jobs:
steps:
- name: Checkout this repo
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Configure sysctl limits
run: |
@@ -61,7 +61,7 @@ jobs:
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v5
uses: actions/cache@v6
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
@@ -74,7 +74,7 @@ jobs:
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version: '24'
+3 -3
View File
@@ -38,7 +38,7 @@ jobs:
steps:
- name: Checkout this repo
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Configure sysctl limits
run: |
@@ -61,7 +61,7 @@ jobs:
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v5
uses: actions/cache@v6
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
@@ -74,7 +74,7 @@ jobs:
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version: '24'
+3 -3
View File
@@ -38,7 +38,7 @@ jobs:
steps:
- name: Checkout this repo
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Configure sysctl limits
run: |
@@ -61,7 +61,7 @@ jobs:
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v5
uses: actions/cache@v6
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
@@ -74,7 +74,7 @@ jobs:
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version: '24'
+3 -3
View File
@@ -38,7 +38,7 @@ jobs:
steps:
- name: Checkout this repo
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Configure sysctl limits
run: |
@@ -61,7 +61,7 @@ jobs:
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v5
uses: actions/cache@v6
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
@@ -74,7 +74,7 @@ jobs:
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version: '24'
+3 -3
View File
@@ -38,7 +38,7 @@ jobs:
steps:
- name: Checkout this repo
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Configure sysctl limits
run: |
@@ -61,7 +61,7 @@ jobs:
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v5
uses: actions/cache@v6
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
@@ -74,7 +74,7 @@ jobs:
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version: '24'
+3 -3
View File
@@ -38,7 +38,7 @@ jobs:
steps:
- name: Checkout this repo
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Configure sysctl limits
run: |
@@ -61,7 +61,7 @@ jobs:
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v5
uses: actions/cache@v6
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
@@ -74,7 +74,7 @@ jobs:
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version: '24'
+3 -3
View File
@@ -38,7 +38,7 @@ jobs:
steps:
- name: Checkout this repo
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Configure sysctl limits
run: |
@@ -61,7 +61,7 @@ jobs:
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v5
uses: actions/cache@v6
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
@@ -74,7 +74,7 @@ jobs:
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version: '24'
+3 -3
View File
@@ -38,7 +38,7 @@ jobs:
steps:
- name: Checkout this repo
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Configure sysctl limits
run: |
@@ -61,7 +61,7 @@ jobs:
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v5
uses: actions/cache@v6
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
@@ -74,7 +74,7 @@ jobs:
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version: '24'
+3 -3
View File
@@ -38,7 +38,7 @@ jobs:
steps:
- name: Checkout this repo
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Configure sysctl limits
run: |
@@ -61,7 +61,7 @@ jobs:
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v5
uses: actions/cache@v6
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
@@ -74,7 +74,7 @@ jobs:
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version: '24'
+4 -4
View File
@@ -6,7 +6,7 @@ jobs:
contributors:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- name: Install ruby version specified in .ruby-version
uses: ruby/setup-ruby@v1
with:
@@ -53,7 +53,7 @@ jobs:
steps:
- name: Checkout this repo
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Configure sysctl limits
run: |
@@ -76,7 +76,7 @@ jobs:
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup yarn cache
uses: actions/cache@v5
uses: actions/cache@v6
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
@@ -89,7 +89,7 @@ jobs:
sudo apt-get -y install libpq-dev google-chrome-stable
- name: Install NodeJS
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version: '24'
+43
View File
@@ -0,0 +1,43 @@
name: Docker Build and Push
on:
push:
branches:
- mainline
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v7
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Log in to the Container registry
uses: docker/login-action@v4.6.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v6
with:
images: ghcr.io/${{ github.repository }}
- name: Build and push Docker image
uses: docker/build-push-action@v7
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
+137 -193
View File
@@ -1,48 +1,31 @@
# This configuration was generated by
# `rubocop --auto-gen-config`
# on 2026-03-01 05:17:50 UTC using RuboCop version 1.85.0.
# on 2026-05-02 06:53:56 UTC using RuboCop version 1.86.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: 1
# Offense count: 407
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation.
Bundler/OrderedGems:
Exclude:
- 'Gemfile'
Capybara/RSpec/HaveContent:
Enabled: false
# Offense count: 19
Capybara/NegationMatcherAfterVisit:
# Offense count: 21
Capybara/RSpec/NegationMatcherAfterVisit:
Exclude:
- 'spec/features/admin/reverting_crops_spec.rb'
- 'spec/features/crops/crop_detail_page_spec.rb'
- 'spec/features/crops/crop_wranglers_spec.rb'
- 'spec/features/gardens/gardens_spec.rb'
- 'spec/features/members/blocking_spec.rb'
- 'spec/features/members/deletion_spec.rb'
- 'spec/features/members/following_spec.rb'
- 'spec/features/members/profile_spec.rb'
- 'spec/features/plantings/planting_a_crop_spec.rb'
# Offense count: 34
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: DefaultSelector.
Capybara/RSpec/HaveSelector:
Exclude:
- 'spec/features/conversations/index_spec.rb'
- 'spec/features/footer_spec.rb'
- 'spec/features/gardens/adding_gardens_spec.rb'
- 'spec/features/harvests/harvesting_a_crop_spec.rb'
- 'spec/features/members/list_spec.rb'
- 'spec/features/plantings/planting_a_crop_spec.rb'
- 'spec/features/seeds/adding_seeds_spec.rb'
- 'spec/features/shared_examples/crop_suggest.rb'
- 'spec/support/feature_helpers.rb'
- 'spec/views/posts/show.html.haml_spec.rb'
# Offense count: 14
Capybara/SpecificMatcher:
Capybara/RSpec/SpecificMatcher:
Exclude:
- 'spec/features/footer_spec.rb'
- 'spec/features/gardens/adding_gardens_spec.rb'
@@ -51,7 +34,7 @@ Capybara/SpecificMatcher:
- 'spec/features/seeds/adding_seeds_spec.rb'
# Offense count: 1
Capybara/VisibilityMatcher:
Capybara/RSpec/VisibilityMatcher:
Exclude:
- 'spec/features/shared_examples/crop_suggest.rb'
@@ -86,12 +69,13 @@ FactoryBot/ExcessiveCreateList:
- 'spec/features/crops/show_spec.rb'
- 'spec/features/percy/percy_spec.rb'
# Offense count: 1158
# This cop supports unsafe autocorrection (--autocorrect-all).
FactoryBot/SyntaxMethods:
Enabled: false
# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
Layout/EmptyLines:
Exclude:
- 'config/environments/production.rb'
# Offense count: 312
# Offense count: 311
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
# SupportedHashRocketStyles: key, separator, table
@@ -99,10 +83,17 @@ FactoryBot/SyntaxMethods:
# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
Layout/HashAlignment:
Exclude:
- 'app/helpers/application_helper.rb'
- 'app/helpers/crops_helper.rb'
- 'app/models/concerns/search_harvests.rb'
- 'app/models/concerns/search_plantings.rb'
- 'app/models/crop.rb'
- 'config/sitemap.rb'
- 'lib/tasks/import.rake'
- 'spec/requests/api/v1/activities_request_spec.rb'
- 'spec/requests/api/v1/members_request_spec.rb'
# Offense count: 6
# Offense count: 8
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
# URISchemes: http, https
@@ -110,10 +101,20 @@ Layout/LineLength:
Exclude:
- 'Gemfile'
- 'app/controllers/admin/versions_controller.rb'
- 'app/controllers/crops_controller.rb'
- 'app/models/concerns/predict_planting.rb'
- 'app/models/crop.rb'
- 'db/seeds.rb'
- 'spec/requests/api/v1/activities_request_spec.rb'
- 'lib/tasks/members.rake'
# Offense count: 3
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: aligned, indented, indented_relative_to_receiver
Layout/MultilineMethodCallIndentation:
Exclude:
- 'app/models/activity.rb'
- 'app/models/concerns/predict_harvest.rb'
# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
@@ -121,23 +122,15 @@ Lint/AmbiguousOperatorPrecedence:
Exclude:
- 'app/controllers/activities_controller.rb'
# Offense count: 4
# Offense count: 3
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: RequireParenthesesForMethodChains.
Lint/AmbiguousRange:
Exclude:
- 'app/models/concerns/search_activities.rb'
- 'app/models/concerns/search_harvests.rb'
- 'app/models/concerns/search_plantings.rb'
- 'db/seeds.rb'
# Offense count: 1
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: AllowSafeAssignment.
Lint/AssignmentInCondition:
Exclude:
- 'app/helpers/crops_helper.rb'
# Offense count: 1
# Configuration parameters: AllowedMethods.
# AllowedMethods: enums
@@ -157,18 +150,6 @@ Lint/DuplicateMethods:
Exclude:
- 'app/models/planting.rb'
# Offense count: 8
# Configuration parameters: AllowComments, AllowEmptyLambdas.
Lint/EmptyBlock:
Exclude:
- 'db/migrate/20171022032108_all_the_predictions.rb'
- 'spec/controllers/home_controller_spec.rb'
- 'spec/controllers/likes_controller_spec.rb'
- 'spec/controllers/plant_parts_controller_spec.rb'
- 'spec/factories/crop_companions.rb'
- 'spec/features/crops/crop_detail_page_spec.rb'
- 'spec/requests/authentications_spec.rb'
# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
Lint/RedundantCopDisableDirective:
@@ -187,27 +168,12 @@ Lint/SuppressedException:
Exclude:
- 'lib/tasks/testing.rake'
# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle.
# SupportedStyles: strict, consistent
Lint/SymbolConversion:
Exclude:
- 'app/helpers/crops_helper.rb'
# Offense count: 7
# This cop supports safe autocorrection (--autocorrect).
Lint/UselessAssignment:
Exclude:
- 'config.rb'
- 'config/compass.rb'
# Offense count: 1
Lint/UselessConstantScoping:
Exclude:
- 'app/controllers/members_controller.rb'
# Offense count: 61
# Offense count: 65
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
Metrics/AbcSize:
Max: 295
@@ -229,12 +195,12 @@ Metrics/CollectionLiteralLength:
Exclude:
- 'lib/tasks/import.rake'
# Offense count: 10
# Offense count: 11
# Configuration parameters: AllowedMethods, AllowedPatterns.
Metrics/CyclomaticComplexity:
Max: 32
# Offense count: 82
# Offense count: 83
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
Metrics/MethodLength:
Max: 296
@@ -244,7 +210,7 @@ Metrics/MethodLength:
Metrics/ModuleLength:
Max: 144
# Offense count: 8
# Offense count: 10
# Configuration parameters: AllowedMethods, AllowedPatterns.
Metrics/PerceivedComplexity:
Max: 32
@@ -258,6 +224,16 @@ Naming/PredicateMethod:
- 'app/models/concerns/finishable.rb'
- 'app/models/seed.rb'
# Offense count: 1
# Configuration parameters: NamePrefix, ForbiddenPrefixes, AllowedMethods, MethodDefinitionMacros, UseSorbetSigs.
# NamePrefix: is_, has_, have_, does_
# ForbiddenPrefixes: is_, has_, have_, does_
# AllowedMethods: is_a?
# MethodDefinitionMacros: define_method, define_singleton_method
Naming/PredicatePrefix:
Exclude:
- 'app/models/member.rb'
# Offense count: 3
RSpec/AnyInstance:
Exclude:
@@ -270,89 +246,54 @@ RSpec/BeEq:
Exclude:
- 'spec/requests/api/v1/activities_request_spec.rb'
# Offense count: 1
# Offense count: 2
RSpec/BeforeAfterAll:
Exclude:
- 'spec/tasks/import_spec.rb'
- 'spec/tasks/members_spec.rb'
# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
RSpec/ContextMethod:
Exclude:
- 'spec/requests/api/v1/activities_request_spec.rb'
# Offense count: 299
# Offense count: 311
# Configuration parameters: Prefixes, AllowedPatterns.
# Prefixes: when, with, without
RSpec/ContextWording:
Enabled: false
# Offense count: 1
# Offense count: 2
# Configuration parameters: IgnoredMetadata.
RSpec/DescribeClass:
Exclude:
- 'spec/tasks/import_spec.rb'
- 'spec/models/harvest_prediction_spec.rb'
- 'spec/tasks/members_spec.rb'
# Offense count: 36
# Offense count: 37
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: SkipBlocks, EnforcedStyle, OnlyStaticConstants.
# SupportedStyles: described_class, explicit
RSpec/DescribedClass:
Exclude:
- 'spec/mailers/harvest_reminder_mailer_spec.rb'
- 'spec/models/like_spec.rb'
- 'spec/models/member_spec.rb'
- 'spec/services/timeline_service_spec.rb'
# Offense count: 13
# This cop supports unsafe autocorrection (--autocorrect-all).
RSpec/EmptyExampleGroup:
Exclude:
- 'spec/controllers/authentications_controller_spec.rb'
- 'spec/controllers/forums_controller_spec.rb'
- 'spec/controllers/home_controller_spec.rb'
- 'spec/controllers/likes_controller_spec.rb'
- 'spec/controllers/plant_parts_controller_spec.rb'
- 'spec/controllers/seeds_controller_spec.rb'
- 'spec/features/crops/crop_detail_page_spec.rb'
- 'spec/features/plantings/planting_a_crop_spec.rb'
- 'spec/requests/authentications_spec.rb'
- 'spec/views/home/index_spec.rb'
- 'spec/views/photos/edit.html.haml_spec.rb'
- 'spec/views/posts/_single.html.haml_spec.rb'
# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: AllowConsecutiveOneLiners.
RSpec/EmptyLineAfterExample:
Exclude:
- 'spec/models/ability_spec.rb'
- 'spec/controllers/crops_controller_spec.rb'
# Offense count: 146
# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
RSpec/EmptyLineAfterFinalLet:
Exclude:
- 'spec/controllers/crops_controller_spec.rb'
# Offense count: 161
# Configuration parameters: CountAsOne.
RSpec/ExampleLength:
Max: 27
# Offense count: 1
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: EnforcedStyle.
# SupportedStyles: method_call, block
RSpec/ExpectChange:
Exclude:
- 'spec/models/crop_spec.rb'
# Offense count: 32
RSpec/ExpectInHook:
Exclude:
- 'spec/controllers/garden_types_controller_spec.rb'
- 'spec/controllers/gardens_controller_spec.rb'
- 'spec/features/admin/forums_spec.rb'
- 'spec/features/admin/plant_parts_spec.rb'
- 'spec/features/admin/roles_spec.rb'
- 'spec/features/crops/crop_photos_spec.rb'
- 'spec/features/members/list_spec.rb'
- 'spec/features/plantings/planting_a_crop_spec.rb'
- 'spec/features/shared_examples/append_date.rb'
# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle.
@@ -387,28 +328,18 @@ RSpec/IncludeExamples:
- 'spec/views/photos/show.html.haml_spec.rb'
- 'spec/views/seeds/index.rss.haml_spec.rb'
# Offense count: 37
# Offense count: 2
# Configuration parameters: Max, AllowedIdentifiers, AllowedPatterns.
RSpec/IndexedLet:
Exclude:
- 'spec/controllers/harvests_controller_spec.rb'
- 'spec/controllers/plantings_controller_spec.rb'
- 'spec/features/crops/crop_photos_spec.rb'
- 'spec/features/members/list_spec.rb'
- 'spec/features/members/profile_spec.rb'
- 'spec/features/percy/percy_spec.rb'
- 'spec/features/planting_reminder_spec.rb'
- 'spec/features/timeline/index_spec.rb'
- 'spec/models/crop_spec.rb'
- 'spec/models/member_spec.rb'
- 'spec/views/forums/index.html.haml_spec.rb'
- 'spec/models/activity_spec.rb'
# Offense count: 719
# Offense count: 711
# Configuration parameters: AssignmentOnly.
RSpec/InstanceVariable:
Enabled: false
# Offense count: 41
# Offense count: 43
RSpec/LetSetup:
Enabled: false
@@ -423,7 +354,7 @@ RSpec/MessageChain:
Exclude:
- 'spec/models/member_spec.rb'
# Offense count: 23
# Offense count: 65
# Configuration parameters: .
# SupportedStyles: have_received, receive
RSpec/MessageSpies:
@@ -434,11 +365,11 @@ RSpec/MultipleDescribes:
Exclude:
- 'spec/features/crops/crop_wranglers_spec.rb'
# Offense count: 189
# Offense count: 235
RSpec/MultipleExpectations:
Max: 19
# Offense count: 166
# Offense count: 171
# Configuration parameters: AllowSubject.
RSpec/MultipleMemoizedHelpers:
Max: 16
@@ -449,24 +380,35 @@ RSpec/MultipleMemoizedHelpers:
RSpec/NamedSubject:
Enabled: false
# Offense count: 111
# Offense count: 112
# Configuration parameters: AllowedGroups.
RSpec/NestedGroups:
Max: 6
# Offense count: 407
# Offense count: 366
# Configuration parameters: AllowedPatterns.
# AllowedPatterns: ^expect_, ^assert_
RSpec/NoExpectationExample:
Enabled: false
# Offense count: 4
# Offense count: 9
RSpec/PendingWithoutReason:
Exclude:
- 'spec/features/members/blocking_spec.rb'
- 'spec/features/plantings/planting_a_crop_spec.rb'
- 'spec/features/seeds/misc_seeds_spec.rb'
- 'spec/features/unsubscribing_spec.rb'
- 'spec/models/ability_spec.rb'
- 'spec/requests/api/v1/gardens_request_spec.rb'
# Offense count: 5
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: Strict, EnforcedStyle, AllowedExplicitMatchers.
# SupportedStyles: inflected, explicit
RSpec/PredicateMatcher:
Exclude:
- 'spec/tasks/members_spec.rb'
# Offense count: 2
RSpec/RepeatedDescription:
Exclude:
@@ -491,18 +433,18 @@ RSpec/ScatteredSetup:
- 'spec/features/percy/percy_spec.rb'
- 'spec/features/plantings/prediction_spec.rb'
# Offense count: 1
# Offense count: 2
# Configuration parameters: CustomTransform, IgnoreMethods, IgnoreMetadata, InflectorPath, EnforcedInflector.
# SupportedInflectors: default, active_support
RSpec/SpecFilePathFormat:
Exclude:
- 'spec/controllers/member_controller_spec.rb'
- 'spec/mailers/harvest_reminder_mailer_spec.rb'
# Offense count: 3
# Offense count: 2
RSpec/StubbedMock:
Exclude:
- 'spec/controllers/garden_types_controller_spec.rb'
- 'spec/controllers/gardens_controller_spec.rb'
- 'spec/controllers/photos_controller_spec.rb'
- 'spec/models/member_spec.rb'
# Offense count: 1
@@ -519,22 +461,12 @@ RSpec/VerifiedDoubles:
- 'spec/controllers/gardens_controller_spec.rb'
- 'spec/views/devise/shared/_links_spec.rb'
# Offense count: 7
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: ResponseMethods.
# ResponseMethods: response, last_response
RSpecRails/HaveHttpStatus:
Exclude:
- 'spec/controllers/api/v1/plantings_controller_spec.rb'
- 'spec/controllers/harvests_controller_spec.rb'
- 'spec/controllers/likes_controller_spec.rb'
- 'spec/requests/harvests_spec.rb'
# Offense count: 17
# Offense count: 1
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: Inferences.
RSpecRails/InferredSpecType:
Enabled: false
Exclude:
- 'spec/mailers/harvest_reminder_mailer_spec.rb'
# Offense count: 30
# Configuration parameters: Database.
@@ -592,14 +524,24 @@ Rails/HasManyOrHasOneDependent:
- 'app/models/crop.rb'
- 'app/models/member.rb'
# Offense count: 7
Rails/HelperInstanceVariable:
Exclude:
- 'app/helpers/crops_helper.rb'
- 'app/helpers/plantings_helper.rb'
# Offense count: 1
Rails/I18nLocaleAssignment:
Exclude:
- 'spec/features/locale_spec.rb'
# Offense count: 40
# Offense count: 5
Rails/I18nLocaleTexts:
Enabled: false
Exclude:
- 'app/controllers/blocks_controller.rb'
- 'app/controllers/comments_controller.rb'
- 'app/controllers/messages_controller.rb'
- 'config/initializers/comfortable_mexican_sofa.rb'
# Offense count: 1
# Configuration parameters: IgnoreScopes.
@@ -614,6 +556,12 @@ Rails/LexicallyScopedActionFilter:
- 'app/controllers/data_controller.rb'
- 'app/controllers/registrations_controller.rb'
# Offense count: 1
# This cop supports unsafe autocorrection (--autocorrect-all).
Rails/OrderArguments:
Exclude:
- 'app/models/activity.rb'
# Offense count: 2
Rails/OutputSafety:
Exclude:
@@ -642,7 +590,7 @@ Rails/RakeEnvironment:
- 'lib/tasks/i18n.rake'
- 'lib/tasks/testing.rake'
# Offense count: 9
# Offense count: 8
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: AllowedReceivers.
# AllowedReceivers: ActionMailer::Preview, ActiveSupport::TimeZone
@@ -655,7 +603,6 @@ Rails/RedundantActiveRecordAllMethod:
- 'app/controllers/scientific_names_controller.rb'
- 'spec/features/members/deletion_spec.rb'
- 'spec/features/percy/percy_spec.rb'
- 'spec/models/harvest_spec.rb'
# Offense count: 5
# This cop supports unsafe autocorrection (--autocorrect-all).
@@ -697,15 +644,6 @@ Rails/RootPathnameMethods:
- 'lib/tasks/import.rake'
- 'spec/rails_helper.rb'
# Offense count: 4
# Configuration parameters: ForbiddenMethods, AllowedMethods.
# ForbiddenMethods: decrement!, decrement_counter, increment!, increment_counter, insert, insert!, insert_all, insert_all!, toggle!, touch, touch_all, update_all, update_attribute, update_column, update_columns, update_counters, upsert, upsert_all
Rails/SkipsModelValidations:
Exclude:
- 'db/migrate/20240101010102_populate_crop_fields_from_openfarm_data.rb'
- 'db/migrate/20240810160538_set_default_language_for_existing_alternate_names.rb'
- 'db/migrate/20251128200506_add_description_to_crops.rb'
# Offense count: 21
Rails/ThreeStateBooleanColumn:
Enabled: false
@@ -737,12 +675,6 @@ Rails/WhereEquals:
- 'app/models/harvest.rb'
- 'app/models/planting.rb'
# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
Rails/WhereMissing:
Exclude:
- 'app/controllers/crops_controller.rb'
# Offense count: 3
# This cop supports unsafe autocorrection (--autocorrect-all).
Rails/WhereRange:
@@ -756,7 +688,7 @@ Rake/MethodDefinitionInTask:
Exclude:
- 'lib/tasks/growstuff.rake'
# Offense count: 4
# Offense count: 5
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: EnforcedStyle, EnforcedStyleForClasses, EnforcedStyleForModules.
# SupportedStyles: nested, compact
@@ -765,10 +697,17 @@ Rake/MethodDefinitionInTask:
Style/ClassAndModuleChildren:
Exclude:
- 'app/controllers/admin/crops_controller.rb'
- 'config/initializers/rack_attack.rb'
- 'lib/actions/oauth_signup_action.rb'
- 'lib/haml/filters/escaped_markdown.rb'
- 'lib/haml/filters/growstuff_markdown.rb'
# Offense count: 1
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/CollectionQuerying:
Exclude:
- 'app/models/member.rb'
# Offense count: 6
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/CommentedKeyword:
@@ -799,12 +738,14 @@ Style/FloatDivision:
Exclude:
- 'app/models/concerns/predict_planting.rb'
# Offense count: 22
# Offense count: 2
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: EnforcedStyle.
# SupportedStyles: always, always_true, never
Style/FrozenStringLiteralComment:
Enabled: false
Exclude:
- 'db/migrate/20260429132911_add_send_harvest_reminder_to_members.rb'
- 'spec/lib/haml/filters/growstuff_markdown_spec.rb'
# Offense count: 2
# This cop supports unsafe autocorrection (--autocorrect-all).
@@ -819,11 +760,14 @@ Style/IdenticalConditionalBranches:
Exclude:
- 'lib/actions/oauth_signup_action.rb'
# Offense count: 1
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/MapIntoArray:
# Offense count: 4
# This cop supports safe autocorrection (--autocorrect).
Style/IfUnlessModifier:
Exclude:
- 'app/helpers/crops_helper.rb'
- 'app/models/concerns/predict_planting.rb'
- 'config/initializers/rack_attack.rb'
- 'lib/tasks/growstuff.rake'
# Offense count: 1
# This cop supports unsafe autocorrection (--autocorrect-all).
@@ -870,13 +814,6 @@ Style/OptionalBooleanParameter:
- 'app/helpers/application_helper.rb'
- 'app/models/concerns/member_newsletter.rb'
# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: PreferredDelimiters.
Style/PercentLiteralDelimiters:
Exclude:
- 'db/migrate/20251130035700_create_versions.rb'
# Offense count: 1
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: Methods.
@@ -884,6 +821,13 @@ Style/RedundantArgument:
Exclude:
- 'app/helpers/application_helper.rb'
# Offense count: 3
# This cop supports safe autocorrection (--autocorrect).
Style/RedundantBegin:
Exclude:
- 'app/models/concerns/predict_harvest.rb'
- 'app/models/harvest.rb'
# Offense count: 4
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: SafeForConstants.
+1 -1
View File
@@ -1 +1 @@
3.4.8
3.4.9
-3
View File
@@ -248,6 +248,3 @@ linters:
ZeroUnit:
enabled: true
Compass::*:
enabled: false
+52
View File
@@ -0,0 +1,52 @@
FROM ruby:3.4.9-trixie
# Install system dependencies
RUN apt-get update -qq && \
apt-get install -y --no-install-recommends \
build-essential \
libpq-dev \
git \
curl \
gnupg2 \
shared-mime-info \
libvips \
&& curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
&& apt-get install -y --no-install-recommends nodejs \
&& npm install -g yarn \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Set production environment
ENV RAILS_ENV=production \
BUNDLE_WITHOUT="development test" \
RAILS_SERVE_STATIC_FILES=true \
RAILS_LOG_TO_STDOUT=true
WORKDIR /app
# Install gems
COPY Gemfile Gemfile.lock .ruby-version ./
RUN bundle config set --local deployment 'true' && \
bundle config set --local without 'development test' && \
bundle install --jobs 4 --retry 3
# Install JavaScript dependencies
COPY package.json yarn.lock ./
RUN yarn install --check-files
# Copy the application code
COPY . .
# Precompile assets
# Secret key base is needed for asset compilation but doesn't need to be the real one
RUN RAILS_ENV=production SECRET_KEY_BASE_DUMMY=1 bundle exec rake assets:precompile
# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
# Start the main process.
CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]
+4 -2
View File
@@ -5,7 +5,7 @@ source 'https://rubygems.org'
# Match ruby version in .ruby-version
ruby File.read('.ruby-version')
gem 'rails', '~> 7.2.0'
gem 'rails', '~> 8.0.0'
# Keeping old sprockets
# https://github.com/rails/sprockets-rails/issues/444#issuecomment-637817050
@@ -116,6 +116,8 @@ gem 'xmlrpc' # fixes rake error - can be removed if not needed later
gem 'puma'
gem 'rack-attack'
gem 'loofah', '>= 2.19.1'
gem 'rack-protection', '>= 2.0.1'
@@ -204,5 +206,5 @@ gem "i18n_data", "~> 1.1"
gem "paper_trail", "~> 17.0"
gem 'sitemap_generator'
gem 'aws-sdk-s3', '~> 1', '>= 1.114.0'
gem 'sitemap_generator'
+146 -161
View File
@@ -33,49 +33,46 @@ GEM
GEM
remote: https://rubygems.org/
specs:
actioncable (7.2.3.1)
actionpack (= 7.2.3.1)
activesupport (= 7.2.3.1)
actioncable (8.0.5.1)
actionpack (= 8.0.5.1)
activesupport (= 8.0.5.1)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
zeitwerk (~> 2.6)
actionmailbox (7.2.3.1)
actionpack (= 7.2.3.1)
activejob (= 7.2.3.1)
activerecord (= 7.2.3.1)
activestorage (= 7.2.3.1)
activesupport (= 7.2.3.1)
actionmailbox (8.0.5.1)
actionpack (= 8.0.5.1)
activejob (= 8.0.5.1)
activerecord (= 8.0.5.1)
activestorage (= 8.0.5.1)
activesupport (= 8.0.5.1)
mail (>= 2.8.0)
actionmailer (7.2.3.1)
actionpack (= 7.2.3.1)
actionview (= 7.2.3.1)
activejob (= 7.2.3.1)
activesupport (= 7.2.3.1)
actionmailer (8.0.5.1)
actionpack (= 8.0.5.1)
actionview (= 8.0.5.1)
activejob (= 8.0.5.1)
activesupport (= 8.0.5.1)
mail (>= 2.8.0)
rails-dom-testing (~> 2.2)
actionpack (7.2.3.1)
actionview (= 7.2.3.1)
activesupport (= 7.2.3.1)
cgi
actionpack (8.0.5.1)
actionview (= 8.0.5.1)
activesupport (= 8.0.5.1)
nokogiri (>= 1.8.5)
racc
rack (>= 2.2.4, < 3.3)
rack (>= 2.2.4)
rack-session (>= 1.0.1)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
useragent (~> 0.16)
actiontext (7.2.3.1)
actionpack (= 7.2.3.1)
activerecord (= 7.2.3.1)
activestorage (= 7.2.3.1)
activesupport (= 7.2.3.1)
actiontext (8.0.5.1)
actionpack (= 8.0.5.1)
activerecord (= 8.0.5.1)
activestorage (= 8.0.5.1)
activesupport (= 8.0.5.1)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
actionview (7.2.3.1)
activesupport (= 7.2.3.1)
actionview (8.0.5.1)
activesupport (= 8.0.5.1)
builder (~> 3.1)
cgi
erubi (~> 1.11)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
@@ -89,22 +86,22 @@ GEM
active_utils (3.6.0)
activesupport (>= 4.2)
i18n
activejob (7.2.3.1)
activesupport (= 7.2.3.1)
activejob (8.0.5.1)
activesupport (= 8.0.5.1)
globalid (>= 0.3.6)
activemodel (7.2.3.1)
activesupport (= 7.2.3.1)
activerecord (7.2.3.1)
activemodel (= 7.2.3.1)
activesupport (= 7.2.3.1)
activemodel (8.0.5.1)
activesupport (= 8.0.5.1)
activerecord (8.0.5.1)
activemodel (= 8.0.5.1)
activesupport (= 8.0.5.1)
timeout (>= 0.4.0)
activestorage (7.2.3.1)
actionpack (= 7.2.3.1)
activejob (= 7.2.3.1)
activerecord (= 7.2.3.1)
activesupport (= 7.2.3.1)
activestorage (8.0.5.1)
actionpack (= 8.0.5.1)
activejob (= 8.0.5.1)
activerecord (= 8.0.5.1)
activesupport (= 8.0.5.1)
marcel (~> 1.0)
activesupport (7.2.3.1)
activesupport (8.0.5.1)
base64
benchmark (>= 0.3)
bigdecimal
@@ -113,17 +110,18 @@ GEM
drb
i18n (>= 1.6, < 2)
logger (>= 1.4.2)
minitest (>= 5.1, < 6)
minitest (>= 5.1)
securerandom (>= 0.3)
tzinfo (~> 2.0, >= 2.0.5)
uri (>= 0.13.1)
addressable (2.9.0)
public_suffix (>= 2.0.2, < 8.0)
ast (2.4.3)
autoprefixer-rails (10.4.16.0)
execjs (~> 2)
aws-eventstream (1.4.0)
aws-partitions (1.1240.0)
aws-sdk-core (3.245.0)
aws-partitions (1.1277.0)
aws-sdk-core (3.254.0)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.992.0)
aws-sigv4 (~> 1.9)
@@ -131,31 +129,21 @@ GEM
bigdecimal
jmespath (~> 1, >= 1.6.1)
logger
aws-sdk-kms (1.123.0)
aws-sdk-core (~> 3, >= 3.244.0)
aws-sdk-kms (1.130.0)
aws-sdk-core (~> 3, >= 3.254.0)
aws-sigv4 (~> 1.5)
aws-sdk-s3 (1.220.0)
aws-sdk-core (~> 3, >= 3.244.0)
aws-sdk-s3 (1.228.2)
aws-sdk-core (~> 3, >= 3.254.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.5)
aws-sigv4 (1.12.1)
aws-eventstream (~> 1, >= 1.0.2)
axe-core-api (4.11.2)
axe-core-api (4.12.0)
dumb_delegator
ostruct
virtus
axe-core-capybara (4.11.2)
axe-core-api (= 4.11.2)
dumb_delegator
axe-core-rspec (4.11.2)
axe-core-api (= 4.11.2)
dumb_delegator
ostruct
virtus
axiom-types (0.1.1)
descendants_tracker (~> 0.0.4)
ice_nine (~> 0.11.0)
thread_safe (~> 0.3, >= 0.3.1)
axe-core-capybara (4.12.0)
axe-core-api (= 4.12.0)
axe-core-rspec (4.12.0)
axe-core-api (= 4.12.0)
base64 (0.3.0)
bcrypt (3.1.22)
benchmark (0.5.0)
@@ -177,7 +165,7 @@ GEM
actionpack (>= 6.1)
activemodel (>= 6.1)
builder (3.3.0)
bullet (8.1.1)
bullet (8.1.3)
activesupport (>= 3.0.0)
uniform_notifier (~> 1.11)
byebug (13.0.0)
@@ -198,20 +186,17 @@ GEM
capybara-screenshot (1.0.27)
capybara (>= 1.0, < 4)
launchy
carrierwave (3.0.7)
carrierwave (3.1.3)
activemodel (>= 6.0.0)
activesupport (>= 6.0.0)
addressable (~> 2.6)
image_processing (~> 1.1)
marcel (~> 1.0.0)
ssrf_filter (~> 1.0)
cgi (0.5.1)
chartkick (5.2.1)
childprocess (5.1.0)
logger (~> 1.5)
coderay (1.1.3)
coercible (1.0.0)
descendants_tracker (~> 0.0.1)
coffee-rails (5.0.0)
coffee-script (>= 2.2.0)
railties (>= 5.2.0)
@@ -221,9 +206,9 @@ GEM
coffee-script-source (1.12.2)
comfy_bootstrap_form (4.0.9)
rails (>= 5.0.0)
concurrent-ruby (1.3.6)
concurrent-ruby (1.3.8)
connection_pool (2.5.5)
crass (1.0.6)
crass (1.0.7)
crowdin-api (1.12.0)
open-uri (>= 0.1.0, < 0.2.0)
rest-client (>= 2.0.0, < 2.2.0)
@@ -236,7 +221,7 @@ GEM
csv_shaper (1.4.0)
activesupport (>= 3.0.0)
csv
dalli (5.0.2)
dalli (5.0.6)
logger
database_cleaner (2.1.0)
database_cleaner-active_record (>= 2, < 3)
@@ -245,17 +230,15 @@ GEM
database_cleaner-core (~> 2.0.0)
database_cleaner-core (2.0.1)
date (3.5.1)
descendants_tracker (0.0.4)
thread_safe (~> 0.3, >= 0.3.1)
devise (5.0.3)
devise (5.0.4)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 7.0)
responders
warden (~> 1.2.3)
diff-lcs (1.6.2)
discard (1.4.0)
activerecord (>= 4.2, < 9.0)
discard (2.0.0)
activerecord (>= 7.0, < 9.0)
domain_name (0.6.20240107)
dotenv (3.2.0)
dotenv-rails (3.2.0)
@@ -276,9 +259,9 @@ GEM
elasticsearch-transport (7.0.0)
faraday
multi_json
erb (6.0.2)
erb (6.0.6)
erubi (1.13.1)
execjs (2.10.0)
execjs (2.10.1)
factory_bot (6.5.5)
activesupport (>= 6.1.0)
factory_bot_rails (6.5.1)
@@ -286,18 +269,18 @@ GEM
railties (>= 6.1.0)
faker (3.8.0)
i18n (>= 1.8.11, < 2)
faraday (2.14.1)
faraday (2.14.3)
faraday-net_http (>= 2.0, < 3.5)
json
logger
faraday-net_http (3.4.2)
faraday-net_http (3.4.4)
net-http (~> 0.5)
ffi (1.17.3)
ffi (1.17.3-x86_64-linux-gnu)
ffi (1.17.4)
ffi (1.17.4-x86_64-linux-gnu)
flickraw (0.9.10)
font-awesome-sass (5.15.1)
sassc (>= 1.11)
friendly_id (5.6.0)
friendly_id (5.7.0)
activerecord (>= 4.0.0)
gbifrb (0.2.0)
geocoder (1.8.6)
@@ -308,21 +291,21 @@ GEM
multi_json (>= 1.9.0)
gli (2.22.2)
ostruct
globalid (1.3.0)
globalid (1.4.0)
activesupport (>= 6.1)
gravatar-ultimate (2.0.0)
activesupport (>= 2.3.14)
rack
haml (7.2.0)
haml (7.2.2)
temple (>= 0.8.2)
thor
tilt
haml-rails (3.0.0)
haml-rails (3.1.0)
actionpack (>= 5.1)
activesupport (>= 5.1)
haml (>= 4.0.6)
railties (>= 5.1)
haml_lint (0.73.0)
haml_lint (0.76.0)
haml (>= 5.0)
parallel (>= 1.10)
rainbow
@@ -339,7 +322,7 @@ GEM
csv
mini_mime (>= 1.0.0)
multi_xml (>= 0.5.2)
i18n (1.14.8)
i18n (1.15.2)
concurrent-ruby (~> 1.0)
i18n-tasks (1.1.2)
activesupport (>= 4.0.2)
@@ -355,18 +338,17 @@ GEM
terminal-table (>= 1.5.1)
i18n_data (1.1.0)
simple_po_parser (~> 1.1)
icalendar (2.12.2)
icalendar (2.12.4)
base64
ice_cube (~> 0.16)
logger
ostruct
ice_cube (0.17.0)
ice_nine (0.11.2)
image_processing (1.12.2)
mini_magick (>= 4.9.5, < 5)
image_processing (1.14.0)
mini_magick (>= 4.9.5, < 6)
ruby-vips (>= 2.0.17, < 3)
io-console (0.8.2)
irb (1.17.0)
irb (1.18.0)
pp (>= 0.6.0)
prism (>= 1.3.0)
rdoc (>= 4.0.0)
@@ -376,7 +358,7 @@ GEM
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
json (2.19.3)
json (2.21.2)
json-schema (6.2.0)
addressable (~> 2.8)
bigdecimal (>= 3.1, < 5)
@@ -388,7 +370,7 @@ GEM
kgio (2.11.4)
kramdown (2.4.0)
rexml
language_server-protocol (3.17.0.5)
language_server-protocol (3.17.0.6)
launchy (3.1.1)
addressable (~> 2.8)
childprocess (~> 5.0)
@@ -404,10 +386,10 @@ GEM
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
logger (1.7.0)
loofah (2.25.1)
loofah (2.25.2)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
mail (2.9.0)
mail (2.9.1)
logger
mini_mime (>= 0.1.1)
net-imap
@@ -432,17 +414,20 @@ GEM
mimemagic (0.4.3)
nokogiri (~> 1)
rake
mini_magick (4.12.0)
mini_magick (5.3.1)
logger
mini_mime (1.1.5)
mini_portile2 (2.8.9)
minitest (5.27.0)
msgpack (1.8.0)
minitest (6.0.6)
drb (~> 2.0)
prism (~> 1.5)
msgpack (1.8.4)
multi_json (1.19.1)
multi_xml (0.8.1)
bigdecimal (>= 3.1, < 5)
net-http (0.9.1)
uri (>= 0.11.1)
net-imap (0.5.12)
net-imap (0.6.6)
date
net-protocol
net-pop (0.1.2)
@@ -453,13 +438,13 @@ GEM
net-protocol
netrc (0.11.0)
nio4r (2.7.5)
nokogiri (1.19.2)
nokogiri (1.19.4)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
nokogiri (1.19.2-x86_64-linux-gnu)
nokogiri (1.19.4-x86_64-linux-gnu)
racc (~> 1.4)
oauth (0.5.6)
oj (3.17.0)
oj (3.17.5)
bigdecimal (>= 3.0)
ostruct (>= 0.2)
omniauth (1.9.2)
@@ -477,16 +462,16 @@ GEM
paper_trail (17.0.0)
activerecord (>= 7.1)
request_store (~> 1.4)
parallel (2.0.1)
parser (3.3.11.1)
parallel (2.1.0)
parser (3.3.12.0)
ast (~> 2.4.1)
racc
percy-capybara (5.0.0)
percy-capybara (5.0.1)
capybara (>= 3)
pg (1.6.3)
pg (1.6.3-x86_64-linux)
popper_js (2.11.8)
pp (0.6.3)
pp (0.6.4)
prettyprint
prettyprint (0.2.0)
prism (1.9.0)
@@ -494,15 +479,14 @@ GEM
coderay (~> 1.1)
method_source (~> 1.0)
reline (>= 0.6.0)
psych (5.3.1)
date
stringio
public_suffix (7.0.5)
puma (7.2.0)
puma (8.0.2)
nio4r (~> 2.0)
query_diet (0.7.3)
racc (1.8.1)
rack (2.2.23)
rack-attack (6.8.0)
rack (>= 1.0, < 4)
rack-cors (2.0.2)
rack (>= 2.0.0)
rack-protection (3.2.0)
@@ -515,20 +499,20 @@ GEM
rackup (1.0.1)
rack (< 3)
webrick
rails (7.2.3.1)
actioncable (= 7.2.3.1)
actionmailbox (= 7.2.3.1)
actionmailer (= 7.2.3.1)
actionpack (= 7.2.3.1)
actiontext (= 7.2.3.1)
actionview (= 7.2.3.1)
activejob (= 7.2.3.1)
activemodel (= 7.2.3.1)
activerecord (= 7.2.3.1)
activestorage (= 7.2.3.1)
activesupport (= 7.2.3.1)
rails (8.0.5.1)
actioncable (= 8.0.5.1)
actionmailbox (= 8.0.5.1)
actionmailer (= 8.0.5.1)
actionpack (= 8.0.5.1)
actiontext (= 8.0.5.1)
actionview (= 8.0.5.1)
activejob (= 8.0.5.1)
activemodel (= 8.0.5.1)
activerecord (= 8.0.5.1)
activestorage (= 8.0.5.1)
activesupport (= 8.0.5.1)
bundler (>= 1.15.0)
railties (= 7.2.3.1)
railties (= 8.0.5.1)
rails-controller-testing (1.0.5)
actionpack (>= 5.0.1.rc1)
actionview (>= 5.0.1.rc1)
@@ -537,21 +521,20 @@ GEM
activesupport (>= 5.0.0)
minitest
nokogiri (>= 1.6)
rails-html-sanitizer (1.7.0)
loofah (~> 2.25)
rails-html-sanitizer (1.7.1)
loofah (~> 2.25, >= 2.25.2)
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
rails-i18n (7.0.10)
rails-i18n (8.1.0)
i18n (>= 0.7, < 2)
railties (>= 6.0.0, < 8)
railties (>= 8.0.0, < 9)
rails_12factor (0.0.3)
rails_serve_static_assets
rails_stdout_logging
rails_serve_static_assets (0.0.5)
rails_stdout_logging (0.0.5)
railties (7.2.3.1)
actionpack (= 7.2.3.1)
activesupport (= 7.2.3.1)
cgi
railties (8.0.5.1)
actionpack (= 8.0.5.1)
activesupport (= 8.0.5.1)
irb (~> 1.13)
rackup (>= 1.0.0)
rake (>= 12.2)
@@ -564,9 +547,14 @@ GEM
rb-fsevent (0.11.2)
rb-inotify (0.11.1)
ffi (~> 1.0)
rdoc (7.2.0)
rbs (4.1.0)
logger
prism (>= 1.6.0)
tsort
rdoc (8.0.0)
erb
psych (>= 4.0.0)
prism (>= 1.6.0)
rbs (>= 4.0.0)
tsort
recaptcha (5.21.2)
redis-client (0.26.2)
@@ -628,7 +616,7 @@ GEM
rswag-ui (2.17.0)
actionpack (>= 5.2, < 8.2)
railties (>= 5.2, < 8.2)
rubocop (1.86.1)
rubocop (1.88.2)
json (~> 2.3)
language_server-protocol (~> 3.17.0.2)
lint_roller (~> 1.1.0)
@@ -639,16 +627,16 @@ GEM
rubocop-ast (>= 1.49.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 4.0)
rubocop-ast (1.49.1)
rubocop-ast (1.50.0)
parser (>= 3.3.7.2)
prism (~> 1.7)
rubocop-capybara (2.22.1)
rubocop-capybara (3.0.0)
lint_roller (~> 1.1)
rubocop (~> 1.72, >= 1.72.1)
rubocop (~> 1.81)
rubocop-factory_bot (2.28.0)
lint_roller (~> 1.1)
rubocop (~> 1.72, >= 1.72.1)
rubocop-rails (2.34.3)
rubocop-rails (2.36.0)
activesupport (>= 4.2.0)
lint_roller (~> 1.1)
rack (>= 1.1)
@@ -657,18 +645,20 @@ GEM
rubocop-rake (0.7.1)
lint_roller (~> 1.1)
rubocop (>= 1.72.1)
rubocop-rspec (3.9.0)
rubocop-rspec (3.10.2)
lint_roller (~> 1.1)
rubocop (~> 1.81)
regexp_parser (>= 2.0)
rubocop (~> 1.86, >= 1.86.2)
rubocop-rspec_rails (2.32.0)
lint_roller (~> 1.1)
rubocop (~> 1.72, >= 1.72.1)
rubocop-rspec (~> 3.5)
ruby-progressbar (1.13.0)
ruby-units (4.1.0)
ruby-vips (2.2.1)
ruby-vips (2.3.0)
ffi (~> 1.12)
rubyzip (3.2.2)
logger
rubyzip (3.4.1)
sass (3.7.4)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
@@ -682,13 +672,13 @@ GEM
sprockets (> 3.0)
sprockets-rails
tilt
scout_apm (6.2.0)
scout_apm (6.2.1)
parser
searchkick (5.3.1)
activemodel (>= 6.1)
hashie
securerandom (0.4.1)
selenium-webdriver (4.43.0)
selenium-webdriver (4.46.0)
base64 (~> 0.2)
logger (~> 1.4)
rexml (~> 3.2, >= 3.2.5)
@@ -701,7 +691,7 @@ GEM
rack (>= 2.2.4, < 3.3)
redis-client (>= 0.23.0, < 1)
simple_po_parser (1.1.6)
sitemap_generator (6.3.0)
sitemap_generator (7.1.1)
builder (~> 3.0)
sprockets (3.7.5)
base64
@@ -711,19 +701,17 @@ GEM
actionpack (>= 5.2)
activesupport (>= 5.2)
sprockets (>= 3.0.0)
ssrf_filter (1.1.2)
stringio (3.2.0)
ssrf_filter (1.5.0)
sysexits (1.2.0)
temple (0.10.4)
terminal-table (4.0.0)
unicode-display_width (>= 1.1.1, < 4)
terser (1.2.7)
terser (1.2.8)
execjs (>= 0.3.0, < 3)
thor (1.5.0)
thread_safe (0.3.6)
tilt (2.7.0)
tilt (2.8.0)
timecop (0.9.11)
timeout (0.5.0)
timeout (0.6.1)
tsort (0.2.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
@@ -740,10 +728,6 @@ GEM
activemodel (>= 3.0.0)
public_suffix
vcr (6.4.0)
virtus (2.0.0)
axiom-types (~> 0.1)
coercible (~> 1.0)
descendants_tracker (~> 0.0, >= 0.0.3)
warden (1.2.9)
rack (>= 2.0.9)
webrat (0.7.3)
@@ -752,7 +736,7 @@ GEM
rack-test (>= 0.5.3)
webrick (1.9.2)
websocket (1.2.11)
websocket-driver (0.8.0)
websocket-driver (0.8.2)
base64
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
@@ -764,7 +748,7 @@ GEM
webrick
xpath (3.2.0)
nokogiri (~> 1.8)
zeitwerk (2.7.5)
zeitwerk (2.8.2)
PLATFORMS
ruby
@@ -841,9 +825,10 @@ DEPENDENCIES
pry
puma
query_diet
rack-attack
rack-cors
rack-protection (>= 2.0.1)
rails (~> 7.2.0)
rails (~> 8.0.0)
rails-assets-leaflet.markercluster!
rails-controller-testing
rails_12factor
@@ -883,7 +868,7 @@ DEPENDENCIES
xmlrpc
RUBY VERSION
ruby 3.4.8p72
ruby 3.4.9
BUNDLED WITH
2.4.22
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "growstuff",
"stack": "heroku-18",
"stack": "heroku-26",
"description": "Open data project for small-scale food growers",
"scripts": {
"postdeploy": "bundle exec rails db:seed"
+7 -12
View File
@@ -4,21 +4,16 @@ class ActivitiesController < DataController
def index
@show_all = params[:all] == '1'
where = {}
where['active'] = true unless @show_all
@activities = Activity.includes(:owner).order(created_at: :desc)
@activities = @activities.active unless @show_all
if params[:member_slug]
@owner = Member.find_by(slug: params[:member_slug])
where['owner_id'] = @owner.id unless @owner.nil?
if params[:member_slug].present?
@owner = Member.find_by!(slug: params[:member_slug])
@activities = @activities.where(owner_id: @owner.id)
end
@activities = Activity.search(
where:,
page: params[:page],
limit: 30,
boost_by: [:created_at],
load: false
)
@activities = @activities.paginate(page: params[:page], per_page: 30)
@filename = "Growstuff-#{specifics}Activities-#{Time.zone.now.to_fs(:number)}.csv"
respond_with(@activities)
end
@@ -15,7 +15,7 @@ module Admin
def create
@crop_companion = @crop.crop_companions.new(crop_companion_params)
if @crop_companion.save
redirect_to admin_crop_crop_companions_path(@crop), notice: 'Companion was successfully created.'
redirect_to admin_crop_crop_companions_path(@crop), notice: t('crop_companions.created')
else
render :new
end
@@ -24,7 +24,7 @@ module Admin
def destroy
@crop_companion = @crop.crop_companions.find(params[:id])
@crop_companion.destroy
redirect_to admin_crop_crop_companions_path(@crop), notice: 'Companion was successfully destroyed.'
redirect_to admin_crop_crop_companions_path(@crop), notice: t('crop_companions.deleted')
end
private
+3 -3
View File
@@ -8,9 +8,9 @@ module Admin
responders :flash
def index
@members = Member.all
@members = @members.where("login_name ILIKE ?", "%#{search_term}%") unless search_term.nil?
@members = @members.order(:login_name).paginate(page: params[:page])
@members = Member.order(:login_name)
@members = @members.where("login_name ILIKE ?", "%#{search_term}%") if search_term.present?
@members = @members.paginate(page: params[:page])
end
def edit
+2 -2
View File
@@ -9,9 +9,9 @@ module Admin
@version = PaperTrail::Version.find(params[:id])
@object = @version.reify
if @object.save
redirect_to admin_crops_path, notice: "Reverted to version from #{@version.created_at.strftime('%B %d, %Y')}"
redirect_to admin_crops_path, notice: t('messages.revert_success', date: @version.created_at.strftime('%B %d, %Y'))
else
redirect_to admin_crops_path, alert: "Could not revert to version from #{@version.created_at.strftime('%B %d, %Y')}. Errors: #{@object.errors.full_messages.to_sentence}"
redirect_to admin_crops_path, alert: t('messages.revert_error', date: @version.created_at.strftime('%B %d, %Y'), errors: @object.errors.full_messages.to_sentence)
end
end
@@ -30,7 +30,7 @@ class AlternateNamesController < ApplicationController
@alternate_name = AlternateName.new(alternate_name_params)
if @alternate_name.save
redirect_to @alternate_name.crop, notice: 'Alternate name was successfully created.'
redirect_to @alternate_name.crop, notice: t('alternate_names.created')
else
render action: "new"
end
@@ -40,7 +40,7 @@ class AlternateNamesController < ApplicationController
# PUT /alternate_names/1.json
def update
if @alternate_name.update(alternate_name_params)
redirect_to @alternate_name.crop, notice: 'Alternate name was successfully updated.'
redirect_to @alternate_name.crop, notice: t('alternate_names.updated')
else
render action: "edit"
end
@@ -51,7 +51,7 @@ class AlternateNamesController < ApplicationController
def destroy
@crop = @alternate_name.crop
@alternate_name.destroy
redirect_to @crop, notice: 'Alternate name was successfully deleted.'
redirect_to @crop, notice: t('alternate_names.deleted')
end
private
@@ -3,6 +3,36 @@
module Api
module V1
class CropsController < BaseController
def search
term = params[:term]
page = params.dig(:page, :number) || 1
per_page = params.dig(:page, :size) || Crop.per_page
search_results = CropSearchService.search(
term,
page: page,
per_page: per_page,
load: true
)
resources = search_results.map do |crop|
Api::V1::CropResource.new(crop, context)
end
serializer = JSONAPI::ResourceSerializer.new(Api::V1::CropResource)
data = resources.map do |resource|
serializer.object_hash(resource, {})
end
render json: {
data: data,
meta: {
record_count: search_results.total_count,
page_count: search_results.total_pages
}
}
end
end
end
end
+2 -2
View File
@@ -68,7 +68,7 @@ class ApplicationController < ActionController::Base
# profile stuff
:bio, :location, :latitude, :longitude,
# email settings
:show_email, :newsletter, :send_notification_email, :send_planting_reminder)
:show_email, :newsletter, :send_notification_email, :send_planting_reminder, :send_harvest_reminder)
end
devise_parameter_sanitizer.permit(:account_update) do |member|
@@ -80,7 +80,7 @@ class ApplicationController < ActionController::Base
:bio, :location, :latitude, :longitude,
:website_url, :instagram_handle, :facebook_handle, :bluesky_handle, :other_url,
# email settings
:show_email, :newsletter, :send_notification_email, :send_planting_reminder,
:show_email, :newsletter, :send_notification_email, :send_planting_reminder, :send_harvest_reminder,
# update password
:current_password)
end
@@ -24,9 +24,9 @@ class AuthenticationsController < ApplicationController
name:
)
flash[:notice] = "Authentication successful."
flash[:notice] = t('messages.auth_success')
else
flash[:notice] = "Authentication failed."
flash[:notice] = t('messages.auth_failed')
end
redirect_to request.env['omniauth.origin'] || edit_member_registration_path
end
+32
View File
@@ -0,0 +1,32 @@
# frozen_string_literal: true
class BlocksController < ApplicationController
load_and_authorize_resource
skip_load_resource only: :create
def create
@block = current_member.blocks.build(blocked: Member.find(params[:blocked]))
if @block.save
flash[:notice] = "Blocked #{@block.blocked.login_name}"
else
flash[:error] = "Already blocking or error while blocking."
end
redirect_back_or_to(root_path)
end
def destroy
@block = current_member.blocks.find(params[:id])
@unblocked = @block.blocked
@block.destroy
flash[:notice] = "Unblocked #{@unblocked.login_name}"
redirect_to @unblocked
end
private
def block_params
params.permit(:id, :blocked)
end
end
+18 -9
View File
@@ -3,6 +3,7 @@
module Charts
class CropsController < ApplicationController
respond_to :json
before_action :set_crop
def sunniness
pie_chart_query 'sunniness'
@@ -13,20 +14,28 @@ module Charts
end
def harvested_for
@crop = Crop.find_by!(slug: params[:crop_slug])
render json: Harvest.joins(:plant_part)
.where(crop: @crop)
.group("plant_parts.name").count(:id)
data = Rails.cache.fetch("#{@crop.cache_key_with_version}/harvested_for", expires_in: 1.day) do
Harvest.joins(:plant_part)
.where(crop: @crop)
.group("plant_parts.name").count(:id)
end
render json: data
end
private
def pie_chart_query(field)
def set_crop
@crop = Crop.find_by!(slug: params[:crop_slug])
render json: Planting.where(crop: @crop)
.where.not(field.to_sym => nil)
.where.not(field.to_sym => '')
.group(field.to_sym).count(:id)
end
def pie_chart_query(field)
data = Rails.cache.fetch("#{@crop.cache_key_with_version}/#{field}", expires_in: 1.day) do
Planting.where(crop: @crop)
.where.not(field.to_sym => nil)
.where.not(field.to_sym => '')
.group(field.to_sym).count(:id)
end
render json: data
end
end
end
+2 -2
View File
@@ -13,7 +13,7 @@ class CropsController < ApplicationController
@crops = Crop.search('*', boost_by: %i(plantings_count harvests_count),
limit: 100,
page: params[:page],
load: false)
load: (request.format.csv? || request.format.rss? ? { include: %i(parent scientific_names seeds harvests creator plantings) } : false))
@num_requested_crops = requested_crops.size if current_member
@filename = filename
respond_with @crops
@@ -160,7 +160,7 @@ class CropsController < ApplicationController
when 'youtube'
Crop.approved.where(en_youtube_url: [nil, '']).order(plantings_count: :desc)
when 'alternate_names'
Crop.approved.left_joins(:alternate_names).where(alternate_names: { id: nil }).order(plantings_count: :desc)
Crop.approved.where.missing(:alternate_names).order(plantings_count: :desc)
when 'wikidata'
crops_with_wikidata = Crop.joins(:scientific_names).where.not(scientific_names: { wikidata_id: nil }).distinct
Crop.approved.where.not(id: crops_with_wikidata).order(plantings_count: :desc)
+3 -3
View File
@@ -13,9 +13,9 @@ class FollowsController < ApplicationController
@follow = current_member.follows.build(followed: Member.find(params[:followed]))
if @follow.save
flash[:notice] = "Followed #{@follow.followed.login_name}"
flash[:notice] = t('messages.followed', name: @follow.followed.login_name)
else
flash[:error] = "Already following or error while following."
flash[:error] = t('messages.follow_error')
end
redirect_back_or_to(root_path)
end
@@ -25,7 +25,7 @@ class FollowsController < ApplicationController
@unfollowed = @follow.followed
@follow.destroy
flash[:notice] = "Unfollowed #{@unfollowed.login_name}"
flash[:notice] = t('messages.unfollowed', name: @unfollowed.login_name)
redirect_to @unfollowed
end
+3 -3
View File
@@ -32,14 +32,14 @@ class ForumsController < ApplicationController
# POST /forums.json
def create
@forum = Forum.new(forum_params)
flash[:notice] = 'Forum was successfully created.' if @forum.save
flash[:notice] = t('forums.created') if @forum.save
respond_with(@forum)
end
# PUT /forums/1
# PUT /forums/1.json
def update
flash[:notice] = 'Forum was successfully updated.' if @forum.update(forum_params)
flash[:notice] = t('forums.updated') if @forum.update(forum_params)
respond_with(@forum)
end
@@ -47,7 +47,7 @@ class ForumsController < ApplicationController
# DELETE /forums/1.json
def destroy
@forum.destroy
flash[:notice] = 'Forum was successfully deleted'
flash[:notice] = t('forums.deleted')
redirect_to forums_url
end
+13 -2
View File
@@ -2,7 +2,7 @@
class GardensController < DataController
def index
@owner = Member.find_by(slug: params[:member_slug])
@owner = Member.find_by!(slug: params[:member_slug]) if params[:member_slug].present?
@show_all = params[:all] == '1'
@show_jump_to = params[:member_slug].present? || false
@@ -57,12 +57,23 @@ class GardensController < DataController
redirect_to(member_gardens_path(@garden.owner))
end
def fetch_wikidata
if @garden.populate_wikidata_info
@garden.save
flash[:notice] = "Wikidata information updated."
else
flash[:alert] = "Could not find Wikidata information for this location."
end
redirect_to @garden
end
private
def garden_params
params.require(:garden).permit(
:name, :slug, :description, :active,
:location, :latitude, :longitude, :area, :area_unit, :garden_type_id
:location, :latitude, :longitude, :area, :area_unit, :garden_type_id,
:location_wikidata_id, :lowest_temp_c, :highest_temp_c
)
end
end
+32 -17
View File
@@ -4,27 +4,26 @@ class HarvestsController < DataController
after_action :update_crop_medians, only: %i(create update destroy)
def index
where = {}
if params[:member_slug]
@owner = Member.find_by(slug: params[:member_slug])
where['owner_id'] = @owner.id
@harvests = Harvest.all
if params[:member_slug].present?
@owner = Member.find_by!(slug: params[:member_slug])
@harvests = @harvests.where(owner_id: @owner.id)
end
if params[:crop_slug]
@crop = Crop.find_by(slug: params[:crop_slug])
where['crop_id'] = @crop.id
@harvests = @harvests.where(crop_id: @crop.id) if @crop
end
if params[:planting_slug]
@planting = Planting.find_by(slug: params[:planting_slug])
where['planting_id'] = @planting.id
@harvests = @harvests.where(planting_id: @planting.id) if @planting
end
@harvests = Harvest.search('*', where:,
limit: 100,
page: params[:page],
load: false,
boost_by: [:created_at])
@harvests = @harvests.includes(:crop, :owner, :plant_part)
@harvests = @harvests.recent.paginate(page: params[:page], per_page: 100)
@filename = csv_filename
@@ -38,9 +37,9 @@ class HarvestsController < DataController
end
def new
@harvest = Harvest.new(harvested_at: Time.zone.today)
@planting = Planting.find_by(slug: params[:planting_slug]) if params[:planting_slug]
@crop = Crop.find_by(id: params[:crop_id])
@harvest = Harvest.new(new_harvest_params.merge(harvested_at: Time.zone.today))
@planting = @harvest.planting
@crop = @harvest.crop
respond_with(@harvest)
end
@@ -52,7 +51,7 @@ class HarvestsController < DataController
def create
@harvest.crop_id = @harvest.planting.crop_id if @harvest.planting_id
@harvest.harvested_at = Time.zone.now if @harvest.harvested_at.blank?
@harvest.save
update_planting_rating if @harvest.save
if params[:return] == 'planting'
respond_with(@harvest, location: @harvest.planting)
else
@@ -61,7 +60,7 @@ class HarvestsController < DataController
end
def update
@harvest.update(harvest_params)
update_planting_rating if @harvest.update(harvest_params)
respond_with(@harvest)
end
@@ -76,7 +75,17 @@ class HarvestsController < DataController
params.require(:harvest)
.permit(:planting_id, :crop_id, :harvested_at, :description,
:quantity, :unit, :weight_quantity, :weight_unit,
:plant_part_id, :slug, :si_weight)
:plant_part_id, :slug, :si_weight, :overall_rating)
.merge(owner_id: current_member.id)
end
def new_harvest_params
return {} unless params[:harvest]
params.require(:harvest)
.permit(:planting_id, :crop_id, :harvested_at, :description,
:quantity, :unit, :weight_quantity, :weight_unit,
:plant_part_id, :slug, :si_weight, :overall_rating)
.merge(owner_id: current_member.id)
end
@@ -103,4 +112,10 @@ class HarvestsController < DataController
@harvest.planting.update_harvest_days!
@harvest.crop.update_harvest_medians
end
def update_planting_rating
return if @harvest.planting.nil? || params[:harvest][:overall_rating].blank?
@harvest.planting.update(overall_rating: params[:harvest][:overall_rating])
end
end
+4 -4
View File
@@ -11,10 +11,10 @@ class LikesController < ApplicationController
likeable_id: params[:id]
)
if @like.likeable && @like.save
@like.likeable.reindex(refresh: true)
@like.likeable.reindex(refresh: true) if @like.likeable.respond_to?(:reindex)
success(@like, liked_by_member: true, status_code: :created)
else
failed(@like, message: 'Unable to like')
failed(@like, message: t('messages.unable_to_like'))
end
end
@@ -26,10 +26,10 @@ class LikesController < ApplicationController
)
if @like&.destroy
@like.likeable.reindex(refresh: true)
@like.likeable.reindex(refresh: true) if @like.likeable.respond_to?(:reindex)
success(@like, liked_by_member: false, status_code: :ok)
else
failed(@like, message: 'Unable to unlike')
failed(@like, message: t('messages.unable_to_unlike'))
end
end
+6 -8
View File
@@ -40,12 +40,9 @@ class MembersController < ApplicationController
end
end
@harvests = Harvest.search(
where: { owner_id: @member.id },
boost_by: [:created_at],
limit: 16,
load: false
)
@harvests = Harvest.where(owner_id: @member.id)
.recent
.limit(16)
respond_to do |format|
format.html # show.html.haml
@@ -90,11 +87,12 @@ class MembersController < ApplicationController
EMAIL_TYPE_STRING = {
send_notification_email: "direct message notifications",
send_planting_reminder: "planting reminders"
send_planting_reminder: "planting reminders",
send_harvest_reminder: "harvest reminders"
}.freeze
def member_params
params.require(:member).permit(:login_name, :tos_agreement, :email, :newsletter)
params.require(:member).permit(:login_name, :tos_agreement, :email, :newsletter, :send_harvest_reminder)
end
def member_json_fields
+11
View File
@@ -27,10 +27,21 @@ class MessagesController < ApplicationController
def create
if params[:conversation_id].present?
@conversation = Mailboxer::Conversation.find(params[:conversation_id])
# Check if any of the recipients have blocked the sender
if @conversation.recipients.any? { |recipient| recipient.already_blocking?(current_member) }
flash[:error] = "You cannot reply to this conversation because one of the recipients has blocked you."
redirect_to conversation_path(@conversation)
return
end
current_member.reply_to_conversation(@conversation, params[:body])
redirect_to conversation_path(@conversation)
else
recipient = Member.find(params[:recipient_id])
if recipient.already_blocking?(current_member)
flash[:error] = "You cannot send a message to a member who has blocked you."
redirect_back_or_to(root_path)
return
end
body = params[:body]
subject = params[:subject]
@conversation = current_member.send_message(recipient, body, subject)
@@ -10,7 +10,7 @@ require './lib/actions/oauth_signup_action'
#
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def failure
flash[:alert] = "Authentication failed."
flash[:alert] = t('messages.auth_failed')
redirect_to request.env['omniauth.origin'] || "/"
end
+14 -18
View File
@@ -9,13 +9,17 @@ class PhotosController < ApplicationController
responders :flash
def index
@photos = Photo.search(
load: false,
boost_by: [:created_at],
where: index_where_clause,
page: params[:page],
limit: Photo.per_page
)
@photos = if @crop
@crop.photos
elsif @planting
@planting.photos
else
Photo.all
end
@photos = @photos.includes(:owner)
.order(created_at: :desc)
.paginate(page: params[:page], per_page: Photo.per_page)
respond_with(@photos)
end
@@ -102,29 +106,21 @@ class PhotosController < ApplicationController
end
@current_set = params[:set]
@current_tag = params[:tag]
page = params[:page] || 1
@sets = current_member.flickr_sets
photos, total = current_member.flickr_photos(page, @current_set)
photos, total = current_member.flickr_photos(page, @current_set, @current_tag)
@photos = WillPaginate::Collection.create(page, 30, total) do |pager|
pager.replace photos
end
end
def index_where_clause
if params[:crop_slug]
{ crops: @crop.id }
elsif params[:planting_id]
{ planting_id: @planting.id }
else
{}
end
end
def set_crop_and_planting
@crop = Crop.find params[:crop_slug] if params[:crop_slug]
@planting = Planting.find params[:planting_id] if params[:planting_id]
@planting ||= Planting.find params[:planting_slug] if params[:planting_slug]
end
end
+1 -1
View File
@@ -33,7 +33,7 @@ class PlacesController < ApplicationController
def search
if params[:new_place].empty?
redirect_to places_path, alert: 'Please enter a valid location'
redirect_to places_path, alert: t('messages.invalid_location')
else
redirect_to place_path(params[:new_place])
end
+7 -23
View File
@@ -8,26 +8,10 @@ class PlantingsController < DataController
def index
@show_all = params[:all] == '1'
where = {}
where['active'] = true unless @show_all
@owner = Member.find_by!(slug: params[:member_slug]) if params[:member_slug].present?
@crop = Crop.find_by(slug: params[:crop_slug]) if params[:crop_slug]
if params[:member_slug]
@owner = Member.find_by(slug: params[:member_slug])
where['owner_id'] = @owner.id unless @owner.nil?
end
if params[:crop_slug]
@crop = Crop.find_by(slug: params[:crop_slug])
where['crop_id'] = @crop.id unless @crop.nil?
end
@plantings = Planting.search(
where:,
page: params[:page],
limit: 30,
boost_by: [:created_at],
load: false
)
@plantings = plantings
@filename = "Growstuff-#{specifics}Plantings-#{Time.zone.now.to_fs(:number)}.csv"
respond_with(@plantings)
@@ -35,7 +19,7 @@ class PlantingsController < DataController
def show
@photos = @planting.photos.includes(:owner).order(date_taken: :desc)
@harvests = Harvest.search(where: { planting_id: @planting.id })
@harvests = Harvest.where(planting_id: @planting.id).recent
@current_activities = @planting.activities.current.includes(:owner).order(created_at: :desc)
@finished_activities = @planting.activities.finished.includes(:owner).order(created_at: :desc)
@matching_seeds = matching_seeds
@@ -116,11 +100,11 @@ class PlantingsController < DataController
new_planting.finished_at = nil
if new_planting.save
redirect_to edit_planting_path(new_planting), notice: 'Planting was successfully transplanted.'
redirect_to edit_planting_path(new_planting), notice: t('messages.transplant_success')
else
# if the save fails, we should probably roll back the finishing of the original planting
@planting.update(finished: false, finished_at: nil)
redirect_to @planting, alert: "There was an error transplanting the planting: #{new_planting.errors.full_messages.to_sentence}"
redirect_to @planting, alert: t('messages.transplant_error', errors: new_planting.errors.full_messages.to_sentence)
end
end
@@ -160,7 +144,7 @@ class PlantingsController < DataController
end
def matching_seeds
Seed.where(crop: @planting.crop, owner: @planting.owner)
@matching_seeds ||= Seed.where(crop: @planting.crop, owner: @planting.owner)
.where('(finished_at IS NULL OR finished_at >= ?)', @planting.planted_at)
.where('(saved_at IS NULL OR saved_at <= ?)', @planting.planted_at)
end
+8 -4
View File
@@ -8,7 +8,7 @@ class PostsController < ApplicationController
respond_to :rss, only: %i(index show)
def index
@author = Member.find_by(slug: params[:member_slug])
@author = Member.find_by!(slug: params[:member_slug]) if params[:member_slug].present?
@posts = posts
respond_with(@posts)
end
@@ -21,6 +21,10 @@ class PostsController < ApplicationController
def new
@post = Post.new
@forum = Forum.find_by(id: params[:forum_id])
if params[:crop_id]
@crop = Crop.friendly.find(params[:crop_id])
@post.body = "[#{@crop.name}](crop)"
end
respond_with(@post)
end
@@ -29,17 +33,17 @@ class PostsController < ApplicationController
def create
params[:post][:author_id] = current_member.id
@post = Post.new(post_params)
flash[:notice] = 'Post was successfully created.' if @post.save
flash[:notice] = t('posts.created') if @post.save
respond_with(@post)
end
def update
flash[:notice] = 'Post was successfully updated.' if @post.update(post_params)
flash[:notice] = t('posts.updated') if @post.update(post_params)
respond_with(@post)
end
def destroy
flash[:notice] = 'Post was deleted.' if @post.destroy
flash[:notice] = t('posts.deleted') if @post.destroy
respond_with(@post)
end
@@ -54,7 +54,7 @@ class ScientificNamesController < ApplicationController
def destroy
@crop = @scientific_name.crop
@scientific_name.destroy
flash[:notice] = 'Scientific name was successfully deleted.'
flash[:notice] = t('scientific_names.deleted')
respond_with(@crop)
end
+12 -16
View File
@@ -2,36 +2,32 @@
class SeedsController < DataController
def index
where = {}
@seeds = Seed.all
if params[:member_slug].present?
@owner = Member.find_by(slug: params[:member_slug])
where['owner_id'] = @owner.id
@owner = Member.find_by!(slug: params[:member_slug])
@seeds = @seeds.where(owner_id: @owner.id)
end
if params[:crop_slug].present?
@crop = Crop.find_by(slug: params[:crop_slug])
where['crop_id'] = @crop.id
@seeds = @seeds.where(crop_id: @crop.id) if @crop
end
if params[:planting_id].present?
@planting = Planting.find_by(slug: params[:planting_id])
where['parent_planting'] = @planting.id
@seeds = @seeds.where(parent_planting_id: @planting.id) if @planting
end
where['tradeable_to'] = params[:tradeable_to] if params[:tradeable_to].present?
@seeds = @seeds.where(tradable_to: params[:tradeable_to]) if params[:tradeable_to].present?
@show_all = (params[:all] == '1')
where['finished'] = false unless @show_all
@seeds = @seeds.current unless @show_all
@filename = csv_filename
@seeds = Seed.search(
where:,
page: params[:page],
limit: 30,
boost_by: [:created_at],
load: false
)
@seeds = @seeds.includes(:crop, :owner)
.order(created_at: :desc)
.paginate(page: params[:page], per_page: 30)
respond_with(@seeds)
end
@@ -61,7 +57,7 @@ class SeedsController < DataController
@seed.finished ||= false
@seed.owner = current_member
@seed.crop = @seed.parent_planting.crop if @seed.parent_planting
flash[:notice] = "Successfully added #{@seed.crop} seed to your stash." if @seed.save
flash[:notice] = t('seeds.added_to_stash', crop: @seed.crop) if @seed.save
if params[:return] == 'planting'
respond_with(@seed, location: @seed.parent_planting)
else
@@ -70,7 +66,7 @@ class SeedsController < DataController
end
def update
flash[:notice] = 'Seed was successfully updated.' if @seed.update(seed_params)
flash[:notice] = t('seeds.updated') if @seed.update(seed_params)
respond_with(@seed)
end
+1 -1
View File
@@ -5,7 +5,7 @@ class SessionsController < Devise::SessionsController
def create
super do |_resource|
flash[:alert] = "There are crops waiting to be wrangled." if Crop.pending_approval.present? && current_member.role?(:crop_wrangler)
flash[:alert] = t('messages.crops_waiting') if Crop.pending_approval.present? && current_member.role?(:crop_wrangler)
end
end
end
+2 -2
View File
@@ -130,9 +130,9 @@ module ApplicationHelper
doc = Nokogiri::XML(response.body)
doc.xpath('//xmlns:entry').first(2).map do |entry|
{
title: entry.xpath('xmlns:title').text,
title: entry.xpath('xmlns:title').text,
content: entry.xpath('xmlns:content').text,
link: entry.xpath('xmlns:link/@href').text,
link: entry.xpath('xmlns:link/@href').text,
updated: entry.xpath('xmlns:updated').text
}
end
+81 -58
View File
@@ -2,28 +2,47 @@
module CropsHelper
def crop_or_parent(crop, attribute)
default = crop.send(attribute)
return default if default.present?
@crop_or_parent_cache ||= {}
cache_key = [crop.persisted? ? crop.id : crop.object_id, attribute]
return @crop_or_parent_cache[cache_key] if @crop_or_parent_cache.key?(cache_key)
parent = crop
while parent = parent.parent
return parent.send(attribute) if parent&.send(attribute).present?
@crop_or_parent_cache[cache_key] = begin
value = crop.send(attribute)
if value.blank?
parent = crop
while (parent = parent.parent)
parent_value = parent.send(attribute)
if parent_value.present?
value = parent_value
break
end
end
end
value
end
# For scopes, arrays, etc return the empty value
default
end
def display_seed_availability(member, crop)
seeds = member.seeds.where(crop:)
total_quantity = seeds.where.not(quantity: nil).sum(:quantity)
@seed_availability_cache ||= {}
cache_key = [
member.persisted? ? member.id : member.object_id,
crop.persisted? ? crop.id : crop.object_id
]
return @seed_availability_cache[cache_key] if @seed_availability_cache.key?(cache_key)
return "You don't have any seeds of this crop." if seeds.none?
@seed_availability_cache[cache_key] = begin
seeds = member.seeds.where(crop:)
if total_quantity == 0
"You have an unknown quantity of seeds of this crop."
else
"You have #{total_quantity} #{Seed.model_name.human(count: total_quantity)} of this crop."
if seeds.none?
"You don't have any seeds of this crop."
else
total_quantity = seeds.where.not(quantity: nil).sum(:quantity)
if total_quantity == 0
"You have an unknown quantity of seeds of this crop."
else
"You have #{total_quantity} #{Seed.model_name.human(count: total_quantity)} of this crop."
end
end
end
end
@@ -40,53 +59,57 @@ module CropsHelper
end
def crop_jsonld_data(crop, full_attributes: true)
same_as_urls = [crop.en_wikipedia_url]
crop.scientific_names.each do |scientific_name|
same_as_urls << "https://www.wikidata.org/wiki/#{scientific_name.wikidata_id}" if scientific_name.wikidata_id.present?
end
subject_of_entities = []
if full_attributes
if crop.en_youtube_url.present?
subject_of_entities << {
'@type': "VideoObject",
url: crop.en_youtube_url
}
end
crop.posts.each do |post|
subject_of_entities << {
'@type': "SocialMediaPosting",
url: post_url(post),
author: {
'@type': 'Person',
name: post.author.login_name
},
'datePublished': post.created_at
}
Rails.cache.fetch([crop.cache_key_with_version, "jsonld", full_attributes]) do
same_as_urls = [crop.en_wikipedia_url]
crop.scientific_names.each do |scientific_name|
if scientific_name.wikidata_id.present?
same_as_urls << "https://www.wikidata.org/wiki/#{scientific_name.wikidata_id}"
end
end
subject_of_entities = []
images = []
crop.photos.each do |photo|
images << photo.fullsize_url
if full_attributes
if crop.en_youtube_url.present?
subject_of_entities << {
'@type': "VideoObject",
url: crop.en_youtube_url
}
end
crop.posts.each do |post|
subject_of_entities << {
'@type': "SocialMediaPosting",
url: post_url(post),
author: {
'@type': 'Person',
name: post.author.login_name
},
datePublished: post.created_at
}
end
crop.photos.each do |photo|
images << photo.fullsize_url
end
end
# TODO: Review plantings, seeds, harvests as a subtype of social media post or event that ended? Or creative work?
# has_many :plantings, dependent: :destroy
# has_many :seeds, dependent: :destroy
# has_many :harvests, dependent: :destroy
{
'@context': "https://schema.org",
'@type': "BioChemEntity",
name: crop.name,
taxonomicRange: crop.scientific_names.map(&:name),
description: crop.description,
sameAs: same_as_urls,
alternateName: crop.alternate_names.map(&:name),
subjectOf: subject_of_entities,
image: images
}.compact
end
# TODO: Review plantings, seeds, harvests as a subtype of social media post or event that ended? Or creative work?
# has_many :plantings, dependent: :destroy
# has_many :seeds, dependent: :destroy
# has_many :harvests, dependent: :destroy
{
'@context': "https://schema.org",
'@type': "BioChemEntity",
name: crop.name,
taxonomicRange: crop.scientific_names.map(&:name),
description: crop.description,
sameAs: same_as_urls,
alternateName: crop.alternate_names.map(&:name),
subjectOf: subject_of_entities,
image: images
}.compact
end
end
+6 -2
View File
@@ -46,9 +46,13 @@ module PlantingsHelper
# Returns a list of gardens the planting can be transplanted to
# based on the planting's owner.
def transplantable_gardens_by_owner(planting)
garden_ids = planting.owner.gardens.select(:id).to_a + GardenCollaborator.where(member_id: planting.owner.id).select(:garden_id).to_a
@transplantable_gardens ||= {}
cache_key = planting.id || planting.object_id
@transplantable_gardens[cache_key] ||= begin
garden_ids = planting.owner.gardens.select(:id).to_a + GardenCollaborator.where(member_id: planting.owner.id).select(:garden_id).to_a
Garden.active.where.not(id: planting.garden_id).where(id: garden_ids)
Garden.active.where.not(id: planting.garden_id).where(id: garden_ids)
end
end
def days_from_now_to_last_harvest(planting)
+13
View File
@@ -57,6 +57,19 @@ class NotifierMailer < ApplicationMailer
mail(to: @member.email, subject: @subject) if @member.send_planting_reminder
end
def harvest_reminder(member)
@member = member
@plantings = @member.plantings.active.select(&:harvest_in_next_week?)
@sitename = ENV.fetch('GROWSTUFF_SITE_NAME', nil)
@subject = I18n.t('notifier_mailer.harvest_reminder.subject', sitename: @sitename)
# Encrypting
message = { member_id: @member.id, type: :send_harvest_reminder }
@signed_message = verifier.generate(message)
mail(to: @member.email, subject: @subject) if @member.send_harvest_reminder
end
def new_crop_request(member, request)
@member = member
@request = request
+7
View File
@@ -123,6 +123,7 @@ class Ability
can :create, GardenCollaborator, garden: { owner_id: member.id }
can :update, GardenCollaborator, garden: { owner_id: member.id }
can :destroy, GardenCollaborator, garden: { owner_id: member.id }
can :destroy, GardenCollaborator, member_id: member.id
can :create, Activity
can :update, Activity, owner_id: member.id
@@ -164,6 +165,12 @@ class Ability
can :destroy, Follow
cannot :destroy, Follow, followed_id: member.id # can't unfollow yourself
# blocking/unblocking permissions
can :create, Block
cannot :create, Block, blocked_id: member.id # can't block yourself
can :destroy, Block, blocker_id: member.id # can only unblock your own blocks
cannot :create, GardenType
cannot :update, GardenType
cannot :destroy, GardenType
+13 -1
View File
@@ -4,7 +4,6 @@ class Activity < ApplicationRecord
extend FriendlyId
include Ownable
include Finishable
include SearchActivities
include Likeable
belongs_to :garden, optional: true
@@ -46,4 +45,17 @@ class Activity < ApplicationRecord
def planting_slug
planting&.crop&.slug
end
scope :active, -> { where(finished: [false, nil]) }
def self.homepage_records(limit)
# Get the latest activity for each owner, then return the latest 'limit' of those
Activity.where(id: Activity.unscoped.select("DISTINCT ON (owner_id) id").order("owner_id, created_at DESC"))
.order(created_at: :desc)
.limit(limit)
end
def self.reindex(refresh: false); end
def reindex(refresh: false); end
end
+18
View File
@@ -0,0 +1,18 @@
# frozen_string_literal: true
class Block < ApplicationRecord
belongs_to :blocker, class_name: "Member"
belongs_to :blocked, class_name: "Member"
validates :blocker_id, uniqueness: { scope: :blocked_id }
after_create :destroy_follow_relationship
private
def destroy_follow_relationship
# Destroy the follow relationship in both directions
Follow.where(follower: blocker, followed: blocked).destroy_all
Follow.where(follower: blocked, followed: blocker).destroy_all
end
end
+11
View File
@@ -4,6 +4,7 @@ class Comment < ApplicationRecord
belongs_to :author, class_name: 'Member', inverse_of: :comments
belongs_to :commentable, polymorphic: true, counter_cache: true
# validates :body, presence: true
validate :author_is_not_blocked
scope :post_order, -> { order(created_at: :asc) } # for display on post page
@@ -25,4 +26,14 @@ class Comment < ApplicationRecord
def to_s
"#{author.login_name} commented on #{commentable.subject}"
end
private
def author_is_not_blocked
return unless author
return unless commentable.author.already_blocking?(author)
errors.add(:base, "You cannot comment on a post of a member who has blocked you.")
end
end
+9 -2
View File
@@ -40,8 +40,15 @@ module MemberFlickr
# Fetches a collection of photos from Flickr
# Returns a [[page of photos], total] pair.
# Total is needed for pagination.
def flickr_photos(page_num = 1, set = nil)
result = if set
def flickr_photos(page_num = 1, set = nil, tags = nil)
result = if tags.present?
flickr.photos.search(
user_id: 'me',
tags: tags,
page: page_num,
per_page: 30
)
elsif set.present?
flickr.photosets.getPhotos(
photoset_id: set,
page: page_num,
+32 -16
View File
@@ -6,23 +6,31 @@ module PredictHarvest
included do
# dates
def first_harvest_date
harvests_with_dates.minimum(:harvested_at)
return @first_harvest_date if defined?(@first_harvest_date)
@first_harvest_date = harvests_with_dates.minimum(:harvested_at)
end
def last_harvest_date
harvests_with_dates.maximum(:harvested_at)
return @last_harvest_date if defined?(@last_harvest_date)
@last_harvest_date = harvests_with_dates.maximum(:harvested_at)
end
def first_harvest_predicted_at
return unless crop.median_days_to_first_harvest.present? && planted_at.present?
return @first_harvest_predicted_at if defined?(@first_harvest_predicted_at)
planted_at + crop.median_days_to_first_harvest.days
@first_harvest_predicted_at = if crop.median_days_to_first_harvest.present? && planted_at.present?
planted_at + crop.median_days_to_first_harvest.days
end
end
def last_harvest_predicted_at
return unless crop.median_days_to_last_harvest.present? && planted_at.present?
return @last_harvest_predicted_at if defined?(@last_harvest_predicted_at)
planted_at + crop.median_days_to_last_harvest.days
@last_harvest_predicted_at = if crop.median_days_to_last_harvest.present? && planted_at.present?
planted_at + crop.median_days_to_last_harvest.days
end
end
# actions
@@ -52,10 +60,16 @@ module PredictHarvest
def before_harvest_time?
first_harvest_predicted_at.present? &&
harvests.empty? &&
first_harvest_predicted_at.present? &&
first_harvest_predicted_at > Time.zone.today
end
def harvest_in_next_week?
first_harvest_predicted_at.present? &&
harvests.empty? &&
first_harvest_predicted_at >= Time.zone.today &&
first_harvest_predicted_at <= Time.zone.today + 7.days
end
def harvest_months
Rails.cache.fetch("#{cache_key_with_version}/harvest_months", expires_in: 5.minutes) do
neighbours_for_harvest_predictions.where.not(harvested_at: nil)
@@ -65,16 +79,18 @@ module PredictHarvest
end
def neighbours_for_harvest_predictions
# use this planting's harvest if any
return harvests if harvests.size.positive?
# otherwise use nearby plantings
if location
return Harvest.where(planting: nearby_same_crop.has_harvests)
.where.not(planting_id: nil)
@neighbours_for_harvest_predictions ||= begin
# use this planting's harvest if any
if harvests.size.positive?
harvests
# otherwise use nearby plantings
elsif location
Harvest.where(planting: nearby_same_crop.has_harvests)
.where.not(planting_id: nil)
else
Harvest.none
end
end
Harvest.none
end
private
+30 -21
View File
@@ -13,40 +13,49 @@ module PredictPlanting
# dates
def finish_predicted_at
if planted_at.blank? || failed?
nil
elsif crop.median_lifespan.present?
planted_at + crop.median_lifespan.days
elsif crop.parent.present? && crop.parent.median_lifespan.present?
planted_at + crop.parent.median_lifespan.days
end
return @finish_predicted_at if defined?(@finish_predicted_at)
@finish_predicted_at = if planted_at.blank? || failed?
nil
elsif crop.median_lifespan.present?
planted_at + crop.median_lifespan.days
elsif crop.parent.present? && crop.parent.median_lifespan.present?
planted_at + crop.parent.median_lifespan.days
end
end
# days
def expected_lifespan
if actual_lifespan.present?
actual_lifespan
elsif crop.median_lifespan.present?
crop.median_lifespan
elsif crop.parent.present? && crop.parent.median_lifespan.present?
crop.parent.median_lifespan
end
return @expected_lifespan if defined?(@expected_lifespan)
@expected_lifespan = if actual_lifespan.present?
actual_lifespan
elsif crop.median_lifespan.present?
crop.median_lifespan
elsif crop.parent.present? && crop.parent.median_lifespan.present?
crop.parent.median_lifespan
end
end
def actual_lifespan
return unless planted_at.present? && finished_at.present? && !failed?
return @actual_lifespan if defined?(@actual_lifespan)
(finished_at - planted_at).to_i
@actual_lifespan = if planted_at.present? && finished_at.present? && !failed?
(finished_at - planted_at).to_i
end
end
def age_in_days
return if planted_at.blank?
return if failed?
return @age_in_days if defined?(@age_in_days)
known_last_day ||= finished_at || Time.zone.today
known_last_day = Time.zone.today if known_last_day > Time.zone.today
@age_in_days = if planted_at.blank? || failed?
nil
else
known_last_day = finished_at || Time.zone.today
known_last_day = Time.zone.today if known_last_day > Time.zone.today
(known_last_day - planted_at).to_i
(known_last_day - planted_at).to_i
end
end
def percentage_grown
-66
View File
@@ -1,66 +0,0 @@
# frozen_string_literal: true
module SearchActivities
extend ActiveSupport::Concern
included do
searchkick merge_mappings: true,
settings: { number_of_shards: 1, number_of_replicas: 0 },
mappings: {
properties: {
active: { type: :boolean },
created_at: { type: :integer },
updated_at: { type: :integer },
due_date: { type: :date }
}
}
def search_data
{
slug:,
active:,
finished: finished?,
name:,
due_date:,
category:,
garden_id:,
garden_name: garden&.name,
garden_slug: garden&.garden_slug,
planting_id:,
planting_name: planting&.crop&.name,
planting_slug: planting&.slug,
description:,
# owner
owner_id:,
owner_login_name:,
owner_slug:,
# timestamps
created_at: created_at.to_i,
updated_at: updated_at.to_i
}
end
def self.homepage_records(limit)
records = []
owners = []
1..limit.times do
where = {
# photos_count: { gt: 0 },
owner_id: { not: owners }
}
one_record = search('*',
limit: 1,
where:,
boost_by: [:created_at],
load: false).first
return records if one_record.nil?
owners << one_record.owner_id
records << one_record
end
records
end
end
end
-74
View File
@@ -1,74 +0,0 @@
# frozen_string_literal: true
module SearchHarvests
extend ActiveSupport::Concern
included do
searchkick merge_mappings: true,
settings: { number_of_shards: 1, number_of_replicas: 0 },
mappings: {
properties: {
harvests_count: { type: :integer },
photos_count: { type: :integer },
created_at: { type: :integer },
harvested_at: { type: :date }
}
}
def search_data
{
slug:,
quantity:,
# crop
crop_id:,
crop_name:,
crop_slug: crop.slug,
# owner
owner_id:,
owner_login_name:,
owner_slug:,
plant_part_name: plant_part&.name,
# planting
planting_id:,
planting_slug: planting&.slug,
# photo
has_photos: photos.size.positive?,
thumbnail_url: default_photo&.thumbnail_url || crop.default_photo&.thumbnail_url,
# counts
photos_count: photos.count,
# timestamps
harvested_at:,
created_at: created_at.to_i
}
end
def self.homepage_records(limit)
records = []
owners = []
1..limit.times do
where = {
# Disabled for now so that more relevant harvests are
# surfaced; even if we're falling back to crop photos.
# photos_count: { gt: 0 },
owner_id: { not: owners }
}
one_record = search('*',
limit: 1,
where:,
boost_by: [:created_at],
load: false).first
return records if one_record.nil?
owners << one_record.owner_id
records << one_record
end
records
end
end
end
-37
View File
@@ -1,37 +0,0 @@
# frozen_string_literal: true
module SearchPhotos
extend ActiveSupport::Concern
included do
searchkick merge_mappings: true,
settings: { number_of_shards: 1, number_of_replicas: 0 },
mappings: {
properties: {
title: { type: :text },
created_at: { type: :integer }
}
}
def search_data
{
id:,
title:,
thumbnail_url:,
fullsize_url:,
# crops
crops: crops.pluck(:id),
# likes
liked_by_members_names:,
# owner
owner_id:,
owner_login_name:,
owner_slug:,
# counts
likes_count:,
created_at: created_at.to_i
}
end
end
end
-87
View File
@@ -1,87 +0,0 @@
# frozen_string_literal: true
module SearchPlantings
extend ActiveSupport::Concern
included do
searchkick merge_mappings: true,
settings: { number_of_shards: 1, number_of_replicas: 0 },
mappings: {
properties: {
active: { type: :boolean },
created_at: { type: :integer },
harvests_count: { type: :integer },
photos_count: { type: :integer },
owner_location: { type: :text }
}
}
def search_data
{
slug:,
active:,
finished: finished?,
has_photos: photos.size.positive?,
location:,
percentage_grown: percentage_grown.to_i,
planted_at:,
planted_from:,
planted_year: planted_at&.year,
quantity:,
sunniness:,
garden_id:,
garden_slug: garden&.garden_slug,
garden_name: garden&.name,
description:,
first_harvest_predicted_at:,
finish_predicted_at:,
# crops
crop_id:,
crop_name:,
crop_slug:,
crop_perennial:,
# owner
owner_id:,
owner_location:,
owner_login_name:,
owner_slug:,
# photos
thumbnail_url: default_photo&.thumbnail_url || crop.default_photo&.thumbnail_url,
# counts
photos_count: photos.size,
harvests_count:,
# timestamps
created_at: created_at.to_i,
updated_at: updated_at.to_i
}
end
def self.homepage_records(limit)
records = []
owners = []
1..limit.times do
where = {
# Disabled for now so that more relevant plantings are
# surfaced; even if we're falling back to crop photos.
# photos_count: { gt: 0 },
owner_id: { not: owners }
}
one_record = search('*',
limit: 1,
where:,
boost_by: [:created_at],
load: false).first
return records if one_record.nil?
owners << one_record.owner_id
records << one_record
end
records
end
end
end
-69
View File
@@ -1,69 +0,0 @@
# frozen_string_literal: true
module SearchSeeds
extend ActiveSupport::Concern
included do
searchkick merge_mappings: true,
settings: { number_of_shards: 1, number_of_replicas: 0 },
mappings: {
properties: {
id: { type: :integer },
created_at: { type: :integer },
plant_before: { type: :text },
photos_count: { type: :integer },
tradable_to: { type: :text }
}
}
def search_data
{
slug:,
finished: finished?,
gmo:,
active:,
heirloom:,
location: owner.location,
organic:,
quantity:,
plant_before: plant_before&.to_fs(:ymd),
tradable_to:,
tradable:,
# crop
crop_id:,
crop_name: crop.name,
crop_slug: crop.slug,
# owner
owner_id:,
owner_location:,
owner_login_name:,
owner_slug:,
# planting
parent_planting:,
# counts
photos_count: photos.size,
# photo
has_photos: photos.size.positive?,
thumbnail_url: default_photo&.thumbnail_url || crop.default_photo&.thumbnail_url,
created_at: created_at.to_i
}
end
def self.homepage_records(limit)
search('*', limit:,
where: {
finished: false,
tradable: true,
_or: [{ plant_before: nil }, { plant_before: { lt: Date.today } }]
},
boost_by: [:created_at],
load: false)
end
end
end
+10 -8
View File
@@ -57,13 +57,13 @@ class Crop < ApplicationRecord
validates :en_wikipedia_url,
format: {
with: %r{\Ahttps?://en\.wikipedia\.org/wiki/[[:alnum:]%_.()-]+\z},
message: 'is not a valid English Wikipedia URL'
message: :not_a_valid_wikipedia_url
},
if: :approved?
validates :en_youtube_url,
format: {
format: {
with: %r{\A(?:https?://)?(?:www\.)?(?:youtube(?:-nocookie)?\.com/(?:(?:v|e(?:mbed)?)/|\S*?[?&]v=)|youtu\.be/)[a-zA-Z0-9_-]{11}(?:[?&]\S*)?\z},
message: 'is not a valid YouTube URL'
message: :not_a_valid_youtube_url
},
allow_blank: true
validates :name, uniqueness: { scope: :approval_status }, if: :pending?
@@ -165,9 +165,11 @@ class Crop < ApplicationRecord
end
def all_companions
return companions unless parent
(companions + parent.all_companions).uniq
@all_companions ||= if parent
(companions + parent.all_companions).uniq
else
companions
end
end
before_destroy :destroy_reverse_companionships
@@ -190,12 +192,12 @@ class Crop < ApplicationRecord
return if rejected?
return unless reason_for_rejection.present? || rejection_notes.present?
errors.add(:approval_status, "must be rejected if a reason for rejection is present")
errors.add(:approval_status, :rejection_reason_required)
end
def must_have_meaningful_reason_for_rejection
return unless reason_for_rejection == "other" && rejection_notes.blank?
errors.add(:rejection_notes, "must be added if the reason for rejection is \"other\"")
errors.add(:rejection_notes, :rejection_notes_required)
end
end
+11
View File
@@ -4,6 +4,7 @@ class Follow < ApplicationRecord
belongs_to :follower, class_name: "Member", inverse_of: :follows
belongs_to :followed, class_name: "Member", inverse_of: :inverse_follows
validates :follower_id, uniqueness: { scope: :followed_id }
validate :follower_is_not_blocked
after_create do
Notification.create(
@@ -14,4 +15,14 @@ class Follow < ApplicationRecord
notifiable: self
)
end
private
def follower_is_not_blocked
return unless follower
return unless followed.already_blocking?(follower)
errors.add(:base, "You cannot follow a member who has blocked you.")
end
end
+16 -2
View File
@@ -21,6 +21,7 @@ class Garden < ApplicationRecord
after_validation :cleanup_area
after_validation :geocode
after_validation :empty_unwanted_geocodes
after_validation :populate_wikidata_info, if: :will_save_change_to_location?
after_save :mark_inactive_garden_plantings_as_finished
scope :active, -> { where(active: true) }
@@ -32,7 +33,7 @@ class Garden < ApplicationRecord
validates :name, uniqueness: { scope: :owner_id }
validates :name,
format: { without: /\n/, message: "must contain no newlines" },
format: { without: /\n/, message: :no_newlines },
allow_blank: false, presence: true,
length: { maximum: 255 }
@@ -53,7 +54,7 @@ class Garden < ApplicationRecord
"acres" => "acre"
}.freeze
validates :area_unit, inclusion: { in: AREA_UNITS_VALUES.values,
message: "%<value>s is not a valid area unit" },
message: :not_a_valid_area_unit },
allow_blank: true
def cleanup_area
@@ -92,6 +93,19 @@ class Garden < ApplicationRecord
end
end
def populate_wikidata_info
return false if location.blank?
wd_id = WikidataService.find_wikidata_id(location)
return false if wd_id.blank?
self.location_wikidata_id = wd_id
temps = WikidataService.fetch_temps(wd_id)
self.highest_temp_c = temps[:highest_temp_c]
self.lowest_temp_c = temps[:lowest_temp_c]
true
end
protected
def strip_blanks
+1 -1
View File
@@ -11,7 +11,7 @@ class GardenCollaborator < ApplicationRecord
return unless member
return unless garden
errors.add(:member_id, "cannot be the garden owner") if garden.owner == member
errors.add(:member_id, :cannot_be_garden_owner) if garden.owner == member
end
def member_slug
+44 -28
View File
@@ -5,9 +5,10 @@ class Harvest < ApplicationRecord
extend FriendlyId
include PhotoCapable
include Ownable
include SearchHarvests
include Likeable
attr_accessor :overall_rating
friendly_id :harvest_slug, use: %i(slugged finders)
# Constants
@@ -58,18 +59,18 @@ class Harvest < ApplicationRecord
##
## Validations
validates :crop, approved: true
validates :crop, presence: { message: "must be present and exist in our database" }
validates :plant_part, presence: { message: "must be present and exist in our database" }
validates :crop, presence: { message: :crop_not_found }
validates :plant_part, presence: { message: :crop_not_found }
validates :harvested_at, presence: true
validates :quantity, allow_nil: true, numericality: {
only_integer: false, greater_than_or_equal_to: 0
}
validates :unit, allow_blank: true, inclusion: {
in: UNITS_VALUES.values, message: "%<value>s is not a valid unit"
in: UNITS_VALUES.values, message: :not_a_valid_unit
}
validates :weight_quantity, allow_nil: true, numericality: { only_integer: false }
validates :weight_unit, allow_blank: true, inclusion: {
in: WEIGHT_UNITS_VALUES.values, message: "%<value>s is not a valid unit"
in: WEIGHT_UNITS_VALUES.values, message: :not_a_valid_unit
}
validate :crop_must_match_planting
validate :owner_must_match_planting
@@ -109,37 +110,53 @@ class Harvest < ApplicationRecord
def to_s
# 50 individual apples, weighing 3lb
# 2 buckets of apricots, weighing 10kg
"#{quantity_to_human} #{unit_to_human} #{crop_name_to_human} #{weight_to_human}".strip
@to_s ||= "#{quantity_to_human} #{unit_to_human} #{crop_name_to_human} #{weight_to_human}".strip
end
def quantity_to_human
return number_to_human(quantity.to_s, strip_insignificant_zeros: true) if quantity
""
@quantity_to_human ||= if quantity
number_to_human(quantity.to_s, strip_insignificant_zeros: true)
else
""
end
end
def unit_to_human
return "" unless quantity && unit
return 'individual' if unit == 'individual'
return "#{unit} of" if quantity == 1
"#{unit.pluralize} of"
@unit_to_human ||= begin
if !quantity || !unit
""
elsif unit == 'individual'
'individual'
elsif quantity == 1
"#{unit} of"
else
"#{unit.pluralize} of"
end
end
end
def weight_to_human
return "" unless weight_quantity
"weighing #{number_to_human(weight_quantity, strip_insignificant_zeros: true)} #{weight_unit}"
@weight_to_human ||= if weight_quantity
"weighing #{number_to_human(weight_quantity, strip_insignificant_zeros: true)} #{weight_unit}"
else
""
end
end
def crop_name_to_human
if unit != 'individual' # buckets of apricot*s*
crop.name.pluralize
elsif quantity == 1
crop.name
else
crop.name.pluralize
end.to_s
@crop_name_to_human ||= begin
if unit != 'individual' # buckets of apricot*s*
crop.name.pluralize
elsif quantity == 1
crop.name
else
crop.name.pluralize
end.to_s
end
end
def self.homepage_records(limit)
recent.one_per_owner.limit(limit)
end
private
@@ -147,7 +164,7 @@ class Harvest < ApplicationRecord
def crop_must_match_planting
return if planting.blank? # only check if we are linked to a planting
errors.add(:planting, "must be the same crop") unless crop == planting.crop
errors.add(:planting, :same_crop_required) unless crop == planting.crop
end
def owner_must_match_planting
@@ -155,14 +172,13 @@ class Harvest < ApplicationRecord
return if owner == planting.owner || planting.garden.garden_collaborators.where(member_id: owner).any?
errors.add(:owner,
"of harvest must be the same as planting, or a collaborator on that garden")
errors.add(:owner, :same_owner_required)
end
def harvest_must_be_after_planting
# only check if we are linked to a planting
return unless harvested_at.present? && planting.present? && planting.planted_at.present?
errors.add(:planting, "cannot be harvested before planting") unless harvested_at > planting.planted_at
errors.add(:planting, :harvest_after_planted) unless harvested_at > planting.planted_at
end
end
+20
View File
@@ -5,4 +5,24 @@ class Like < ApplicationRecord
belongs_to :likeable, polymorphic: true, counter_cache: true, touch: true
validates :member, :likeable, presence: true
validates :member, uniqueness: { scope: :likeable }
validate :member_is_not_blocked
def likeable_author
if likeable.respond_to?(:author)
likeable.author
elsif likeable.respond_to?(:owner)
likeable.owner
end
end
private
def member_is_not_blocked
return unless member
author = likeable_author
return unless author&.already_blocking?(member)
errors.add(:base, "You cannot like content of a member who has blocked you.")
end
end
+52 -13
View File
@@ -52,6 +52,15 @@ class Member < ApplicationRecord
has_many :followed, through: :follows
has_many :followers, through: :inverse_follows, source: :follower
#
# Blocking other members
has_many :blocks, class_name: "Block", foreign_key: "blocker_id", dependent: :destroy,
inverse_of: :blocker
has_many :inverse_blocks, class_name: "Block", foreign_key: "blocked_id",
dependent: :destroy, inverse_of: :blocked
has_many :blocked_members, through: :blocks, source: :blocked
has_many :blockers, through: :inverse_blocks, source: :blocker
#
# Global data records this member created
has_many :requested_crops, class_name: 'Crop', foreign_key: 'requester_id', dependent: :nullify,
@@ -70,6 +79,7 @@ class Member < ApplicationRecord
scope :interesting, -> { confirmed.located.recently_signed_in.has_plantings }
scope :has_plantings, -> { joins(:plantings).group("members.id") }
scope :wants_reminders, -> { where(send_planting_reminder: true) }
scope :wants_harvest_reminders, -> { where(send_harvest_reminder: true) }
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
@@ -96,21 +106,21 @@ class Member < ApplicationRecord
validates :tos_agreement, acceptance: { allow_nil: true, accept: true }
validates :login_name,
length: {
minimum: 2, maximum: 25, message: "should be between 2 and 25 characters long"
minimum: 2, maximum: 25, message: :login_name_length
},
exclusion: {
in: %w(growstuff admin moderator staff nearby), message: "name is reserved"
in: %w(growstuff admin moderator staff nearby), message: :login_name_reserved
},
format: {
with: /\A\w+\z/, message: "may only include letters, numbers, or underscores"
with: /\A\w+\z/, message: :login_name_format
},
uniqueness: {
case_sensitive: false
}
validates :website_url, format: { with: %r{\Ahttps?://}, message: "must start with http:// or https://" }, allow_blank: true
validates :other_url, format: { with: %r{\Ahttps?://}, message: "must start with http:// or https://" }, allow_blank: true
validates :website_url, format: { with: %r{\Ahttps?://}, message: :url_format }, allow_blank: true
validates :other_url, format: { with: %r{\Ahttps?://}, message: :url_format }, allow_blank: true
validates :instagram_handle, :facebook_handle, :bluesky_handle,
format: { without: %r{\Ahttps?://|/}, message: "should be a handle, not a URL" }, allow_blank: true
format: { without: %r{\Ahttps?://|/}, message: :handle_format }, allow_blank: true
#
# Triggers
@@ -152,7 +162,7 @@ class Member < ApplicationRecord
end
def unread_count
receipts.where(is_read: false).count
@unread_count ||= receipts.where(is_read: false).count
end
def self.login_name_or_email(login)
@@ -164,12 +174,12 @@ class Member < ApplicationRecord
end
def self.nearest_to(place)
nearby_members = []
if place
latitude, longitude = Geocoder.coordinates(place, params: { limit: 1 })
nearby_members = Member.located.sort_by { |x| x.distance_from([latitude, longitude]) } if latitude && longitude
end
nearby_members
return [] if place.blank?
latitude, longitude = Geocoder.coordinates(place, params: { limit: 1 })
return [] unless latitude && longitude
Member.located.near([latitude, longitude], 1000)
end
def already_following?(member)
@@ -179,4 +189,33 @@ class Member < ApplicationRecord
def get_follow(member)
follows.find_by(followed_id: member.id) if already_following?(member)
end
def already_blocking?(member)
blocks.exists?(blocked_id: member.id)
end
def get_block(member)
blocks.find_by(blocked_id: member.id) if already_blocking?(member)
end
def has_activity?
(gardens.exists? && gardens.count > 1) ||
plantings.exists? ||
harvests.exists? ||
seeds.exists? ||
photos.exists? ||
forums.exists? ||
activities.exists? ||
posts.exists? ||
comments.exists? ||
requested_crops.exists? ||
created_crops.exists? ||
likes.exists? ||
created_alternate_names.exists? ||
created_scientific_names.exists? ||
follows.exists? ||
inverse_follows.exists? ||
blocks.exists? ||
inverse_blocks.exists?
end
end
-1
View File
@@ -3,7 +3,6 @@
class Photo < ApplicationRecord
include Likeable
include Ownable
include SearchPhotos
PHOTO_CAPABLE = %w(Garden Planting Harvest Seed Post Crop).freeze
+2 -2
View File
@@ -29,12 +29,12 @@ class PhotoAssociation < ApplicationRecord
def photo_and_item_have_same_owner
return if photographable_type == 'Crop'
errors.add(:photo, "must have same owner as item it links to") unless photographable.owner_id == photo.owner_id
errors.add(:photo, :photo_owner_mismatch) unless photographable.owner_id == photo.owner_id
end
def crop_present
return unless %w(Planting Seed Harvest).include?(photographable_type)
errors.add(:crop_id, "failed to calculate crop") if crop_id.blank?
errors.add(:crop_id, :calculate_crop_failed) if crop_id.blank?
end
end
+21 -15
View File
@@ -7,7 +7,6 @@ class Planting < ApplicationRecord
include Ownable
include PredictPlanting
include PredictHarvest
include SearchPlantings
include Likeable
friendly_id :planting_slug, use: %i(slugged finders)
@@ -72,7 +71,7 @@ class Planting < ApplicationRecord
##
## Validations
validates :garden, presence: true
validates :crop, presence: true, approved: { message: "must be present and exist in our database" }
validates :crop, presence: true, approved: { message: :crop_must_be_approved }
validate :finished_must_be_after_planted
validate :owner_must_match_garden_owner
validate :cannot_be_finished_and_failed
@@ -80,10 +79,10 @@ class Planting < ApplicationRecord
only_integer: true, greater_than_or_equal_to: 0
}
validates :sunniness, allow_blank: true, inclusion: {
in: SUNNINESS_VALUES, message: "%<value>s is not a valid sunniness value"
in: SUNNINESS_VALUES, message: :not_a_valid_sunniness
}
validates :planted_from, allow_blank: true, inclusion: {
in: PLANTED_FROM_VALUES, message: "%<value>s is not a valid planting method"
in: PLANTED_FROM_VALUES, message: :not_a_valid_planting_method
}
validates :overall_rating, allow_blank: true, numericality: {
only_integer: true, greater_than_or_equal_to: 1, less_than_or_equal_to: 5
@@ -119,33 +118,40 @@ class Planting < ApplicationRecord
end
def nearby_same_crop
return Planting.none if location.blank? || latitude.blank? || longitude.blank?
return @nearby_same_crop if defined?(@nearby_same_crop)
# latitude, longitude = Geocoder.coordinates(location, params: { limit: 1 })
Planting.joins(:garden)
.where(crop:)
.located
.where('gardens.latitude < ? AND gardens.latitude > ?',
latitude + 10, latitude - 10)
@nearby_same_crop = if location.blank? || latitude.blank? || longitude.blank?
Planting.none
else
# latitude, longitude = Geocoder.coordinates(location, params: { limit: 1 })
Planting.joins(:garden)
.where(crop:)
.located
.where('gardens.latitude < ? AND gardens.latitude > ?',
latitude + 10, latitude - 10)
end
end
def self.homepage_records(limit)
recent.one_per_owner.limit(limit)
end
private
def cannot_be_finished_and_failed
errors.add(:failed, "can't be true if planting is also finished") if finished && failed
errors.add(:failed, :failed_and_finished) if finished && failed
end
# 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
errors.add(:finished_at, "must be after the planting date") unless planted_at < finished_at
errors.add(:finished_at, :finished_after_planted) unless planted_at < finished_at
end
def owner_must_match_garden_owner
return if owner == garden.owner || garden.garden_collaborators.where(member_id: owner).any?
errors.add(:owner,
"must be the same as garden, or a collaborator on that garden")
errors.add(:owner, :same_owner_required)
end
end
+4 -3
View File
@@ -49,9 +49,10 @@ class Post < ApplicationRecord
# return posts sorted by recent activity
def self.recently_active
Post.order(created_at: :desc).sort do |a, b|
b.recent_activity <=> a.recent_activity
end
left_joins(:comments)
.select('posts.*, COALESCE(MAX(comments.created_at), posts.created_at) AS last_activity_at')
.group('posts.id')
.order(Arel.sql('last_activity_at DESC'))
end
def owner_id
+13 -12
View File
@@ -5,7 +5,6 @@ class Seed < ApplicationRecord
include PhotoCapable
include Finishable
include Ownable
include SearchSeeds
friendly_id :seed_slug, use: %i(slugged finders)
@@ -28,7 +27,7 @@ class Seed < ApplicationRecord
#
# Validations
validates :crop, approved: true
validates :crop, presence: { message: "must be present and exist in our database" }
validates :crop, presence: { message: :crop_not_found }
validates :quantity, allow_nil: true,
numericality: { only_integer: true, greater_than_or_equal_to: 0 }
validates :days_until_maturity_min, allow_nil: true,
@@ -36,20 +35,15 @@ class Seed < ApplicationRecord
validates :days_until_maturity_max, allow_nil: true,
numericality: { only_integer: true, greater_than_or_equal_to: 0 }
validates :tradable_to, allow_blank: false,
inclusion: { in: TRADABLE_TO_VALUES, message: "You may only trade seed nowhere, " \
"locally, nationally, or internationally" }
inclusion: { in: TRADABLE_TO_VALUES, message: :tradable_to_inclusion }
validates :organic, allow_blank: false,
inclusion: { in: ORGANIC_VALUES, message: "You must say whether the seeds " \
"are organic or not, or that you don't know" }
inclusion: { in: ORGANIC_VALUES, message: :organic_inclusion }
validates :gmo, allow_blank: false,
inclusion: { in: GMO_VALUES, message: "You must say whether the seeds are " \
"genetically modified or not, or that you don't know" }
inclusion: { in: GMO_VALUES, message: :gmo_inclusion }
validates :heirloom, allow_blank: false,
inclusion: { in: HEIRLOOM_VALUES, message: "You must say whether the seeds" \
"are heirloom, hybrid, or unknown" }
inclusion: { in: HEIRLOOM_VALUES, message: :heirloom_inclusion }
validates :source, allow_blank: true,
inclusion: { in: SOURCE_VALUES, message: "You must say where the seeds are from," \
"or that you don't know" }
inclusion: { in: SOURCE_VALUES, message: :source_inclusion }
#
# Delegations
@@ -78,4 +72,11 @@ class Seed < ApplicationRecord
def to_s
I18n.t('seeds.string', crop: crop.name, owner:)
end
def self.homepage_records(limit)
current.tradable
.where("plant_before IS NULL OR plant_before < ?", Time.zone.today)
.order(created_at: :desc)
.limit(limit)
end
end
+2 -2
View File
@@ -2,7 +2,7 @@
class CropSearchService
# Crop.search(string)
def self.search(query, page: 1, per_page: 12, current_member: nil)
def self.search(query, page: 1, per_page: 12, current_member: nil, **options)
search_params = {
page:,
per_page:,
@@ -12,7 +12,7 @@ class CropSearchService
includes: %i(scientific_names alternate_names),
misspellings: { edit_distance: 2 },
load: false
}
}.merge(options)
# prioritise crops the member has planted
search_params[:boost_where] = { planters_ids: current_member.id } if current_member
+1 -1
View File
@@ -85,7 +85,7 @@ class GbifService
end
def import!
Crop.order(updated_at: :desc).each do |crop|
Crop.order(updated_at: :desc).find_each do |crop|
Rails.logger.debug { "#{crop.id}, #{crop.name}" }
update_crop(crop) if crop.valid?
rescue ActiveRecord::RecordInvalid
+74
View File
@@ -0,0 +1,74 @@
# frozen_string_literal: true
require 'net/http'
require 'json'
class WikidataService
CELSIUS_UNIT_ID = 'http://www.wikidata.org/entity/Q25267'
FAHRENHEIT_UNIT_ID = 'http://www.wikidata.org/entity/Q42289'
def self.find_wikidata_id(location_name)
return nil if location_name.blank?
uri = URI("https://www.wikidata.org/w/api.php?action=wbsearchentities&search=#{URI.encode_www_form_component(location_name)}&language=en&format=json")
req = Net::HTTP::Get.new(uri)
req['User-Agent'] = "Growstuff (https://www.growstuff.org; admin@growstuff.org)"
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(req)
end
data = JSON.parse(response.body)
data.dig('search', 0, 'id')
rescue StandardError => e
Rails.logger.error "WikidataService.find_wikidata_id error: #{e.message}"
nil
end
def self.fetch_temps(wikidata_id)
return {} if wikidata_id.blank?
uri = URI("https://www.wikidata.org/w/api.php?action=wbgetentities&ids=#{wikidata_id}&props=claims&format=json")
req = Net::HTTP::Get.new(uri)
req['User-Agent'] = "Growstuff (https://www.growstuff.org; admin@growstuff.org)"
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(req)
end
data = JSON.parse(response.body)
claims = data.dig('entities', wikidata_id, 'claims') || {}
highest_temp = extract_temp(claims['P6591'])
lowest_temp = extract_temp(claims['P7422'])
{
highest_temp_c: highest_temp,
lowest_temp_c: lowest_temp
}
rescue StandardError => e
Rails.logger.error "WikidataService.fetch_temps error: #{e.message}"
{}
end
def self.extract_temp(claim_data)
return nil if claim_data.blank?
# We take the first value
main_snak = claim_data.first&.dig('mainsnak')
return nil unless main_snak&.dig('datavalue', 'type') == 'quantity'
quantity_data = main_snak.dig('datavalue', 'value')
amount = quantity_data['amount'].to_f
unit = quantity_data['unit']
case unit
when CELSIUS_UNIT_ID
amount
when FAHRENHEIT_UNIT_ID
(amount - 32) * 5.0 / 9.0
else
nil
end
end
end
+1 -1
View File
@@ -3,7 +3,7 @@
- content_for :breadcrumbs do
- if @owner
%li.breadcrumb-item= link_to 'Activities', activities_path
%li.breadcrumb-item.active= link_to "#{@owner}'s activities", activities_path(owner: @owner)
%li.breadcrumb-item.active= link_to "#{@owner}'s activities", member_activities_path(@owner)
- else
%li.breadcrumb-item.active= link_to 'Activities', activities_path
+3 -3
View File
@@ -16,14 +16,14 @@
%p
%span.help-block
For detailed crop wrangling guidelines, please consult the
= link_to "crop wrangling guide", "http://wiki.growstuff.org/index.php/Crop_wrangling"
= link_to "crop wrangling guide", "https://github.com/Growstuff/growstuff/wiki/Crop-Wrangling"
on the Growstuff wiki.
.form-group
= f.label :crop_id, class: 'control-label col-md-2'
.col-md-8
= collection_select(:alternate_name, :crop_id,
Crop.all, :id, :name,
= select(:alternate_name, :crop_id,
Crop.order(:name).pluck(:name, :id),
{ selected: @alternate_name.crop_id || @crop.id },
class: 'form-control')
+6
View File
@@ -1,6 +1,12 @@
- if crop.approved? && signed_in?
- active_plantings = current_member.plantings.where(crop: crop).active
.btn-group.crop-actions{"aria-label" => "Crop Actions", role: "group"}
= render 'plantings/modal', planting: Planting.new(crop: crop, owner: current_member)
= render 'harvests/modal', harvest: Harvest.new(crop: @crop, owner: current_member)
= render 'seeds/modal', seed: Seed.new(crop: @crop, owner: current_member)
= link_to new_post_path(crop_id: crop.slug), class: 'btn', id: 'post-button' do
= post_icon
Post
- if active_plantings.any?
= render 'plantings/failed_modal', crop: crop, active_plantings: active_plantings
+1 -1
View File
@@ -85,7 +85,7 @@
-# Only crop wranglers see the crop hierarchy (for now)
- if can? :wrangle, @crop
= f.collection_select(:parent_id, Crop.all.order(:name), :id, :name,
= f.select(:parent_id, Crop.order(:name).pluck(:name, :id),
{ include_blank: true, label: 'Parent crop'})
%span.help-block Optional. For setting up crop hierarchies for varieties etc.
+10 -9
View File
@@ -5,18 +5,19 @@
%p Nobody has harvested this crop yet.
- unless crop.harvests.empty?
%ul.list-group.list-group-flush
- Harvest.where(crop: crop).includes(:owner).order(harvested_at: :desc).limit(3).each do |harvest|
%li.list-group-item
= link_to harvest_path(harvest), class: 'card-link' do
= harvest_icon
#{harvest.owner} harvested #{display_quantity(harvest)}.
.float-right= render 'members/location', member: harvest.owner
.harvest-timeago
%small #{standard_time_distance(harvest.harvested_at, Time.zone.now.to_date)}
- Rails.cache.fetch([crop, "recent_harvests", Time.zone.today]) do
- Harvest.where(crop: crop).includes(:owner).order(harvested_at: :desc).limit(3).each do |harvest|
%li.list-group-item
= link_to harvest_path(harvest), class: 'card-link' do
= harvest_icon
#{harvest.owner} harvested #{display_quantity(harvest)}.
.float-right= render 'members/location', member: harvest.owner
.harvest-timeago
%small #{standard_time_distance(harvest.harvested_at, Time.zone.now.to_date)}
%li.list-group-item= link_to "View all #{crop.name} harvests", crop_harvests_path(crop), class: 'card-link'
- if crop.approved?
- if current_member
%li.list-group-item= link_to "Harvest #{crop.name}", new_harvest_path(crop_id: crop.id), class: 'btn btn-block'
%li.list-group-item= link_to "Harvest #{crop.name}", new_harvest_path(harvest: { crop_id: crop.id }), class: 'btn btn-block'
- else
%li.list-group-item.active
= icon 'fas', 'user'
+2
View File
@@ -8,6 +8,8 @@
= link_to planting_path(planting), class: 'card-link' do
= planting_icon
= planting
- if can?(:edit, planting)
.float-right= render 'plantings/actions', planting: planting
.float-right= render 'members/location', member: planting.owner
.card-footer
- if crop.approved?
+1 -1
View File
@@ -6,7 +6,7 @@
Nobody has posted about #{crop.name.pluralize} yet.
%p
- if can? :create, Post
= link_to "Post something", new_post_path, class: 'btn btn-default'
= link_to "Post something", new_post_path(crop_id: crop.slug), class: 'btn btn-default'
- else
= render partial: "shared/signin_signup",
locals: { to: "post your tips and experiences growing #{crop.name.pluralize}" }
+9 -8
View File
@@ -44,8 +44,10 @@ csv.headers *all_headers
@crops.each do |c|
csv.row c do |csv, crop|
csv.cells :id, :name, :en_wikipedia_url
csv.cell :growstuff_url, crop_url(c)
csv.cell :id, c.id
csv.cell :name, c.name
csv.cell :en_wikipedia_url, c.en_wikipedia_url
csv.cell :growstuff_url, crop_url(slug: c.slug)
if c.scientific_names.any?
csv.cell :default_scientific_name, c.default_scientific_name
@@ -58,10 +60,10 @@ csv.headers *all_headers
end
csv.cell :plantings_count, c.plantings_count || 0
csv.cell :seeds_count, c.seeds.size[]
csv.cell :seeds_count, c.seeds.size
csv.cell :harvests_count, c.harvests.size
# Sunniness
# Sunniness
sunniness = c.sunniness
sunniness_rec = sunniness.max_by{|k,v| v}
@@ -74,7 +76,7 @@ csv.headers *all_headers
# Planted from
planted_from = c.planted_from
planted_from = c.planted_from
planted_from_rec = planted_from.max_by{|k,v| v}
if planted_from_rec
csv.cell :plant_from_recommendation, planted_from_rec[0]
@@ -105,12 +107,11 @@ csv.headers *all_headers
csv.cell col, harvested_plant_parts[pp] || 0
end
csv.cell :added_by_member_id, c.creator.id
csv.cell :added_by_member_name, c.creator.to_s
csv.cell :added_by_member_id, c.creator&.id
csv.cell :added_by_member_name, c.creator&.to_s
csv.cell :date_added, c.created_at.to_fs(:db)
csv.cell :last_modified, c.updated_at.to_fs(:db)
csv.cell :license, "CC-BY-SA Growstuff http://growstuff.org/"
end
end
+14 -10
View File
@@ -36,10 +36,11 @@
= cute_icon
= render 'predictions', crop: @crop
- if @crop.all_companions.any?
%section.companions
%h2 Companions
- @crop.all_companions.each do |companion|
= render 'crops/tiny', crop: companion
- cache [@crop, 'companions'] do
%section.companions
%h2 Companions
- @crop.all_companions.each do |companion|
= render 'crops/tiny', crop: companion
- if crop_or_parent(@crop, :en_youtube_url).present?
%section.youtube
@@ -73,10 +74,11 @@
= pie_chart crop_harvested_for_path(@crop, format: :json), legend: "bottom"
- if @crop.varieties.any?
%section.varieties
%h2 Varieties
.index-cards
= render 'varieties', crop: @crop
- cache [@crop, 'varieties'] do
%section.varieties
%h2 Varieties
.index-cards
= render 'varieties', crop: @crop
%section.crop-map
%h2
@@ -134,9 +136,11 @@
= render 'harvests', crop: @crop
= render 'find_seeds', crop: @crop
= render 'openfarm_data', crop: @crop
- cache [@crop, 'openfarm_data'] do
= render 'openfarm_data', crop: @crop
= render 'nutritional_data', crop: @crop
- cache [@crop, 'nutritional_data'] do
= render 'nutritional_data', crop: @crop
= cute_icon
.card
@@ -28,6 +28,12 @@
= f.check_box :send_planting_reminder
Receive regular reminders to track your planting and harvesting.
.form-group
.col-md-offset-2.col-md-8.checkbox
%label
= f.check_box :send_harvest_reminder
Receive regular reminders of upcoming harvests.
.form-group
.col-md-offset-2.col-md-8.checkbox
%label
+1
View File
@@ -6,6 +6,7 @@
- @forums.each do |forum|
%h2= forum
%p= forum.description
%p
= localize_plural(forum.posts, Post)
|
+27
View File
@@ -102,6 +102,8 @@
%strong Collaborators:
- if can?(:create, GardenCollaborator.new(garden: @garden))
= link_to "Manage", garden_garden_collaborators_path(@garden)
- elsif current_member.present? && (collab = @garden.garden_collaborators.find_by(member: current_member))
= link_to "Leave garden", garden_garden_collaborator_path(@garden, collab), method: :delete, class: 'text-danger', data: { confirm: 'Are you sure you want to leave this garden?' }
- if @garden.garden_collaborators.any?
%ul
- @garden.garden_collaborators.each do |collabator|
@@ -122,6 +124,31 @@
%strong Garden type:
= @garden.garden_type.name
- if @garden.location_wikidata_id.present?
%hr
%p
%small
Data about this location from
= link_to "wikidata", "https://www.wikidata.org/wiki/#{@garden.location_wikidata_id}", target: '_blank', rel: 'noopener noreferrer'
%p
%strong Highest temperature:
- if @garden.highest_temp_c.present?
= "#{ @garden.highest_temp_c.round(1) }°C"
- else
Not known
%p
%strong Lowest temperature:
- if @garden.lowest_temp_c.present?
= "#{ @garden.lowest_temp_c.round(1) }°C"
- else
Not known
- elsif can?(:edit, @garden) && @garden.location.present?
.alert.alert-info
%p Wikidata information is missing for this location.
= button_to "Fetch Wikidata info", fetch_wikidata_garden_path(@garden), method: :post, class: 'btn btn-info btn-sm'
.card
.card-header
%h4 #{@garden.owner}'s gardens
+11
View File
@@ -52,6 +52,17 @@
= f.select(:weight_unit, Harvest::WEIGHT_UNITS_VALUES, { include_blank: false }, class: 'form-control')
= f.text_area :description, rows: 6, label: 'Notes'
- if @planting.present?
.row
.col-md-12
= f.range_field :overall_rating, min: 1, max: 5, value: @planting.overall_rating, include_blank: 'Leave blank', label: 'Overall Rating - Planting', list: "rating-list", title: "How well is the planting going?"
%datalist{"id": "rating-list"}
%option{"value": "1"} Poor
%option{"value": "2"}
%option{"value": "3"}
%option{"value": "4"}
%option{"value": "5"} Great
.card-footer
.text-right= f.submit 'Save'
+4 -2
View File
@@ -13,7 +13,7 @@
.index-cards
- harvest.crop.plant_parts.order(:name).each do |plant_part|
.card
= link_to harvests_path(harvest: {planting_id: harvest.planting_id, crop_id: harvest.crop_id, plant_part_id: plant_part.id}), method: :post do
= link_to new_harvest_path(harvest: {planting_id: harvest.planting_id, crop_id: harvest.crop_id, plant_part_id: plant_part.id}) do
.card-title.text-center
%h3= plant_part_icon(plant_part.name)
%h3= plant_part.name
@@ -22,10 +22,12 @@
%h6 All Plant parts
%nav.nav
- PlantPart.all.order(:name).each do |plant_part|
= link_to harvests_path(harvest: {planting_id: harvest.planting_id, crop_id: harvest.crop_id, plant_part_id: plant_part.id}), method: :post, class: 'nav-link border' do
= link_to new_harvest_path(harvest: {planting_id: harvest.planting_id, crop_id: harvest.crop_id, plant_part_id: plant_part.id}), class: 'nav-link border' do
= plant_part_icon(plant_part.name)
= plant_part
%a.btn#modalHarvestButton{"data-bs-target" => "#modelHarvestForm", "data-bs-toggle" => "modal", href: ""}
= harvest_icon
Record harvest
+4 -3
View File
@@ -1,3 +1,4 @@
%p
%small
= harvest.harvested_at
- cache harvest do
%p
%small
= harvest.harvested_at
+1 -1
View File
@@ -4,7 +4,7 @@
- content_for :breadcrumbs do
- if @owner
%li.breadcrumb-item= link_to 'Harvests', harvests_path
%li.breadcrumb-item.active= link_to "#{@owner}'s harvests", harvests_path(owner: @owner)
%li.breadcrumb-item.active= link_to "#{@owner}'s harvests", member_harvests_path(@owner)
- else
%li.breadcrumb-item.active= link_to "Harvests", harvests_path
.row
+7 -6
View File
@@ -1,11 +1,12 @@
%h2= t('.recently_planted')
- Planting.homepage_records(6).each do |planting|
= link_to planting_path(slug: planting['slug']), class: 'list-group-item list-group-item-action flex-column align-items-start' do
- next unless planting.thumbnail_url.present?
= link_to planting_path(slug: planting.slug), class: 'list-group-item list-group-item-action flex-column align-items-start' do
.d-flex.w-100.justify-content-between.homepage--list-item
%p.mb-2
= image_tag planting['thumbnail_url'], width: 75, class: 'rounded shadow', alt: "Image of #{planting['crop_name']} by #{planting['owner_login_name']}"
= image_tag planting.thumbnail_url, width: 75, class: 'rounded shadow', alt: "Image of #{planting.crop_name} by #{planting.owner_login_name}"
.text-right
%h4= planting['crop_name']
- if planting['planted_from'].present?
%span.badge.badge-success= planting['planted_from'].pluralize
%small.text-muted planted by #{planting['owner_login_name']}
%h4= planting.crop_name
- if planting.planted_from.present?
%span.badge.badge-success= planting.planted_from.pluralize
%small.text-muted planted by #{planting.owner_login_name}
Loaded 100 of 352 files, more files were not shown because too many files have changed in this diff. Show more