Rails 4、如何使用自定义方法进行排序

Rails 4, how to ordering using custom method

我想使用自定义方法订购 Conversation 型号。

我找到了一些解决方案:

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

http://awaxman11.github.io/blog/2013/10/11/sorting-a-rails-resource-based-on-a-calculated-value/ ,

Conversation订单优先。

首先- answer_percent desc, 二阶至last_answer次 (使用自定义模型方法 last_answered_to_i )。

last_answered_to_i 方法来源:

def last_answered_to_i
  if Conversation.where(company_id: self.id, is_answered: true).present?
    last_conversation = Conversation.where(company_id: self.id, is_answered: true).first
    if last_conversation.answered_at.blank? || last_conversation.asked_at.blank?
      minutes =  (Time.now- last_conversation.updated_at)/1.minutes
    else
      minutes =  (last_conversation.answered_at - last_conversation.asked_at)/1.minutes
    end
    minutes.to_i
  else
    nil
  end
end

订购后我想使用 kaminari 添加分页 gem。

@lists = Company.searchable.order("answer_percent desc").page(params[:page]).per(20)

如何按列和自定义方法排序并添加分页?

我认为答案取决于您想在视图中看到什么,因为有些问题实际上可以通过您在那里调用@lists 的方式来解决。此外,您发现的一些链接使按模型方法排序听起来比实际更困难。

对于您的情况,您可以通过自定义方法对对话进行排序,如下所示: Conversation.all.sort_by(&:custom_method)

或者具体来说: Conversation.all.sort_by(&:last_answered_to_i)

具体来说,您不能使用 SQL 来根据实际数据库中不存在的内容进行排序或排序,因此您使用 Ruby sort_by 方法。有关符号的详细信息,请参阅 this post

对于您的实际视图,我不确定您希望如何组织它。我最近做了一些事情,我需要通过另一个名为 "categories" 的资源对我的资源进行分组,然后通过 "netvotes" 对原始资源进行排序,这是一种自定义模型方法,然后按名称排序。我是通过以下方式完成的:

  • 在控制器中按名称排序:@resources = Resource.order(:name)
  • 在视图的外循环中按类别分组:<% @resources.group_by(&:category).each do |category, resources| %>
  • 然后在部分资源中按投票对资源进行排序:<%= render resources.sort_by(&:netvotes).reverse %>

视图有点混乱,所以这里是 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 %>

这里是 _resource.html.erb 部分:

<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>

我希望这能帮助您想出更多的方法来解决您的问题。