Ruby/Active Record: Custom Sorting Order

Ruby / Active Record: custom sorting order

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 you can do sorting in your view

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

Alternately, you can move this to a static method in your model file, for easy sorting outside 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 for O(n) db queries depending on how you sort / access this object

See also: https://stackoverflow.com/a/14282353/811255 for using the Comparable module (probably a cleaner solution)

Ruby on Rails / Active Record: Custom Sorting Order

Foo.order "id = #{param[:param].to_i} desc", :name

I used the .to_i just as a very simple way to ensure this parameter is clean, make sure you do that however you need to so that you're not leaving yourself open to SQL injection.

Rails ActiveRecord 4.2 custom sort order

You can use a sql case statement to control the ordering.

has_many :events, ->{ "ORDER BY CASE WHEN event_type = 'morning' THEN '1' WHEN event_type = 'afternoon' THEN '2' WHEN event_type = 'evening' THEN '3' END" }  

Order an Active Record Relation with a custom method

You need order not sort_by. Sort by sort on the enumerable object and it is not aware of associations. Read more here: https://apidock.com/ruby/Enumerable/sort_by

So you will probably end up with something like Profile.joins(:countries).where(id: [1,2,3], countries: {country_code: "US"}).order("countries.country_code asc")

This will bring you any profiles where the id is 1 or 2 or 3 and they HAVE an associated country with country. Profiles that do not have an associated country will not be included.

custom ordering activerecord data in rails

Try:

Course.all.order("average_rating DESC, created_at ASC")

Rails: Custom ordering of records

Switch to a integer like Aaron said, then you will probably want to use a default_scope.

For example:

class Task < ActiveRecord::Base
default_scope :order => 'tasks.position' # assuming the column name is position
...

With a default scope you won't have to specify the sort order in any of your find method calls - the tasks will automatically be sorted.

How do you order by a custom model method that has no attribute in SQL?

It fails because you are asking your db to do the sorting.

@posts = Post.all.sort {|a,b| a.custom_method <=> b.custom_method}

Note that this becomes non-trivial when you want to start paging results and no longer wish to fetch .all. Think about your design a bit before you go with this.

Rails ActiveRecord how to do custom sorting on a has_many relationship

You should consider storing integers in the database instead of the day names. It would make things easier to sort, and probably a bit more performant.

Then, you can override the day getter (to return the day name from the integer) and setter (to store the integer corresponding to the day name). You might not have to override the setter depending on what you get from your form.

Don't forget to have a custom validation, to check if the integer is between 1 and 7.

Rails 4, how to ordering using custom method

I think the answer depends on what you want to see in the view because some of the problem could actually be solved in how you call @lists there. Also, some of the links you found make sorting by a model method sound more difficult than it is.

In your case, you can sort your conversations by a custom method like so:
Conversation.all.sort_by(&:custom_method)

Or specifically:
Conversation.all.sort_by(&:last_answered_to_i)

Specifically, you cannot use SQL to sort or order by something not in the actual database, so you use the Ruby sort_by method. For more info on the ampersand, see this post.

For your actual view, I'm not sure really how you want to organize it. I recently did something where I needed to group my resource by another resource called "categories", and then sort the original resource by "netvotes" which was a custom model method, then order by name. I did it by:

  • Ordering by name in the controller: @resources = Resource.order(:name)
  • Grouping by category in the outer loop of the view: <% @resources.group_by(&:category).each do |category, resources| %>
  • Then sorting the resources by votes in the partial for resources: <%= render resources.sort_by(&:netvotes).reverse %>

The view is a bit confusing, so here is the full view loop in index.html.erb:

<% @resources.group_by(&:category).each do |category, resources| %>
<div class="well">
<h3 class="brand-text"><%= category.name %></h3>
<%= render resources.sort_by(&:netvotes).reverse %>
</div>
<% end %>

And here is the _resource.html.erb partial:

<div class="row resource">
<div class="col-sm-2 text-center">
<div class="vote-box">
<%= link_to fa_icon('chevron-up lg'), upvote_resource_path(resource), method: :put %><br>
<%= resource.netvotes %><br>
<%= link_to fa_icon('chevron-down lg'), downvote_resource_path(resource), method: :put %>
</div>
</div>
<div class="col-sm-10">
<%= link_to resource.name, resource.link, target: "_blank" %>
<p><%= resource.notes %></p>
</div>
</div>

I hope that helps you think through some more ways to address your problem.



Related Topics



Leave a reply



Submit