简体   繁体   English

Rails自定义记录顺序?

[英]Rails custom order of records?

My Rails site has different categories that the user can browse through. My Rails网站具有用户可以浏览的不同类别。 Right now they're rendered in the view through a simple loop, but I'd like to be able to choose the order from left to right in which they're displayed. 现在,它们通过一个简单的循环在视图中呈现,但是我希望能够从左到右选择显示它们的顺序。

Here's the current code: 这是当前代码:

<h4>Explore Listings</h4>
  <% @categories.each do |f| %>
    <p class="category-page-category"><%= link_to f.name, view_category_path(f.id) %></p>
  <% end %>

What would be an easy solution to accomplish what I want to do? 什么是完成我想做的简单解决方案?

First of all native sorting by the DB is to be preferred in every case (it's much faster). 首先,在每种情况下都应首选数据库进行本机排序(这要快得多)。 If your sorting does not depend on already existing Category attributes, migrate a new attribute like position: 如果您的排序不依赖于已经存在的Category属性,请迁移一个新的属性,例如position:

add_column :categories, :position, :integer

and add a scope to the model: 并向模型添加范围:

class Category < ActiveRecord::Base
  def self.ordered default_order=nil
    return scoped if default_order.nil? or 
      not( %w(asc desc).include?(default_order.to_s) )
    order("position #{default_order}")
  end
end

and then in the controller: 然后在控制器中:

def index
  @categories = Category.ordered params[:order]
end

following the sorting attribute approach you also should ensure your position attribute is valid defined. 按照排序属性方法,您还应该确保有效定义了位置属性。 So like: 像这样:

class Category < ActiveRecord::Base
  before_create :default_position
  validates :position, 
    presence: true,
    numericality: true,
    uniqueness: true,
    on: :update

  def self.ordered default_order=nil
    return scoped if default_order.nil? or 
      not( %w(asc desc).include?(default_order.to_s) )
    order("position #{default_order}")
  end

  private
  def default_position
    self.position = self.class.maximum("position") + 1
  end
end

Changing positions has to be implemented. 必须执行更改职位。
Otherwise if positions never change, this means Categories have to be sorted by their creation datetime. 否则,如果职位从未改变,则意味着必须按类别的创建日期时间对类别进行排序。 Then you also could sort by created_at instead of position. 然后,您也可以按created_at而不是排名进行排序。

The easiest way I know of how to do this is to set up an AJAX form which will pass an order parameter which will be handled by the controller to re-render the form. 我知道如何执行此操作的最简单方法是设置一个AJAX表单,该表单将传递一个order参数,该参数将由控制器处理以重新呈现该表单。 Your controller would then listen for the order parameter and append that to @categories . 然后,您的控制器将侦听order参数并将其附加到@categories

For example, your controller code might look something like: 例如,您的控制器代码可能看起来这样

def index
  @categories = Category.<some_other_scope>

  @categories = @categories.order(order_param) if order_param.present?

  respond_to do |format
    format.js { render :index }
  end
end

private

def order_param
  params.permit(:order)
end

It sounds like you want to sort the array of categories before they are shown, no? 听起来您想在显示类别之前对类别数组进行排序,对吗?

If so you can use http://www.ruby-doc.org/core-2.1.2/Enumerable.html#method-i-sort_by or http://www.ruby-doc.org/core-2.1.2/Enumerable.html#method-i-sort to sort your categories however you want before rendering them. 如果是这样,您可以使用http://www.ruby-doc.org/core-2.1.2/Enumerable.html#method-i-sort_byhttp://www.ruby-doc.org/core-2.1.2 /Enumerable.html#method-i-sort在呈现类别之前对类别进行排序。

So this could end up looking something like: 因此,最终结果可能类似于:

 <% @categories.sort_by(&:name).each do |f| %>

assuming categories have a name field. 假设类别具有名称字段。 This should probably be done in the controller or in the model with a scope (if you are sorting based on a database field) to keep this logic out of the view. 这可能应该在控制器中或在具有范围的模型中完成(如果您要基于数据库字段进行排序),以使此逻辑不在视图范围之内。

看起来act_as_list正是您需要的

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM