2016-11-08 2 views
2

私はいくつかのKPIを計算する必要がある学校のアプリケーション用のカスタムダッシュボードを作成しています。現在、それをやっているのは、コントローラのダッシュボード/インデックスアクションのOpportunityクラスからいくつかのクラスメソッドを呼び出して、タイルで使用される変数になります。したがって、各変数はダッシュボードの異なるタイルです。カスタムRailsダッシュボード、ビューで表示するデータ取得を最適化する方法は?

方法は、以下に示す機会クラスに属している:

class Opportunity < ApplicationRecord 
    belongs_to :organization 
    belongs_to :opportunity_status 
    has_many :tasks, dependent: :destroy 
    has_many :opportunity_status_logs, dependent: :destroy 

    before_create :create_status_log 
    after_update :create_status_log, if: :opportunity_status_id_changed? 

    validates :name, :description, :revenue, :opportunity_status_id, :closing_date, presence: true 
    validates :name, :description, format: { with: /\A[[:alpha:]a-zA-Z0-9ñÑ#()\-.,\s]+\z/ } 
    validates :revenue, numericality: true 
    validates :closing_date, inclusion: { in: (Time.zone.today..Time.zone.today+5.years) } 


    def create_status_log 
    OpportunityStatusLog.create(opportunity_id: self.id, opportunity_status_id: self.opportunity_status_id) 
    end 

    def status_updated_by(user) 
    @status_log = self.opportunity_status_logs.last 
    @status_log.user_id = user.id 
    @status_log.save! 
    end 

    def self.actives 
    self.where.not(opportunity_status_id: [11,12]) 
    end 

    def self.won 
    self.where(opportunity_status_id: 11) 
    end 

    def self.lost 
    self.where(opportunity_status_id: 12) 
    end 

    def self.average_revenue 
    self.won.average(:revenue) 
    end 

    def self.minimum_revenue 
    self.won.minimum(:revenue) 
    end 

    def self.maximum_revenue 
    self.won.maximum(:revenue) 
    end 

    def self.filter_by_status(status_id) 
    self.where(opportunity_status: status_id) 
    end 

    def self.relative_percentage(item_amount, total) 
    item_amount * 100/total 
    end 

    def self.conversion_rate 
    self.won.count/self.all.count.to_f * 100 
    end 

    def self.potential_revenue 
    self.actives.sum(:revenue) 
    end 
end 

と、これはコントローラが構成されている方法です。

class DashboardController < ApplicationController 
    before_action :authenticate_user! 

    def index 
    @opportunities = Opportunity.includes(:opportunity_status).all 
    @actives = Opportunity.actives.count 
    @won = Opportunity.won.count 
    @lost = Opportunity.lost.count 
    @average_revenue = Opportunity.average_revenue 
    @minimum_revenue = Opportunity.minimum_revenue 
    @maximum_revenue = Opportunity.maximum_revenue 
    @in_appreciation = Opportunity.filter_by_status(6).count 
    @in_value_proposition = Opportunity.filter_by_status(7).count 
    @in_management_analysis = Opportunity.filter_by_status(8).count 
    @in_proposal = Opportunity.filter_by_status(9).count 
    @in_review = Opportunity.filter_by_status(10).count 
    @app_perc = Opportunity.relative_percentage(@in_appreciation, @opportunities.count) 
    @vp_perc = Opportunity.relative_percentage(@in_value_proposition, @opportunities.count) 
    @ma_perc = Opportunity.relative_percentage(@in_management_analysis, @opportunities.count) 
    @pp_perc = Opportunity.relative_percentage(@in_proposal, @opportunities.count) 
    @rw_perc = Opportunity.relative_percentage(@in_review, @opportunities.count) 
    @conversion_rate = '%.2f' % [Opportunity.conversion_rate] 
    @potential_revenue = Opportunity.potential_revenue 
    end 
end 

期待どおりに動作するにもかかわらず、それはコントローラのように見えますちょっと太っていると私は、現在のアプローチでは、アプリケーションの規模が非常に遅くなる場合は、実行されているクエリの量のために遅くなると感じています。それで、データ検索とKPIの表示を最適化するためにこれをリファクタリングする方法はありますか?事前

答えて

1

ありがとうございますFacade Pattern in Railsを実装してみてください。それはあなたのコントローラをスキニーにしますが、クエリ部分ではそれらのクエリを作成する必要がありますが、スキップする方法はありません。

あなたは

これは、まさに私が探していたものである
+0

はありがとうございました、それは時期尚早な最適化のようになります。この時点で、インデックスを追加すると、パフォーマンスの遅れを取得するときに、将来のSQLビューを作成することにより、DBを最適化しようとすることができますクイックレスポンスと非常に有益なリソースは、私が家に帰るとすぐに私はそれを実装します、私が話していたことは間違いありません。私はクエリの量を避けることは不可能だとは思っていましたが、この新しいアプローチでは、テストのためにもっときれいに見えるでしょう。 –

+0

助けてくれて嬉しいです:) –

関連する問題