如何根据user_settings表配置对columns表查询结果排序并保留ActiveRecord_Relation类型
实现方案
前置准备
确保已正确配置User与UserSetting模型的关联,可正常获取当前登录用户的配置数据。
实现步骤
1. 提取用户列排序映射
# 获取当前用户的配置,可根据实际业务关联逻辑调整查询方式 current_user_setting = current_user.user_settings.take # 构建 列ID => 排序优先级 的映射哈希 col_order_map = if current_user_setting&.params.present? # 若params字段为text类型存储的JSON字符串,需先调用 JSON.parse(current_user_setting.params) 解析 current_user_setting.params.dig("columns")&.index_by { |item| item["col_id"] } || {} else {} end
2. 构造数据库级排序,保留ActiveRecord_Relation类型
@columns = Column.all.then do |relation| if col_order_map.any? # 构造CASE WHEN排序语句 order_sql = Arel.sql( col_order_map.map do |col_id, config| "WHEN id = #{col_id.to_i} THEN #{config['place'].to_i}" end.join(" ") + " ELSE 999 END ASC" ) relation.order(order_sql) else # 无用户配置时走默认排序规则,可自定义 relation.order(id: :asc) end end
说明
- 最终返回的
@columns仍然是Column::ActiveRecord_Relation类型,支持后续链式调用其他ActiveRecord方法(如分页、条件筛选等) - 未出现在用户配置中的列默认排序优先级最低,排在列表末尾,可通过修改
ELSE 999的数值调整规则 - 代码中对
col_id和place都做了整数转换,避免SQL注入风险
注意:如果你的业务场景中列数量超过50个,建议额外优化排序逻辑,避免CASE WHEN语句过长影响查询性能。
内容的提问来源于stack exchange,提问作者aaltw
相关产品推荐
相关产品推荐

