Ruby / Active Record: Custom Sort Order

I am working on rails 3.2 ruby ​​1.9.2 project.

I am getting some values ​​from a database with the classic:

designators = Model.find()

      

And I am showing this given (simplified code):

<table class="rwy_modes_table" cellspacing='0'>
  <% designators.each do |info_design| %>
    <tr id="rwy_mode_<%=info_design.id%>">
      <td class="spacer"><%= info_design.try(:designator) %></td>
    </tr>
  <% end %>
</table>

      

Values, for example: 3L, 3C, 3R. (L for left, C for center, 4 for right). I would like the ordered values: 3L, 3C, 3R and not 3C, 3L, 3R

I do not know how to define this order. Any idea?

+3


source to share


2 answers


Try something like this:

(app/models/designator.rb)
# determines the sort value for based on my_attribute.
# designators should be in the order 'l', 'c', 'r' - regardless of any preceeding numeral
def sort_val
  return 0 if self.my_attribute =~ /l/i
  return 1 if self.my_attribute =~ /c/i
  return 2 if self.my_attribute =~ /r/i
end

(app/helpers/designators_helper.rb)
def sorted_designators(designators)
  designators.sort{|a, b| a.sort_val <=> b.sort_val }
end

      

Where can you sort in your view

(app/views/...)
sorted_designators(designators).each do |design|

      

Alternatively you can move this to a static method in your model file to make sorting easier outside of your view



(app/models/designator.rb)
def self.sorted_designators(designators)
  designators.sort{|a, b| a.sort_val <=> b.sort_val }
end

      

and use them in your controller like this

app/controllers...
@designators = Designator.sorted_designators(designators)

      

Note: this is an in-memory sort, so watch out for O (n) db queries depending on how you sort / access this object

See also: fooobar.com/questions/31979 / ... for using the Comparable module (maybe a cleaner solution)

+4


source


You could do something like this. This is not a complete answer, but this approach might help.

arr = ["3R", "3C", "2C", "4C", "2L", "2R", "3L", "4R", "4L"] # Array to be sorted

tmp_arr = ['L', 'C', 'R']

arr.sort_by {|s| [s[0], tmp_arr.index(s[1])] }
# => ["2L", "2C", "2R", "3L", "3C", "3R", "4L", "4C", "4R"]

      



This assumes what "2R"

precedes "3L"

. If you want to ignore numbers while sorting, you can remove s[0]

from the code block

+3


source







All Articles