Search code examples
ruby-on-railsrubyruby-on-rails-2

Issue ordering array in the view


I'm trying to order a column inside array but is not ordering is showing values without ordering by lastname ASC.

Here is my table:

|products|
  |id| |money| |client_id|
   1     1000      1
   2     2000      4
   3     2000      7
   4     2000      5
   5     2000      6
   6     2000      3
   7     2000      2

|customers|
  |id| |name|    |lastname1|    |lastname2|
   1    Lionel     Messi        Bueno
   2    Cristiano  Ronaldo      Tiger
   3    Cecs       Fabregas     Midtlon
   4    Andres     Iniesta      Blanco
   5    Neymar     Dos Santos   Junior

Here is my controller

class ProductController < ApplicationController
  def index
    @products= Product.all
  end
end  

Here is the model

class Client < ActiveRecord::Base
  has_many :products

  def str_name
     return lastname1.to_s+" "+lastname2.to_s+" "+name.to_s
  end
end

class Product < ActiveRecord::Base
   belongs_to :client
end

Here is my view

<table>
  <tr>
    <td>Money</td>
    <td>Client</td>     
  </tr>

  <% @products.each do |p| %>
  <tr> 
    <td><%= p.money %></td>
    <td><%= p.str_name %></td>
  <% end %>
  </tr> 
</table>

I tried but is not ordering by lastname1 asc:

  <% @products.each do |p| %>
  <tr> 
    <td><%= p.money %></td>
    <td><% @a= p.client(:order=>"lastname1 ASC")%> <%= @a.str_name %></td>
  <% end %>

The log is:

 SELECT * FROM `clients` WHERE (`clients`.`id` = 1)
 SELECT * FROM `clients` WHERE (`clients`.`id` = 2)
 SELECT * FROM `clients` WHERE (`clients`.`id` = 3)
 SELECT * FROM `clients` WHERE (`clients`.`id` = 4)

And should be like this:

 SELECT * FROM `clients` order by last_name1 ASC

Please somebody can help me?


Solution

  • <% @a= p.client(:order=>"lastname1 ASC")%> <%= @a.str_name %></td>
    

    The line above does technically nothing. When you are already in the loop and you ask for the client of the current product, how many is it going to return? Only one, right ? Right, if you have a belongs_to on the other side (which I hope you do, this answer relies on it). So you're actually "sorting" a set of one element every iteration. And that's why your Select is ignoring the "order by". What you should be doing though, is to get a list of all the products ordered by their respective clients' "lastname1". This should not be done in a view like you're trying to do, but in your controller. In your controller:

    #In Rails 4
    @products = Product.joins(:client).order('clients.lastname1 ASC')
    
    #Other version (be careful where to use plurals and where not to)
    @products = Product.find(:all, :joins => :client, :order => 'clients.lastname1 ASC')
    

    And in your view:

    <% @products.each do |p| %>
      <tr> 
        <td><%= p.money %></td>
        <td><%= p.client.str_name %></td>
      </tr>
    <% end %>