user2142645
user2142645

Reputation: 69

Optimize search RoR

i am building a RoR (rails 4) project with this search and showing in a table with bootstrap 3 style.

  1. My next code work's but is too slow. I hope this can be optimize.
  2. There is a way for show a loading in the middle of the page?

I am very new in RoR and my English is not good. I am sorry about that. Please help me! and thanks for everything!

<div class="panel panel-primary">
  <div class="panel-body">
    <table class="table table-striped table-bordered table-hover">
      <thead>
        <tr>
          <th>Grado</th>
          <% meses = ((@cargo_total_grado.fecha_inicio)..@cargo_total_grado.fecha_final).map {|d| [d.strftime('%b'), d.year]}.uniq %> 
          <% meses.each do |m| %> 
          <th> <%= m.first + " " + m.second.to_s %> </th>
          <% end %> 
          <th>Total</th>
        </tr>
      </thead>
      <tbody>      
        <% @cursos.each do |curso| %>
        <% alumnos = Alumno.select("id").where(:id => curso.alumno_ids) %>
        <tr>
          <td><small><%= curso.id_curso %></small></td>
          <% total = 0 %>
          <% meses.each do |m| %> 
          <% inicio = (m.second.to_s + m.first.to_s + "-01").to_date %>
          <% final = inicio.next_month %>
          <% mes = alumnos.map { |e| e.planes.map {|r| r.cargos.where("fecha_cargo >= ? AND fecha_cargo < ?", inicio, final).sum(:monto)}.sum }.sum %>
          <% total += mes %>
          <td><small> <%= number_to_currency(mes) %> </small></td>
          <% end %> 
          <th><small><%= number_to_currency(total) %></small></th>
        </tr>
        <% end %>
        <tr>
          <th></th>
          <% totales = 0 %>
          <% meses.each do |m| %> 
          <% inicio = (m.second.to_s + m.first.to_s + "-01").to_date %>
          <% final = inicio.next_month %>
          <% mes_total = @cursos.map { |c| c.alumnos.map { |e| e.planes.map {|r| r.cargos.where("fecha_cargo >= ? AND fecha_cargo < ?", inicio, final).sum(:monto)}.sum }.sum }.sum %>
          <% totales += mes_total %>
          <th><small> <%= number_to_currency(mes_total) %> </small></th>
          <% end %> 
          <th><small><%= number_to_currency(totales) %></small></th>
        </tr>
      </tbody>
    </table>
  </br>
</div>

Upvotes: 3

Views: 130

Answers (2)

Ali Raza
Ali Raza

Reputation: 9

for getting more Optimized results you can use elastic search for this.

Upvotes: 0

Mario
Mario

Reputation: 1359

So your issue is that you have WAY too many SQL calls. Rails needs to query the database for each of these which causes slowdown.

You should look into Eager Loading in order to fix this problem, commonly known as the N + 1 queries problem.

Active Record lets you specify in advance all the associations that are going to be loaded. This is possible by specifying the includes method of the Model.find call. With includes, Active Record ensures that all of the specified associations are loaded using the minimum possible number of queries.

For example, you seem to be loading multiple courses into your @cursos object and let from that loading multiple Alumno objects and then those load Cargo objects. This is going to result in multiple calls to the database. Instead of this in your model you could do something like:

@cursos = Curso.includes(alumnos: [:cargos]).all

For the second part of your answer, whether you could show a loading animation:
Yes you can, BUT you would have to use AJAX calls in order to load the information from other routes you'd create that return the required info. It's not too complicated but it does add a bit of complexity to the app. Take a look at this if you're interested.

P.S. Parece que hablas español? Si hay algo que no entiendes puedo explicártelo por chat, solo me avisas cuando tengas tiempo.

Upvotes: 3

Related Questions