Elixir/Phoenix模板中限制好友展示数并统计剩余好友
问题
我在模板中有如下代码:
<%= for user <- @users do %> <%= user.name %> <%= for friend <- user.friends do %> <%= friend.name %> <% end %> <% end %>
这段代码会遍历所有用户,展示用户名及其全部好友关系。我希望将好友展示限制为3个,并统计剩余好友数量,实现如下效果:
用户一:
- 好友一
- 好友二
- 好友三
- 14 更多
用户二:
- 好友一
- 好友二
- 好友三
- 0 更多
请问该如何实现?我曾考虑在preload中限制数量,但这会影响主查询。
解决方案
不需要修改查询逻辑,直接在模板层处理就能实现需求,同时保留好友列表的完整数据:
<%= for user <- @users do %> <%= user.name %> <ul> <% # 提取前3个好友展示 %> <%= for friend <- Enum.take(user.friends, 3) do %> <li><%= friend.name %></li> <% end %> <% # 计算剩余好友数,避免负数 %> <% remaining_count = max(length(user.friends) - 3, 0) %> <li><%= remaining_count %> 更多</li> </ul> <% end %>
核心逻辑说明
Enum.take(user.friends, 3):从已加载的好友列表中直接取前3条,不会改动原始查询的结果max(length(user.friends) - 3, 0):计算剩余好友数,用max确保当好友总数不足3时显示0,避免出现负数
如果担心全量加载好友带来的性能问题,可以在查询阶段额外统计好友总数,同时按需加载部分好友(以Ecto为例):
后端查询代码
from u in User, # 可选:如果不需要全量好友,可预加载前3个 preload: [friends: ^from(f in Friend, limit: 3)], # 统计每个用户的总好友数 left_join: f in assoc(u, :friends), group_by: u.id, select_merge: %{total_friends: count(f.id)}
对应模板代码
<%= for user <- @users do %> <%= user.name %> <ul> <%= for friend <- user.friends do %> <li><%= friend.name %></li> <% end %> <% remaining_count = max(user.total_friends - 3, 0) %> <li><%= remaining_count %> 更多</li> </ul> <% end %>
这种方式既避免了全量加载好友的性能损耗,也不会影响主查询的其他业务逻辑。
内容的提问来源于stack exchange,提问作者user2831849
相关产品推荐
相关产品推荐

