From a1659f3600b05a047fb2bc79eeb868de431b8d2d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Sep 2026 07:04:43 +0000 Subject: [PATCH 1/9] Bump msgpack from 1.8.4 to 1.8.5 Bumps [msgpack](https://github.com/msgpack/msgpack-ruby) from 1.8.4 to 1.8.5. - [Changelog](https://github.com/msgpack/msgpack-ruby/blob/master/ChangeLog) - [Commits](https://github.com/msgpack/msgpack-ruby/compare/v1.8.4...v1.8.5) --- updated-dependencies: - dependency-name: msgpack dependency-version: 1.8.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index fae5e0bfb..1ff54a7e7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -429,7 +429,7 @@ GEM minitest (6.0.6) drb (~> 2.0) prism (~> 1.5) - msgpack (1.8.4) + msgpack (1.8.5) multi_json (1.19.1) multi_xml (0.8.1) bigdecimal (>= 3.1, < 5) From 6fba37fc9cf69fe807e3c1ef3ef82fe5db211a14 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 17 Sep 2026 12:43:34 +0000 Subject: [PATCH 2/9] Add require: false to aws-sdk-s3 in Gemfile Prevents aws-sdk-s3, aws-sdk-core, and aws-sdk-kms from auto-loading on application boot across web and worker processes. The gem is required on-demand in config/sitemap.rb. Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com> --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 0d68f7043..c898fb59a 100644 --- a/Gemfile +++ b/Gemfile @@ -209,5 +209,5 @@ gem "i18n_data", "~> 1.1" gem "paper_trail", "~> 17.0" -gem 'aws-sdk-s3', '~> 1', '>= 1.114.0' +gem 'aws-sdk-s3', '~> 1', '>= 1.114.0', require: false gem 'sitemap_generator' From bbcef2163b4b4a126c2ab86f9abf529386364bc5 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 17 Sep 2026 12:41:39 +0000 Subject: [PATCH 3/9] Use database distinct count for GardenType gardens Replaces in-memory `.uniq.count`, `.uniq.empty?`, and `.uniq.each` calls with database-level `.distinct` queries on GardenType gardens association. Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com> --- app/models/garden_type.rb | 5 +++-- app/views/garden_types/show.html.haml | 4 ++-- spec/models/garden_type_spec.rb | 29 +++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/app/models/garden_type.rb b/app/models/garden_type.rb index 83336d46f..d317f9c89 100644 --- a/app/models/garden_type.rb +++ b/app/models/garden_type.rb @@ -14,8 +14,9 @@ class GardenType < ApplicationRecord name.gsub!(/[^A-Za-z]/, '') end - def subtitler(garden_type) - num = garden_type.gardens.uniq.count + def subtitler(garden_type = self) + garden_type ||= self + num = garden_type.gardens.distinct.count s = num > 1 || num.zero? ? "s are" : " is" "#{num} garden#{s} using this garden type" end diff --git a/app/views/garden_types/show.html.haml b/app/views/garden_types/show.html.haml index cd9575965..44b49e05a 100644 --- a/app/views/garden_types/show.html.haml +++ b/app/views/garden_types/show.html.haml @@ -5,8 +5,8 @@ - content_for :buttonbar do = render 'garden_types/actions', garden_type: @garden_type -- if @garden_type.gardens.uniq.empty? +- if @garden_type.gardens.distinct.empty? %p There are no gardens to display. - else - - @garden_type.gardens.uniq.each do |garden| + - @garden_type.gardens.distinct.each do |garden| = render 'gardens/overview', garden: garden diff --git a/spec/models/garden_type_spec.rb b/spec/models/garden_type_spec.rb index fd998354b..a9223c286 100644 --- a/spec/models/garden_type_spec.rb +++ b/spec/models/garden_type_spec.rb @@ -37,4 +37,33 @@ describe GardenType do it { expect(garden_type.gardens.size).to eq(1) } it { expect { garden_type.destroy }.not_to change(Garden, :count) } end + + describe "#subtitler" do + let(:garden_type) { create(:garden_type, name: "Community Plot") } + + context "when there are no gardens" do + it "returns 0 gardens string" do + expect(garden_type.subtitler).to eq("0 gardens are using this garden type") + end + end + + context "when there is 1 garden" do + before { create(:garden, garden_type:) } + + it "returns 1 garden string" do + expect(garden_type.subtitler).to eq("1 garden is using this garden type") + end + end + + context "when there are multiple gardens" do + before do + create(:garden, garden_type:) + create(:garden, garden_type:) + end + + it "returns plural gardens string" do + expect(garden_type.subtitler).to eq("2 gardens are using this garden type") + end + end + end end From 88bb77ab013754249c7fcd2f576e1d4dcef2ce1c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Sep 2026 21:10:38 +0000 Subject: [PATCH 4/9] Bump aws-sdk-s3 from 1.229.0 to 1.232.0 Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.229.0 to 1.232.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.232.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 1ff54a7e7..1513386e6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -127,8 +127,8 @@ GEM autoprefixer-rails (10.4.16.0) execjs (~> 2) aws-eventstream (1.4.0) - aws-partitions (1.1279.0) - aws-sdk-core (3.254.1) + aws-partitions (1.1287.0) + aws-sdk-core (3.257.0) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.992.0) aws-sigv4 (~> 1.9) @@ -136,11 +136,12 @@ GEM bigdecimal jmespath (~> 1, >= 1.6.1) logger - aws-sdk-kms (1.130.0) - aws-sdk-core (~> 3, >= 3.254.0) + rexml (~> 3.4, >= 3.4.2) + aws-sdk-kms (1.132.0) + aws-sdk-core (~> 3, >= 3.256.0) aws-sigv4 (~> 1.5) - aws-sdk-s3 (1.229.0) - aws-sdk-core (~> 3, >= 3.254.1) + aws-sdk-s3 (1.232.0) + aws-sdk-core (~> 3, >= 3.256.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.5) aws-sigv4 (1.12.1) @@ -157,7 +158,7 @@ GEM erubi (>= 1.0.0) rack (>= 0.9.0) rouge (>= 1.0.0) - bigdecimal (4.1.2) + bigdecimal (4.1.3) bluecloth (2.2.0) bonsai-elasticsearch-rails (7.0.1) elasticsearch-model (< 8) From 882b4793344db2e4a68b8176c52ad94653259c75 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 17 Sep 2026 21:21:20 +0000 Subject: [PATCH 5/9] Remove Unicorn dependency and enable Puma clustered workers with preloading Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com> --- .rubocop.yml | 1 - Gemfile | 1 - config/puma.rb | 4 ++-- config/unicorn.rb | 25 ------------------------- 4 files changed, 2 insertions(+), 29 deletions(-) delete mode 100644 config/unicorn.rb diff --git a/.rubocop.yml b/.rubocop.yml index 6323a5281..59ac0c5bd 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -56,7 +56,6 @@ Style/Documentation: # Include: app/**/*.rb, config/**/*.rb, db/**/*.rb, lib/**/*.rb Rails/Output: Exclude: - - 'config/unicorn.rb' - 'db/seeds.rb' Metrics/BlockLength: diff --git a/Gemfile b/Gemfile index c898fb59a..b2adfdc1c 100644 --- a/Gemfile +++ b/Gemfile @@ -59,7 +59,6 @@ gem 'rails-assets-leaflet.markercluster', source: 'https://rails-assets.org' gem 'pg' gem 'ruby-units' # for unit conversion -gem 'unicorn' # http server gem "comfortable_mexican_sofa", git: "https://github.com/restarone/comfortable-mexican-sofa.git" diff --git a/config/puma.rb b/config/puma.rb index a47b28904..d7d146412 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -27,14 +27,14 @@ pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" } # Workers do not work on JRuby or Windows (both of which do not support # processes). # -# workers ENV.fetch("WEB_CONCURRENCY") { 2 } +workers ENV.fetch("WEB_CONCURRENCY") { 2 } # Use the `preload_app!` method when specifying a `workers` number. # This directive tells Puma to first boot the application and load code # before forking the application. This takes advantage of Copy On Write # process behavior so workers use less memory. # -# preload_app! +preload_app! # Allow puma to be restarted by `rails restart` command. plugin :tmp_restart diff --git a/config/unicorn.rb b/config/unicorn.rb deleted file mode 100644 index c4218569a..000000000 --- a/config/unicorn.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -# from https://blog.heroku.com/archives/2013/2/27/unicorn_rails -worker_processes 3 -timeout 30 -preload_app true - -before_fork do |_server, _worker| - Signal.trap 'TERM' do - puts 'Unicorn master intercepting TERM and sending myself QUIT instead' - Process.kill 'QUIT', Process.pid - end - - defined?(ActiveRecord::Base) && - ActiveRecord::Base.connection.disconnect! -end - -after_fork do |_server, _worker| - Signal.trap 'TERM' do - puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to sent QUIT' - end - - defined?(ActiveRecord::Base) && - ActiveRecord::Base.establish_connection -end From 9d10682ff36f02ef4cdaf447e82ba1a25c934846 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 18 Sep 2026 02:40:38 +0000 Subject: [PATCH 6/9] Remove Unicorn dependency and update Gemfile.lock, enable Puma clustered workers with preloading Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com> --- Gemfile.lock | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 1513386e6..e7b1f549a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -376,7 +376,6 @@ GEM concurrent-ruby railties (>= 4.1) jsonapi-swagger (0.8.1) - kgio (2.11.4) kramdown (2.4.0) rexml language_server-protocol (3.17.0.6) @@ -561,7 +560,6 @@ GEM tsort (>= 0.2) zeitwerk (~> 2.6) rainbow (3.1.1) - raindrops (0.20.1) rake (13.4.2) rb-fsevent (0.11.2) rb-inotify (0.11.1) @@ -740,9 +738,6 @@ GEM unicode-display_width (3.2.0) unicode-emoji (~> 4.1) unicode-emoji (4.2.0) - unicorn (6.1.0) - kgio (~> 2.6) - raindrops (~> 0.7) uniform_notifier (1.18.0) uri (1.1.1) useragent (0.16.11) @@ -884,7 +879,6 @@ DEPENDENCIES sprockets (< 4) terser timecop - unicorn validate_url vcr webrat @@ -893,7 +887,7 @@ DEPENDENCIES xmlrpc RUBY VERSION - ruby 4.0.6 + ruby 4.0.6 BUNDLED WITH - 2.4.22 + 4.0.7 From ce00cc9c5f949832f9c992335ba9cb8b8a526d97 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Fri, 18 Sep 2026 13:24:31 +0930 Subject: [PATCH 7/9] Merge pull request #4794 from Growstuff/improve-cache-memory-usage-9918781528129420138 Optimize caching memory usage in PhotoCapable and CropsHelper --- app/helpers/crops_helper.rb | 4 ++-- app/models/concerns/photo_capable.rb | 16 ++++++++-------- spec/helpers/crops_helper_spec.rb | 21 +++++++++++++++++++++ spec/models/crop_spec.rb | 7 +++++++ 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/app/helpers/crops_helper.rb b/app/helpers/crops_helper.rb index 1ac4c626e..41484b754 100644 --- a/app/helpers/crops_helper.rb +++ b/app/helpers/crops_helper.rb @@ -77,7 +77,7 @@ module CropsHelper } end - crop.posts.each do |post| + crop.posts.limit(50).each do |post| subject_of_entities << { '@type': "SocialMediaPosting", url: post_url(post), @@ -89,7 +89,7 @@ module CropsHelper } end - crop.photos.each do |photo| + crop.photos.limit(50).each do |photo| images << photo.fullsize_url end end diff --git a/app/models/concerns/photo_capable.rb b/app/models/concerns/photo_capable.rb index b8f4ff09a..9308d9068 100644 --- a/app/models/concerns/photo_capable.rb +++ b/app/models/concerns/photo_capable.rb @@ -10,18 +10,18 @@ module PhotoCapable scope :has_photos, -> { includes(:photos).where.not(photos: { id: nil }) } def default_photo - Rails.cache.fetch("#{cache_key_with_version}/default_photo", expires_in: 8.hours) do - most_liked_photo - end + most_liked_photo end def thumbnail_url - df = default_photo + Rails.cache.fetch("#{cache_key_with_version}/thumbnail_url", expires_in: 8.hours) do + df = default_photo - if df - df.source == 'flickr' ? df.fullsize_url : df.thumbnail_url - elsif respond_to?(:crop) && crop.present? - crop.thumbnail_url + if df + df.source == 'flickr' ? df.fullsize_url : df.thumbnail_url + elsif respond_to?(:crop) && crop.present? + crop.thumbnail_url + end end end diff --git a/spec/helpers/crops_helper_spec.rb b/spec/helpers/crops_helper_spec.rb index 7099ad066..9899a6e72 100644 --- a/spec/helpers/crops_helper_spec.rb +++ b/spec/helpers/crops_helper_spec.rb @@ -42,4 +42,25 @@ describe CropsHelper do end end end + + describe '#crop_jsonld_data' do + let(:crop) { create(:crop, name: 'Tomato') } + + it 'returns schema.org BioChemEntity hash structure' do + data = helper.crop_jsonld_data(crop) + expect(data['@context']).to eq('https://schema.org') + expect(data['@type']).to eq('BioChemEntity') + expect(data[:name]).to eq('Tomato') + end + + it 'caps posts and photos at 50' do + create_list(:post, 60, crops: [crop]) + photos = create_list(:photo, 60) + photos.each { |p| crop.photo_associations.create!(photo: p) } + + data = helper.crop_jsonld_data(crop, full_attributes: true) + expect(data[:subjectOf].size).to eq(50) + expect(data[:image].size).to eq(50) + end + end end diff --git a/spec/models/crop_spec.rb b/spec/models/crop_spec.rb index 2c5890dea..dce317c77 100644 --- a/spec/models/crop_spec.rb +++ b/spec/models/crop_spec.rb @@ -154,6 +154,13 @@ describe Crop do it { expect(crop.default_photo).to eq photo } + it 'caches thumbnail_url string in Rails.cache' do + expected_url = photo.source == 'flickr' ? photo.fullsize_url : photo.thumbnail_url + expect(crop.thumbnail_url).to eq expected_url + cached_value = Rails.cache.read("#{crop.cache_key_with_version}/thumbnail_url") + expect(cached_value).to eq expected_url + end + include_examples 'has default photo' end From 41887c944710e477307b991de85063b97b836546 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 19 Sep 2026 17:46:33 +0930 Subject: [PATCH 8/9] Bump adm-zip from 0.6.0 to 0.6.1 (#4798) Bumps [adm-zip](https://github.com/cthackers/adm-zip) from 0.6.0 to 0.6.1. - [Release notes](https://github.com/cthackers/adm-zip/releases) - [Changelog](https://github.com/cthackers/adm-zip/blob/master/history.md) - [Commits](https://github.com/cthackers/adm-zip/compare/v0.6.0...v0.6.1) --- updated-dependencies: - dependency-name: adm-zip dependency-version: 0.6.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 8615ef623..166a92aa8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -631,9 +631,9 @@ acorn@^8.16.0: integrity sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ== adm-zip@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.6.0.tgz#bbc5c6c333755e967a06dd98747f431e1d53a3cf" - integrity sha512-XleryMhbuksdKtofnWZ9Sk+4CUTbms4Mb/EU32SZwToAyZ5RgVos/ki8n+yr0LWHOGKuakbXTuuYNHLQjhddgg== + version "0.6.1" + resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.6.1.tgz#5b95da4a6e7af0663b71457c06e1517fa6ac8d5f" + integrity sha512-Xwrja8nx9e5o2N1my4DsKCeKpdrnACyr1wtbPxBDgGzKzKyE9kRtBFA8mWldI+RVlD7CBZNWY/wQ2+ydwOR6kQ== agent-base@^7.1.0, agent-base@^7.1.2: version "7.1.4" From c0614b50bc853f7aaa32a1e53f7bd2efecd7b004 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Sat, 19 Sep 2026 18:19:00 +0930 Subject: [PATCH 9/9] Optimize CanCan abilities using declarative hash conditions (#4797) Refactor block-based CanCan ability definitions for ScientificName, AlternateName, Planting, Activity, and Harvest into declarative hash conditions to eliminate per-record SQL queries and N+1 evaluation overhead. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> --- app/models/ability.rb | 36 +++++++--------------------- app/models/alternate_name.rb | 2 +- app/models/scientific_name.rb | 2 +- config/initializers/faraday_patch.rb | 9 +++++++ spec/models/ability_spec.rb | 19 +++++++++++++++ 5 files changed, 39 insertions(+), 29 deletions(-) create mode 100644 config/initializers/faraday_patch.rb diff --git a/app/models/ability.rb b/app/models/ability.rb index a53c16ec8..75427dfb1 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -36,14 +36,10 @@ class Ability can :read, Crop, approval_status: "approved" # scientific names should only be viewable if associated crop is approved cannot :read, ScientificName - can :read, ScientificName do |sn| - sn.crop.approved? - end + can :read, ScientificName, crop: { approval_status: "approved" } # ... same for alternate names cannot :read, AlternateName - can :read, AlternateName do |an| - an.crop.approved? - end + can :read, AlternateName, crop: { approval_status: "approved" } cannot :create, GardenType cannot :update, GardenType @@ -109,16 +105,10 @@ class Ability can :create, Planting can :update, Planting, garden: { owner_id: member.id }, crop: { approval_status: 'approved' } can :destroy, Planting, garden: { owner_id: member.id }, crop: { approval_status: 'approved' } - can :update, Planting do |planting| - planting.garden.garden_collaborators.where(member_id: member.id).any? - end + can :update, Planting, garden: { garden_collaborators: { member_id: member.id } } can :transplant, Planting, garden: { owner_id: member.id } - can :transplant, Planting do |planting| - planting.garden.garden_collaborators.where(member_id: member.id).any? - end - can :destroy, Planting do |planting| - planting.garden.garden_collaborators.where(member_id: member.id).any? - end + can :transplant, Planting, garden: { garden_collaborators: { member_id: member.id } } + can :destroy, Planting, garden: { garden_collaborators: { member_id: member.id } } can :create, GardenCollaborator, garden: { owner_id: member.id } can :update, GardenCollaborator, garden: { owner_id: member.id } @@ -128,24 +118,16 @@ class Ability can :create, Activity can :update, Activity, owner_id: member.id can :destroy, Activity, owner_id: member.id - can :update, Activity do |activity| - activity.garden&.garden_collaborators&.where(member_id: member.id)&.any? - end - can :destroy, Activity do |activity| - activity.garden&.garden_collaborators&.where(member_id: member.id)&.any? - end + can :update, Activity, garden: { garden_collaborators: { member_id: member.id } } + can :destroy, Activity, garden: { garden_collaborators: { member_id: member.id } } can :create, Harvest can :update, Harvest, owner_id: member.id can :destroy, Harvest, owner_id: member.id can :update, Harvest, owner_id: member.id, planting: { owner_id: member.id } can :destroy, Harvest, owner_id: member.id, planting: { owner_id: member.id } - can :update, Harvest do |harvest| - harvest.planting&.garden&.garden_collaborators&.where(member_id: member.id)&.any? - end - can :destroy, Harvest do |harvest| - harvest.planting&.garden&.garden_collaborators&.where(member_id: member.id)&.any? - end + can :update, Harvest, planting: { garden: { garden_collaborators: { member_id: member.id } } } + can :destroy, Harvest, planting: { garden: { garden_collaborators: { member_id: member.id } } } can :create, Photo can :update, Photo, owner_id: member.id diff --git a/app/models/alternate_name.rb b/app/models/alternate_name.rb index 1d755402e..e133d89e6 100644 --- a/app/models/alternate_name.rb +++ b/app/models/alternate_name.rb @@ -7,7 +7,7 @@ class AlternateName < ApplicationRecord validates :crop, presence: true validates :language, presence: true - after_commit :reindex + after_commit :reindex, if: -> { Searchkick.callbacks? } delegate :reindex, to: :crop end diff --git a/app/models/scientific_name.rb b/app/models/scientific_name.rb index 94ab605b6..1c8160bcb 100644 --- a/app/models/scientific_name.rb +++ b/app/models/scientific_name.rb @@ -5,7 +5,7 @@ class ScientificName < ApplicationRecord belongs_to :creator, class_name: 'Member', inverse_of: :created_scientific_names validates :name, presence: true validates :crop, presence: true - after_commit :reindex + after_commit :reindex, if: -> { Searchkick.callbacks? } delegate :reindex, to: :crop def to_s diff --git a/config/initializers/faraday_patch.rb b/config/initializers/faraday_patch.rb new file mode 100644 index 000000000..5d5ee1221 --- /dev/null +++ b/config/initializers/faraday_patch.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +# Faraday 2.x compatibility shim for Searchkick / Elasticsearch gem +module Faraday + class Error < StandardError + ConnectionFailed = Faraday::ConnectionFailed unless const_defined?(:ConnectionFailed) + TimeoutError = Faraday::TimeoutError unless const_defined?(:TimeoutError) + end +end diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index 8eced2577..219d4633d 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -34,6 +34,25 @@ describe Ability do end end + context 'scientific names and alternate names' do + let(:approved_crop) { create(:crop, approval_status: 'approved') } + let(:pending_crop) { create(:crop, approval_status: 'pending') } + let(:scientific_name) { create(:scientific_name, crop: approved_crop) } + let(:unapproved_scientific_name) { create(:scientific_name, crop: pending_crop) } + let(:alternate_name) { create(:alternate_name, crop: approved_crop) } + let(:unapproved_alternate_name) { create(:alternate_name, crop: pending_crop) } + + it 'can read scientific names and alternate names of approved crops' do + ability.should be_able_to(:read, scientific_name) + ability.should be_able_to(:read, alternate_name) + end + + it 'cannot read scientific names and alternate names of unapproved crops' do + ability.should_not be_able_to(:read, unapproved_scientific_name) + ability.should_not be_able_to(:read, unapproved_alternate_name) + end + end + context "crop wrangling" do let(:crop) { create(:crop) }