一直想实现表格的排序,网上查到wice_grid是个很不错的gem,看了例子也觉得超炫酷。所以bundle install来尝试一下。但不知道为何总有一些莫明其妙的问题使用不上。所以想自己尝试写一下。
刚开始准备用AJAX来实现,正好显摆一下自己前两天刚刚学会的技巧,但苦于基础太差。尝试失败。
又想排序即使用同步实现的话,从用户的角度上来说,应该可以接受。所以就尝试用同步的方式来做。
代码写的很乱,性能也没有验证,但万幸功能实现了。具体如下:
- routes中增加一个路由:
match "/products/sort_by/:sort_id", to: "products#sort_by", via: "get"
- 在products/index.html.erb中修改一下代码,使得表头变成链接:
<table class="table table-striped">
<thead>
<tr>
<th><%= link_to "ID", "/products/sort_by/#{@order[:p_id]}" %></th>
<th><%= "Name" %></th>
<th><%= link_to "Price", "/products/sort_by/#{@order[:p_price]}" %></th>
<th><%= link_to "Description", "/products/sort_by/#{@order[:p_description]}" %></th>
<th><%=t '.actions', :default => t("helpers.actions") %></th>
</tr>
</thead>
需要注意的是, @order[:p_id]中的”:p_id",定义在controller的order_init
方法中。
- 对应的productscontroller中增加下面的代码:
def index
@products = Product.all.paginate(page: params[:page], per_page: 12)
#初始化排序相关的数据
@order = order_init
end
def sort_by
@order = order_init
#判断传过来的参数是否是正确的值,如果是,进行排序,如果不是,跳转到root_path
#@order[:p_by]是一个数组,包含所有字段正序和倒序的情况
if @order[:p_by].include?(params[:sort_id])
@products = Product.all.order("%s %s" % params[:sort_id].split("_")[1..2])
#在前面已经把所有列的排序情况初始化了,下面是当某一列进行排序后,下一次点击则变为反序
order_change(@order, params[:sort_id])
@products = @products.paginate(page: params[:page], per_page: 12)
respond_to do |format|
#一定要用render,这样@products才是排序后的数据
format.html {render 'index'}
end
else
redirect_to root_path
end
end
private
#初始化@order,如果要增加可排序的列,只需要在这个方法增加order[:column] = "column_desc"即可
def order_init
order = {}
order_by = ["desc", "asc"]
order[:p_price] = "p_price_desc"
order[:p_id] = "p_id_desc"
order[:p_description] = "p_description_desc"
order[:p_by] = []
order.keys.each do |key|
order_by.each { |ele| order[:p_by] << "#{key.to_s}_#{ele}" }
end
return order
end
#当某一列进行排序后,下一次点击则变为反序
def order_change(order, string)
temp = string.split("_")
key = temp[0] + "_" + temp[1]
value = temp[2]
value = value == "desc" ? "#{key}_asc" : "#{key}_desc"
order[key.to_sym] = value
end
这样就OK了