Optimize seed_sow_months method for improved performance and accuracy in calculating sow months based on latitude.

This commit is contained in:
Brenda Wallace committed 2026-11-04 06:31:14 +13:00
1 parent d0567f3516
commit d8a012efa3
1 file changed
+13 -7
+13 -7
View File
@@ -220,13 +220,19 @@ class Crop < ApplicationRecord
# where they live can't say which hemisphere they mean, and are left out. Empty
# when no packet says anything.
def seed_sow_months
rows = Seed.of_crop(self).joins(:owner).where.not(members: { latitude: nil })
.where('cardinality(seeds.sow_months) > 0').pluck('seeds.sow_months', 'members.latitude')
counts = Hash.new(0)
rows.each do |months, latitude|
months.map { |month| latitude.negative? ? month : opposite_month(month) }.uniq.each { |month| counts[month] += 1 }
end
counts.select { |_month, count| count * 2 >= rows.size }.keys.sort
packets = Seed.of_crop(self).joins(:owner).where.not(members: { latitude: nil }).where('cardinality(seeds.sow_months) > 0')
total = packets.count
return [] if total.zero?
months = Seed.connection.select_rows(<<~SQL.squish)
SELECT month, COUNT(*) FROM (
SELECT DISTINCT packets.id,
CASE WHEN packets.latitude < 0 THEN sown ELSE ((sown + 5) % 12) + 1 END AS month
FROM (#{packets.select('seeds.id', 'seeds.sow_months', 'members.latitude').to_sql}) packets,
unnest(packets.sow_months) AS sown
) per_packet GROUP BY month HAVING COUNT(*) * 2 >= #{total.to_i}
SQL
months.map { |month, _count| month.to_i }.sort
end
# The months to sow in the northern hemisphere: the southern ones, six months on.