Merge pull request #775 from pozorvlak/speed_up_homepage

Speed up homepage by calculating "interesting" things more efficiently
This commit is contained in:
Cesy
2015-08-05 19:18:56 +01:00
2 changed files with 15 additions and 38 deletions

View File

@@ -29,6 +29,12 @@ class Crop < ActiveRecord::Base
scope :pending_approval, -> { where(:approval_status => "pending") }
scope :approved, -> { where(:approval_status => "approved") }
scope :rejected, -> { where(:approval_status => "rejected") }
# Crops with enough plantings and photos
# ActiveRecord wizardry copied from
# http://stackoverflow.com/questions/13226913/how-do-i-select-all-records-with-more-than-n-child-records
scope :has_plantings, ->(min_plantings) { select("crops.*").joins(:plantings).group("crops.id").having("count(crops.id) >= ?", min_plantings) }
scope :has_photos, ->(min_photos) { select("crops.*").joins(:photos).group("crops.id").having("count(crops.id) >= ?", min_photos) }
scope :interesting, -> { has_plantings(3).has_photos(3).randomized.limit(12) }
## Wikipedia urls are only necessary when approving a crop
validates :en_wikipedia_url,
@@ -174,14 +180,6 @@ class Crop < ActiveRecord::Base
return popular_plant_parts
end
def interesting?
min_plantings = 3 # needs this many plantings to be interesting
min_photos = 3 # needs this many photos to be interesting
return false unless photos.size >= min_photos
return false unless plantings_count >= min_plantings
return true
end
def pending?
approval_status == "pending"
end
@@ -202,19 +200,6 @@ class Crop < ActiveRecord::Base
[ "already in database", "not edible", "not enough information", "other" ]
end
# Crop.interesting
# returns a list of interesting crops, for use on the homepage etc
def Crop.interesting
howmany = 12 # max number to find
interesting_crops = Array.new
Crop.randomized.each do |c|
break if interesting_crops.size == howmany
next unless c.interesting?
interesting_crops.push(c)
end
return interesting_crops
end
# Crop.create_from_csv(row)
# used by db/seeds.rb and rake growstuff:import_crops
# CSV fields:

View File

@@ -90,10 +90,6 @@ class Planting < ActiveRecord::Base
return photos.first
end
def interesting?
return photos.present?
end
def calculate_days_before_maturity(planting, crop)
p_crop = Planting.where(:crop_id => crop).where.not(:id => planting)
differences = p_crop.collect do |p|
@@ -113,19 +109,15 @@ class Planting < ActiveRecord::Base
# we can't do this via a scope (as far as we know) so sadly we have to
# do it this way.
def Planting.interesting(howmany=12, require_photo=true)
interesting_plantings = Array.new
seen_owners = Hash.new(false) # keep track of which owners we've seen already
Planting.all.each do |p|
break if interesting_plantings.size == howmany # got enough yet?
if require_photo
next unless p.photos.present? # skip those without photos, if required
end
next if seen_owners[p.owner] # skip if we already have one from this owner
seen_owners[p.owner] = true # we've seen this owner
interesting_plantings.push(p)
if require_photo then
candidates = Planting.joins(:photos).uniq
else
candidates = Planting
end
return interesting_plantings
# Find the most recent acceptable planting for each member
most_recent_ids = candidates.select("max(plantings.id)")
.unscope(:order)
.group("plantings.owner_id")
return candidates.where(id: most_recent_ids).limit(howmany)
end
end