Ruby on rails - 如何按 DESC 进行 .limit 排序,然后按 (:id) 排序



这会将标签限制为标签计数最高的前 20 个:

标签.rb

scope :top_20, -> {
  where("taggings_count != 0").order("taggings_count DESC").limit(3)
}

然后我想根据他们的:id而不是根据他们的tagging_count来订购这 20

application_controller

before_action :tag_cloud
def tag_cloud
  @tags = Tag.all.top_20.order(:id)
end

不幸的是,.order(:id)不起作用。它们仍然按计数降序显示。

_tags.html.erb

<% tag_cloud(@tags, %w(css1 css2 css3 css4)) do |tag, css_class| %>
  <%= link_to tag.name, tag_path(tag), :class => css_class %>
<% end %>

如果您需要进一步的代码或解释来帮助您帮助我,请告诉我:-]

如果你想用纯SQL而不是Ruby sort来做到这一点,你必须使用一个子查询来做到这一点:

Tag.from(Tag.top_20, :tags).order(:id)

http://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-from

查询将仅考虑第一个order。您可以通过重新排序来覆盖它,但这在您的情况下不起作用,因为它将覆盖order("taggings_count DESC")

对你有用的是排序:

@tags = Tag.all.top_20.sort{ |x,y| x.id <=> y.id }

我宁愿像这样重写这个范围:

from(
  where.not(taggings_count: 0)
     .order(taggings_count: :desc)
     .limit(20)
        .as(table_name)
)

这样做是修改 FROM -子句,使其不是从表中获取结果'tags'而是从别名为具有相同名称(table_name返回该名称)的临时结果集(在子查询中获取)中获取结果,以欺骗 ActiveRecord 认为我们正在查询相同的源。您可以在顶部应用任何操作,就好像它是整个表一样。

至于as方法,似乎没有在任何地方提到......它来自Arel,ActiveRecord中使用的SQL AST管理器。实际上,它被委托给查询的Arel::SelectManager,可在任何ActiveRecord::Relation arel方法上使用。

不太清楚您的问题,您想将记录订购为 desc 还是 asc 订单?

编写作用域,如下所示

scope :order_id_asc, -> { order('id ASC') }
scope :order_id_desc, -> { order('id DESC') }

并按如下方式重写代码,调用任何一个作用域

def tag_cloud
    @tags = Tag.top_20.order_id_asc
end

最新更新