Wij hechten veel waarde aan transparantie, dus we hebben er geen probleem mee om onze code te tonen over hoe we de rankings berekenen.

Ruby Code: RankCalculation Module

    
      module RankCalculation
        extend ActiveSupport::Concern

        def weighted_rating(r, v, m, c)
          (v / (v.to_f + m)) * r + (m / (v.to_f + m)) * c
        end

        def overall_score(google_avg:, treatwell_avg:, m_google:, m_treatwell:)
          google_score = if google_rating.present? && google_rating_count.present?
                          weighted_rating(google_rating, google_rating_count, m_google, google_avg)
                        end

          treatwell_score = if treatwell_rating.present? && treatwell_rating_count.present?
                              weighted_rating(treatwell_rating, treatwell_rating_count, m_treatwell, treatwell_avg)
                            end

          if google_score && treatwell_score
            (google_score + treatwell_score) / 2.0
          else
            google_score || treatwell_score || 0
          end
        end

        def total_reviews
          (google_rating_count || 0) + (treatwell_rating_count || 0)
        end

        def normalize_rating(rating)
          return 0.0 if rating.nil?
          scaled = Math.exp(rating - 5.0)
          penalty = rating < 4.8 ? 0.7 : 1.0
          (scaled * penalty).clamp(0.0, 1.0)
        end


        def reputation_factor(count, max_count)
          return 0 if count.to_f <= 0 || max_count.to_f <= 0
          Math.log(1 + count.to_f) / Math.log(1 + max_count.to_f)
        end

        def adjusted_overall_score(google_avg:, treatwell_avg:, m_google:, m_treatwell:)
          google_weight = 0.45
          google_count_weight = 0.10
          google_rep_weight = 0.10
          google_growth_weight = 0.05
          treatwell_weight = 0.20
          treatwell_count_weight = 0.05
          treatwell_rep_weight = 0.03
          treatwell_growth_weight = 0.02

          capped_google_growth = [google_review_growth.to_f, 5].min
          capped_treatwell_growth = [treatwell_review_growth.to_f, 5].min

          max_google_reviews = Salon.maximum(:google_rating_count).to_f.nonzero? || 1.0
          max_treatwell_reviews = Salon.maximum(:treatwell_rating_count).to_f.nonzero? || 1.0
          max_google_growth = 5.0
          max_treatwell_growth = 5.0

          g_rating = normalize_rating(google_rating.to_f)
          g_count = google_rating_count.to_f / max_google_reviews
          g_rep = reputation_factor(google_rating_count, max_google_reviews)
          g_growth = (google_rating.to_f >= 4.8) ? (capped_google_growth / max_google_growth) : 0.0

          t_rating = normalize_rating(treatwell_rating.to_f)
          t_count = treatwell_rating_count.to_f / max_treatwell_reviews
          t_rep = reputation_factor(treatwell_rating_count, max_treatwell_reviews)
          t_growth = (treatwell_rating.to_f >= 4.8) ? (capped_treatwell_growth / max_treatwell_growth) : 0.0

          total = (
            g_rating * google_weight +
            g_count * google_count_weight +
            g_rep * google_rep_weight +
            g_growth * google_growth_weight +
            t_rating * treatwell_weight +
            t_count * treatwell_count_weight +
            t_rep * treatwell_rep_weight +
            t_growth * treatwell_growth_weight
          ) * 100.0

          total
        end

        module ClassMethods
          def update_rankings!(m_google: 50.0, m_treatwell: 100.0)
            google_avg = where.not(google_rating: nil).average(:google_rating).to_f
            treatwell_avg = where.not(treatwell_rating: nil).average(:treatwell_rating).to_f

            salons = all.to_a
            scores = salons.map do |salon|
              adjusted = salon.adjusted_overall_score(
                google_avg: google_avg,
                treatwell_avg: treatwell_avg,
                m_google: m_google,
                m_treatwell: m_treatwell
              )
              [salon, adjusted]
            end

            sorted = scores.sort_by { |_, score| -score }
            sorted.each_with_index do |(salon, score), index|
              salon.update!(ranking: index + 1)

              computed_percentage = if score >= 95
                                      100
                                    else
                                      score.round
                                    end
              salon.update_column(:ranking_percentage, computed_percentage)
            end
          end
        end
      end