很容易,在此railscast http://railscasts.com/episodes/240-search-sort-paginate-with-ajax之后,能够创建一个基于我的数据库中存在的列进行排序的表。但我在我的表中显示的其他列不是数据库列,我仍然需要按这些列排序。
例如,我有多个列来组成捐赠者名称(prefix1,first_name1,middle_name1,last_name1,suffix1,prefix2,first_name2,middle_name2,last_name2,suffix2,company)。我在我的模型中定义了“who_donated”,它是使用我给出的一些规则的实际表列的组合。所以基本上我显示的捐赠者表格中有一个who_donated字段,我希望能够对该字段进行排序。
如果该列不是数据库表中的实际列,我如何对视图表的列进行排序?
答案 0 :(得分:1)
因为我有很多不同的方法来收集信息以放入我需要排序的列中,因为可能有很多行可以排序,我决定将尽可能多的工作放在mysql服务器上尽可能为每个案例进行排序。
这就是我解决它的方法......我几乎跟着railscast 228和240进行初始设置:http://asciicasts.com/episodes/228-sortable-table-columns和http://asciicasts.com/episodes/240-search-sort-paginate-with-ajax
然后我做了一些修改如下。
donors_controller:
def last_sort_column
params[:sort].blank? ? 'created_at' : params[:sort]
end
def sort_column
case
when Donor.column_names.include?(params[:sort]) then params[:sort]
when params[:sort] == 'Donors' then
'concat(prefix1,first_name1,middle_name1,last_name1,suffix1,
prefix2,first_name2,middle_name2,last_name2,suffix2,company)'
when params[:sort] == 'First Donated' then
'(select min(donations.created_at) from donations where donations.donor_id = donors.id)'
when params[:sort] == 'Last Donated' then
'(select max(donations.created_at) from donations where donations.donor_id = donors.id)'
when params[:sort] == 'Times Donated' then
'(select count(*) from donations where donations.donor_id = donors.id)'
when params[:sort] == 'Total Amount' then
'(select sum(amount) from donations where donations.donor_id = donors.id)'
else 'created_at'
end
end
def sort_direction
%w[asc desc].include?(params[:direction]) ? params[:direction] : "asc"
end
和application_helper:
def sortable(column, title = nil)
title ||= column.titleize
css_class = (column == last_sort_column) ? "current #{sort_direction}" : nil
direction = (column == last_sort_column && sort_direction == "asc") ? "desc" : "asc"
link_to title, params.merge(:sort => column, :direction => direction, :page => nil), {:class => css_class}
end
添加last_sort_column是因为发送到order by语句的sort_column
与列名不匹配,所以它永远不会记住你已经分类为asc或desc的内容。
这允许我把我想要的sql语句疯狂地放入排序中,但仍然完全阻止了sql注入的任何可能性,因为url只会显示列的实际名称。如果输入了我允许的有效选项以外的其他内容,则默认为created_at并抛弃虚假值。
我真的很惊讶这是如何快速排序超过100k行链接到另外200k行。
答案 1 :(得分:0)
最简单的情况:
<% sorted_donors = @unsorted_donors.sort_by{ |donor| donor.who_donated } %>
在此处阅读有关sort_by的更多信息:http://www.ruby-doc.org/core-1.9.2/Enumerable.html#method-i-sort_by
就像我说的,直接将这些代码放入视图中是获得所需排序的最丑陋,最简单的方法。如果你正在进行分页,你需要在分页之前在控制器中进行排序等等......但是这段代码至少应该让你朝着正确的方向前进。