2017-01-30 5 views
1

Ich habe einen Bootstrap Tabs, mit 3 Tabs: verifizierte Kommentare, ungeprüfte Kommentare und alle Kommentare. Jeder Tab-Inhalt zeigt abhängig vom RoR-Attribut unterschiedliche Kommentare an: verifiziert (true oder false). Aber ich habe ein Optimierungsproblem, weil ich @ratings (Kommentare) 3 mal nenne, und filtere die Kommentare so: @ratings.where(:verified => true), und in der Produktion ist die Anwendung wirklich langsam.Ruby on rails: Filterdaten nach Attributen, ohne Anrufinstanzvariable viele Male

Jemand weiß, wie könnte ich verifiziert, unbestätigt und alle mit einer anderen Methode filtern?

hier ist der Code:

show.html.erb

<% if @school.ratings.count > 0 %> 
     <ul class="nav nav-tabs" role="tablist" style="margin-bottom: 30px;"> 
      <li role="presentation" class="<%= 'active' if @school.is_subscribed? %>"> 
       <a href="#verifie" aria-controls="verifie" role="tab" data-toggle="tab"> 
        <h3> 
         Avis vérifiés (<%= @ratings.where(:verified => true).count %>) 
        </h3> 
       </a> 
      </li> 
      <li role="presentation"> 
       <a href="#non_verifie" aria-controls="non_verifie" role="tab" data-toggle="tab"> 
        <h3> 
         Avis non-vérifiés (<%= @ratings.where(:verified => false).count %>) 
        </h3> 
       </a> 
      </li> 

      <li role="presentation" class="<%= 'active' unless @school.is_subscribed? %>"> 
        <a href="#all_avis" aria-controls="all_avis" role="tab" data-toggle="tab"> 
         <h3> 
          Tous les avis (<%= @ratings.count %>) 
         </h3> 
        </a> 
       </li> 
      </ul> 
      <div class="tab-content"> 
       <div role="tabpanel" class="tab-pane <%= 'active' if @school.is_subscribed? %>" id="verifie"> 
        <%= render partial: "schools/rating", collection: @ratings.where(:verified => true) %> 
       </div> 
       <div role="tabpanel" class="tab-pane" id="non_verifie"> 
        <%= render partial: "schools/rating", collection: @ratings.where(:verified => false) %> 
       </div> 
       <div role="tabpanel" class="tab-pane <%= 'active' unless @school.is_subscribed? %>" id="all_avis"> 
        <%= render partial: "schools/rating", collection: @ratings %> 
       </div> 
      </div> 
      <a href="#post-rating" id="post-rating-bottom-btn" class="btn btn-warning post-rating-btn"><%= fa_icon 'star' %> 
       Laisser un avis</a> 
     <% else %> 
      <p>Pas encore d'avis sur cette auto-école. Soyez le premier 
       <a id="post-rating-be-first" href="#post-rating" class="btn btn-warning post-rating-btn"><%= fa_icon 'star' %> 
        Donnez votre avis</a> 
      </p> 
     <% end %> 

schools_controller.erb

@school = School.where(city_namespace: params[:city], title_namespace: params[:title]).first || raise(ActionController::RoutingError.new('Not Found')) 
    @rating = Rating.new(params[:rating]) 
    @rating.school_id = @school.id 
    @ratings = @school.ratings.desc(:created_at) 

Zögern Sie nicht, wenn Sie mehr Code benötigen/Infos !

Danke!

Antwort

1

Ich bin persönlich nicht sicher, ob Sie Ihre Server-Ressourcen für mehrere Aufrufe der Instanzvariablen ausgeben. Ich glaube, dass Ihre App langsam ist, weil Sie die große Menge von ActiveRecord-Objekten auswählen (die selbst langsam sind). Also meine Tipps sind:

In Ihrem Controller Sie einfach drei Instanzvariablen initialisieren können:

@ratings = @school.ratings.desc(:created_at) 
@verified_ratings = @ratings.where(:verified => true) 
@unverified_ratings = @ratings.where(:verified => false) 

Dann rufen sie einfach aus Ihrer Sicht. Es geht nicht um Optimierung, aber trotzdem.

Tipp 0 Wenn Sie ein paar Rating-Datensätze auswählen müssen, verwenden Sie zupfen. Mit pluck werden Sie nicht das ActiveRecord-Objekt, sondern die Arrays von Arrays instanziieren. Übergeben Sie die Symbole der Spalten, die Sie benötigen. Zum Beispiel: Rating.where (: verifiziert => false) .pluck (: Spalte_1,: column_2)

Tipp 1. Um Ihre Serverressourcen sparen Sie Paginierung verwenden können durch Abschnitte von Daten von DB auszuwählen. Verwenden Sie Kaminari oder will_paginate Edelsteine.

Tipp 2. Wenn Sie auf Postgresql sind verwenden postgresql_cursor Juwel so etwas wie ausführen:

Rating.desc(:created_at).each_instance(block_size: SIZE_YOU_NEED).lazy.map { do_something } 

Es Ihre Daten in den Reihen geladen werden. Die Größe der Chargen kann geändert werden (übergeben Sie den Wert an block_size). Sie können die Daten in diesen Stapeln sortieren (ohne postgresql_cursor Gem können Sie das nicht tun). Man könnte sagen, es ist ein alternativer Ansatz für die Paginierung.

+0

Der Aufruf im Controller spart zwar keine Zeit in DB-Aufrufen, aber es ist sauberer Code. – Iceman

+0

Wahr. Mein wichtigster Punkt ist die Verwendung der Paginierung – VAD

+0

@VAD danke für die Hilfe, aber mein Chef verweigern eine Seitenumbruch, er möchte alle Kommentare auf der gleichen Seite für jeden Tabs .. –