Rails自定义记录顺序?

时间:2014-08-27 02:45:45

标签: ruby-on-rails

My Rails网站有不同的类别,用户可以浏览。现在,他们通过一个简单的循环在视图中呈现,但我希望能够从左到右选择他们显示的顺序。

这是当前的代码:

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

完成我想做的事情会是一个简单的解决方案吗?

4 个答案:

答案 0 :(得分:1)

首先,DB的本地排序在每种情况下都是首选(它要快得多)。 如果您的排序不依赖于现有的Category属性,请迁移一个新属性,如position:

add_column :categories, :position, :integer

并向模型添加范围:

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

然后在控制器中:

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

遵循排序属性方法,您还应确保您的位置属性定义有效。所以喜欢:

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

必须实施变更职位 否则,如果位置永远不会改变,这意味着类别必须按其创建日期时间排序。然后你也可以按created_at而不是position来排序。

答案 1 :(得分:0)

我知道如何执行此操作的最简单方法是设置一个AJAX表单,该表单将传递order参数,该参数将由控制器处理以重新呈现表单。然后,您的控制器将侦听order参数并将其附加到@categories

例如,您的控制器代码可能看起来像那样

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

答案 2 :(得分:0)

听起来你想在显示之前对类别数组进行排序,不是吗?

如果是这样,您可以使用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在渲染类别之前对其进行排序。

所以这可能最终看起来像:

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

假设类别具有名称字段。这可能应该在控制器或带有作用域的模型中完成(如果您基于数据库字段进行排序),以使该逻辑不在视图之外。

答案 3 :(得分:0)

看起来acts_as_list正是您所需要的