如何在多表继承(MTI)中使用ranked-model gem?
在多表继承(MTI)中使用ranked-model实现跨表共享排序
1. 基础准备
先在Gemfile中添加ranked-model依赖:
gem 'ranked-model'
执行bundle install完成安装。
2. 调整模型代码
由于Mitarbeiter和MitarbeiterTrenner分属不同数据表,但需要在同一team维度下共享排序规则,我们需要在两个子类中配置ranked-model,并自定义跨表的排序上下文:
class MitarbeiterListeEintrag < ActiveRecord::Base # 父类定义通用方法,获取同一team下的跨表记录集合 def self.ranked_team_records(team_id) # 联合查询两个表的排序字段与标识,用于排序计算 mitarbeiter_records = Mitarbeiter.where(team_id: team_id).select(:sort_order, :id, "'mitarbeiter' as table") trenners_records = MitarbeiterTrenner.where(team_id: team_id).select(:sort_order, :id, "'mitarbeiter_trenner' as table") mitarbeiter_records.union(trenners_records).order(:sort_order) end end class Mitarbeiter < MitarbeiterListeEintrag set_table_name "mitarbeiter" include RankedModel # 指定排序字段为已有的sort_order,按team分组排序 ranks :sort_order, with_same: :team_id # 重写ranked-model的排序范围,纳入跨表记录 def ranked_scope self.class.ranked_team_records(team_id) end end class MitarbeiterTrenner < MitarbeiterListeEintrag set_table_name "mitarbeiter_trenner" include RankedModel ranks :sort_order, with_same: :team_id def ranked_scope self.class.ranked_team_records(team_id) end end
3. 混合列表查询与展示
要获取同一team下的混合排序列表,直接合并两个表的记录并按sort_order排序即可:
def get_team_mixed_list(team) mitarbeiter = Mitarbeiter.where(team: team) trenners = MitarbeiterTrenner.where(team: team) (mitarbeiter + trenners).sort_by(&:sort_order) end
4. 关键注意点
- 重写
ranked_scope后,调用ranked-model的move_higher、move_lower等方法时,会自动考虑跨表记录的位置,保证排序一致性。 - 确保两个表的
sort_order字段均为非空整数类型,匹配ranked-model的要求。 - 批量调整排序时,可直接操作
sort_order字段,或结合联合查询使用ranked-model的批量更新方法。
内容的提问来源于stack exchange,提问作者Raswidr
相关产品推荐
相关产品推荐

