Rails中Smart Listing自定义排序:如何按姓氏对姓名进行排序?
按姓氏实现Smart Listing排序的解决方案
嘿,这个需求很常见,咱们分两种场景来解决:
场景1:数据库已拆分存储名字和姓氏
如果你的数据库表已经有独立的first_name(名字)和last_name(姓氏)字段,那事情就简单多了——直接把排序目标字段换成last_name就行:
%th= smart_listing.sortable(t('.name'), 'last_name')
这样点击「姓名」表头时,就会自动按姓氏字段进行升序/降序排序,表头显示的还是原来的“姓名”文本,完全不影响用户体验。
场景2:数据库仅存储合并的姓名字段
如果你的数据库里还是存的类似"Carlos Gonzales"这种合并的姓名字符串,那需要在模型层做一些处理,让Smart Listing能识别姓氏排序:
步骤1:在模型中添加排序Scope
根据你使用的数据库类型,编写对应的字符串拆分排序逻辑:
- PostgreSQL:用
SPLIT_PART函数拆分姓氏
# app/models/user.rb class User < ApplicationRecord scope :sort_by_last_name, ->(direction) { order("SPLIT_PART(name, ' ', 2) #{direction.upcase}") } end
- MySQL:用
SUBSTRING_INDEX函数获取姓氏
scope :sort_by_last_name, ->(direction) { order("SUBSTRING_INDEX(name, ' ', -1) #{direction.upcase}") }
- SQLite:结合
SUBSTR和INSTR实现拆分
scope :sort_by_last_name, ->(direction) { order("SUBSTR(name, INSTR(name, ' ') + 1) #{direction.upcase}") }
步骤2:配置Smart Listing的自定义排序属性
在控制器中,把自定义的排序逻辑绑定到Smart Listing:
# app/controllers/users_controller.rb def index smart_listing_create :users, User.all, partial: 'users/list', sort_attributes: [ { last_name: ->(direction) { User.sort_by_last_name(direction) } } ] end
步骤3:更新视图中的排序表头
最后把视图里的排序字段换成我们定义的:last_name:
%th= smart_listing.sortable(t('.name'), :last_name)
这样设置后,点击「姓名」表头就会自动按姓氏进行排序啦!
内容的提问来源于stack exchange,提问作者Carlos Felipe Gonzalez
相关产品推荐
相关产品推荐

