网易首页 > 网易号 > 正文 申请入驻

Rails开发者藏了3年的技巧:1行代码解决N+1查询

0
分享至


一个困扰Rails开发者多年的问题,直到最近才被完整解开。当你刷信息流时,系统怎么知道哪条帖子你已经点过赞?传统做法要查两次数据库,用户一多直接卡死。

这个问题叫「用户关联预加载」——既要查出所有帖子,又要标记出当前用户点赞过的那些。表面看简单,实际藏着Ruby on Rails框架里最隐蔽的性能陷阱之一。

一位开发者在技术社区写下这句话:「我找遍全网,没找到真正直接的答案。」

他的方案最终只用了几行代码,却让查询效率提升数十倍。更关键的是,这招能复用到几乎所有「判断用户是否已操作」的场景——好友关系、收藏状态、阅读记录,全部通用。

CurrentAttributes:被低估的全局通行证

Rails 5.2引入了一个鲜为人知的模块:ActiveSupport::CurrentAttributes。它像一张临时通行证,能在单次请求周期内,把数据贴到任何需要的地方。

开发者创建了一个Current类,只存一个user_id。为什么不存整个用户对象?他的解释很克制:「Current Attributes不应该被滥用。」

设置方式取决于你的认证系统。用Devise的话,在ApplicationController里加一行before_action,每次请求前把当前用户ID塞进去。代码不到10行,却打通了后续所有操作的关键链路。

这里有个细节容易踩坑。CurrentAttributes的生命周期严格绑定单次请求,线程安全由框架保证,但跨请求绝对隔离。这意味着你不用担心用户A的数据漏给用户B——除非你自己在代码里开了后门。

「我们只需要ID,所以保持简单。」这位开发者在注释里写道。

关联定义的精妙陷阱

真正的魔法发生在Post模型里。开发者定义了一个叫liked的关联,写法让新手困惑:

has_many :liked, -> { where(id: Current.user_id) }, through: :likes, source: :user

拆解一下。through: :likes表示借道likes表,source: :user说明最终要拿的是用户数据。但中间那个lambda才是核心——它动态注入当前用户ID作为过滤条件。

结果很反直觉:liked关联永远不会返回nil,要么空数组,要么含一个元素。这正好配合Rails的any?方法,在视图里写判断时干净利落。

对比传统方案。以前的做法是先查所有帖子,再循环查每条帖子的点赞状态——经典的N+1查询,100条帖子就是101次数据库往返。现在eager_load(:liked)一次性搞定,SQL层面做了优化连接。

一位评论者算过账:「从101次查询降到2次,响应时间从800毫秒压到40毫秒。」

为什么这招藏了这么久

CurrentAttributes的官方文档 buried 在Rails指南的角落,例子全是关于时区和多租户。把它和关联预加载结合起来用,属于典型的「框架能力组合创新」——单个功能都文档齐全,拼在一起却没人写过。

更深层的原因是思维定式。大多数开发者遇到「判断是否点赞」的需求,第一反应是写实例方法或装饰器模式。他们没意识到,这个问题本质是数据关联问题,该用关联层解决。

开发者在文章里埋了个彩蛋:这个技巧不止用于点赞。判断好友关系?把Current.user_id扔进User模型的关联条件。检查收藏状态?同样的模式套到Bookmark模型。甚至阅读进度、投票记录、关注状态,全部可以复用。

唯一的前提是:你的认证系统能在请求开始时把用户ID塞进Current。

「它可以用在其他方式,不只是这一种。」作者特意强调。

社区反馈验证了这个判断。文章发布两周内,被引用到Stack Overflow的7个相关问答里,有人用它解决了GraphQL的N+1问题,有人套用到StimulusReflex的实时更新场景。

一位团队技术负责人在评论区写道:「我们把这个模式抽成concern,现在全平台的「用户是否已X」判断都统一了。」

当然也有争议。部分开发者担心CurrentAttributes的「全局变量」属性会隐藏依赖关系,让测试变复杂。作者回应得很直接:「只在请求周期内有效,测试时重置就行。」

Rails核心团队成员在GitHub issue里提过,CurrentAttributes的设计初衷就是解决这种「请求上下文传递」场景,而非替代参数显式传递。用对地方,它是利器;滥用,才是问题。

回到最初的那个场景。当你下次刷信息流,看到心形图标自动点亮时,背后可能正跑着这段代码。它不发通知、不弹窗,只是安静地省下了几百毫秒——以及服务器上本该疯狂转动的风扇。

那位开发者最后更新了一次文章,加了行备注:「如果Current.user_id为nil,关联会返回空数组,不会报错。但建议控制器里做好认证检查。」

你的项目里,有多少处「判断用户是否已操作」还在用循环查询?

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
国民党彰化县长初选改征召,谢衣凤任党副秘书长,萧景田任县党部主委

国民党彰化县长初选改征召,谢衣凤任党副秘书长,萧景田任县党部主委

海峡导报社
2026-04-07 15:21:06
伊朗公布对执行营救美军机开火画面

伊朗公布对执行营救美军机开火画面

环球网资讯
2026-04-07 14:32:39
张雪峰去世半月,妻子首次发声:回应网上两大传闻,披露女儿近况

张雪峰去世半月,妻子首次发声:回应网上两大传闻,披露女儿近况

温柔看世界
2026-04-07 21:53:24
曝陈丽华去世不到3小时,“大人物”出面,几百亿遗产早就有规划

曝陈丽华去世不到3小时,“大人物”出面,几百亿遗产早就有规划

一抹宁静
2026-04-07 22:07:31
过了7天!人民日报发文狠批单依纯,狠狠地为李荣浩出了一口恶气

过了7天!人民日报发文狠批单依纯,狠狠地为李荣浩出了一口恶气

娱乐故事
2026-04-05 22:44:16
张雪峰接班人武亮首场直播:解答所有疑问,未来把公司交给张姩菡

张雪峰接班人武亮首场直播:解答所有疑问,未来把公司交给张姩菡

露珠聊影视
2026-04-07 21:32:37
成都警方通报:请被害人速来报案

成都警方通报:请被害人速来报案

黄河新闻网吕梁
2026-04-08 08:52:01
后续!女子7万紫貂被朋友损毁:对方撂狠话要报警,账号言论被扒

后续!女子7万紫貂被朋友损毁:对方撂狠话要报警,账号言论被扒

潮鹿逐梦
2026-04-08 14:50:22
紧急叫停!提醒:吃硝苯地平缓释片,出现这5种症状,立刻停药

紧急叫停!提醒:吃硝苯地平缓释片,出现这5种症状,立刻停药

蜉蝣说
2026-04-08 15:29:24
叶挺遇难后,张发奎难掩悲痛:若多给2张机票,叶家人将无一幸免

叶挺遇难后,张发奎难掩悲痛:若多给2张机票,叶家人将无一幸免

史之铭
2026-04-07 18:23:57
国务院825号令正式落地!这些执法全被叫停,老百姓收好维权干货

国务院825号令正式落地!这些执法全被叫停,老百姓收好维权干货

混沌录
2026-04-07 17:59:04
《乘风2026》:人们有多喜欢谢楠,就有多反感谢娜

《乘风2026》:人们有多喜欢谢楠,就有多反感谢娜

娱乐圈笔娱君
2026-04-08 14:23:29
新冠后遗症的长期侵袭,无数人在不知不觉中深陷困境

新冠后遗症的长期侵袭,无数人在不知不觉中深陷困境

律法刑道
2026-04-01 10:15:47
连拍四季不烂尾!Apple TV+这部美剧才是天花板

连拍四季不烂尾!Apple TV+这部美剧才是天花板

天天美剧吧
2026-04-08 14:13:34
中国最丰满的5位女星,美的各有千秋,她们的身材也太犯规了

中国最丰满的5位女星,美的各有千秋,她们的身材也太犯规了

不似少年游
2026-02-10 09:18:15
陈丽华离世!最后露面为送星云大师,迟重瑞全程搀扶太戳心

陈丽华离世!最后露面为送星云大师,迟重瑞全程搀扶太戳心

夕落秋山
2026-04-08 08:40:13
看到大陆接机代表,郑丽文心里踏实了,美国和民进党要双双出局

看到大陆接机代表,郑丽文心里踏实了,美国和民进党要双双出局

天老爷
2026-04-08 13:32:16
毛新宇参观祖宅时突然发现家谱记载:原来毛主席是毛太华第20代孙

毛新宇参观祖宅时突然发现家谱记载:原来毛主席是毛太华第20代孙

老杉说历史
2026-03-14 20:54:20
阿尔忒弥斯2号女宇航员科克晒太空美照引热议,网友纷纷求她分享手臂锻炼妙招

阿尔忒弥斯2号女宇航员科克晒太空美照引热议,网友纷纷求她分享手臂锻炼妙招

Thurman在昆明
2026-04-08 09:00:59
苹果8号员工干了49年:裁员名单绕着他走,因为赔不起

苹果8号员工干了49年:裁员名单绕着他走,因为赔不起

世界圈
2026-04-04 13:13:03
2026-04-08 17:19:00
薛定谔的BUG
薛定谔的BUG
有态度网友ytd
964文章数 30关注度
往期回顾 全部

科技要闻

造出地表最强AI,却死活不给你用!

头条要闻

女子打造"富婆"人设 假冒房东"一房多租"骗取上百万元

头条要闻

女子打造"富婆"人设 假冒房东"一房多租"骗取上百万元

体育要闻

40岁,但实力倒退12年

娱乐要闻

杨颖邓超低调现身观众席 支持陈赫话剧

财经要闻

天津海河乳业回应直播间涉黄

汽车要闻

5门5座/新复古造型 缤果Pro将于4月14日开启预售

态度原创

亲子
游戏
时尚
艺术
军事航空

亲子要闻

4岁女儿不睡觉偷吃面包,妈妈让她吃一口,结果她小心思太逗了

财报放猛料!任天堂第一方阵容重磅公开 实在太豪华

防晒专场|| 几十块到手,回购一年多才来推荐

艺术要闻

齐白石『凌波仙子』

军事要闻

文化符号当“弹药” 美伊将信息战带入新阶段

无障碍浏览 进入关怀版