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

前端 未结 6 1181
生来不讨喜
生来不讨喜 2021-02-02 08:11

Previously I ordered my posts as this:

@posts = Post.find(:all, :order => \"created_at DESC\")

But now I want to replace created_at

6条回答
  •  情深已故
    2021-02-02 08:43

    As the first answer noted, order is an Active Record command that essentially does a SQL query on your database, but that field doesn't actually exist in your database.

    As someone else commented, you can more cleanly run the Ruby method sort_by by using the ampersand (more info here):

    Post.all.sort_by(&:custom_method)

    However, things do get complicated depending on what you want to do in your view. I'll share a case I recently did in case that helps you think through your problem. 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| %>
      

    <%= category.name %>

    <%= render resources.sort_by(&:netvotes).reverse %>
    <% end %>

    And here is the _resource.html.erb partial:

    <%= link_to fa_icon('chevron-up lg'), upvote_resource_path(resource), method: :put %>
    <%= resource.netvotes %>
    <%= link_to fa_icon('chevron-down lg'), downvote_resource_path(resource), method: :put %>
    <%= link_to resource.name, resource.link, target: "_blank" %>

    <%= resource.notes %>

提交回复
热议问题