Phoenix Contexts 入门:用 Elixir 模块封装数据访问与业务逻辑
Phoenix Contexts 入门用 Elixir 模块封装数据访问与业务逻辑【免费下载链接】phoenixPeace of mind from prototype to production项目地址: https://gitcode.com/gh_mirrors/ph/phoenix本指南介绍 Phoenix 框架的核心设计概念 ——Contexts上下文。Context 是把数据访问、数据校验与业务逻辑封装进命名良好的 Elixir 模块的一种组织方式它是连接 Ecto 数据层与 Controller、LiveView 等 Web 界面的桥梁。读完本文你将理解 Context 在 Phoenix 应用中的定位、mix phx.gen.*系列生成器如何自动产出 Context 模块、如何把相关资源聚合到同一 Context 以应对应用增长并能用真实的电商项目骨架动手实践。什么是 Context模块即边界构建 Phoenix 项目时我们首先是在构建一个 Elixir 应用Phoenix 的职责是为这个 Elixir 应用提供 Web 界面。我们习惯用模块与函数组织代码并给特定模块赋予名字控制器Controller、路由器Router、LiveView 等。而 Web 应用中最关键的部分往往是封装数据访问与数据校验的模块这些模块就被称为contexts上下文。它们通常通过Ecto访问数据库或通过Req这类 HTTP 客户端调用外部 API。给这些模块起一个名字是为了让开发者能识别这些模式、便于交流。归根结底Context 和你的控制器、视图一样只是普通的 Elixir 模块。如果你使用过mix phx.gen.html、mix phx.gen.json或mix phx.gen.live那你已经使用过 Context 了。以 request_lifecycle.md 与 ecto.md 中学到的知识为基础本文把这些概念串联起来聚焦于如何写出面向 Web 功能、与整个 Elixir 应用良好交互的代码。生成器如何构建 Context在 Phoenix 应用中运行生成器即可直观感受 Context 的产出。例如$ mix phx.gen.live Post posts title body:text这条命令会输出若干文件其中包括位于lib/my_app/posts/post.ex的MyApp.Posts.Postschema它描述资源在数据库中的表示方式一个名为MyApp.Posts的context 模块它封装了对上述 schema 的全部数据库访问。MyApp.Posts模块把所有与帖子posts相关的功能集中在一起而不是把逻辑零散地撒在控制器、LiveView 等各处。从 lib/mix/tasks/phx.gen.live.ex 的源码可以看到生成器的完整定位它生成的 context 模块是给定资源的 API 边界an API boundary for the given resource且一个 context 常常承载多个相关资源A context often holds many related resources。生成器会按[context] schema table attr:type...的格式解析参数并说明生成后需要在router.ex中补充 Live 路由。整个生成流程由Mix.Phoenix.Context与Mix.Phoenix.Schema两个模块协同完成schema 负责把数据库字段映射为 Elixir 结构体context 负责组装对外 API。值得留意的是在mix phx.gen.live、mix phx.gen.html、mix phx.gen.json中context 名称是可选的。查看 lib/mix/tasks/phx.gen.context.ex 中validate_args!/4的实现可以发现当第二个参数以小写字母开头时Phoenix 会用Phoenix.Naming.camelize/1把复数表名驼峰化为 context 模块名如users→Users实现省略 context 名自动生成的行为。嵌套资源把相关 Schema 聚合到同一 ContextContext 的另一个重要用途是嵌套资源nest resources。例如给帖子添加评论时由于评论从属于帖子可以把它们的 schema 放在一起$ mix phx.gen.live Posts Comment comments post_id:references:posts body:text上面命令的第一个参数是context 模块名它指示 Phoenix 把评论功能与帖子功能聚合到同一处。post_id属性则指定了对 posts 表的外键引用。随着应用增长Context 帮你把相关联的 schema 分组管理而不是让几十个 schema 散落一地、彼此关系毫无头绪。源码对此有更明确的印证。lib/mix/tasks/phx.gen.context.ex 中生成器支持--merge-with-existing-context与--no-merge-with-existing-context两个开关当向已存在的 context中生成新资源时默认会弹出确认提示告知你该 context 当前的函数与文件数量并提醒同一 context 中放多个资源是可以的只要它们紧密相关如果关系不紧密另一个 context 可能更合适。生成器随后把新的 schema 访问函数与测试**注入inject**进现有模块而不是覆盖重写。这里还有一条来自官方文档的建模建议两个资源在数据库中有外键关联并不代表它们必须属于同一个 context——否则几乎所有资源都会被塞进一个巨型 context。拿不准时优先为每个资源建独立 context之后再重构。命名 Contextmix phx.gen.auth 的显式 Context开发者也可以用 Context 有意地为应用的各个部分命名。例如mix phx.gen.auth要求显式给出 context 名常见用法是$ mix phx.gen.auth Accounts User users也可以按喜好命名例如$ mix phx.gen.auth Identity Client clients生成的Accounts或Identitycontext 会封装管理用户或客户端及其令牌的全部功能。你也可以把 context 命名为Users但账户/身份管理在大多数应用中都有明确的名称与边界给它一个显式名称能让其用途一目了然。而且说到底它们也只是普通的模块。参考 lib/mix/tasks/phx.gen.auth.ex 的文档可知mix phx.gen.auth Accounts User users会在Accountscontext 下生成两个schemaUser与UserTokenmix phx.gen.auth Identity Client clients则会生成Identitycontext 以及其中的Client与ClientToken。该生成器支持多次调用例如分别生成Store User users与Backoffice Admin admins并默认按 schema 创建 scope相关细节可查阅 mix_phx_gen_auth.md 与 scopes.md。动手实践构建 hello 电商应用本指南后续章节将围绕一个电商系统展开展示商品、允许用户把商品加入购物车并完成下单。我们会通过有意图地设计和命名 Context来完成它。与 Phoenix 其他指南不同这个系列指南需要按顺序阅读。先从零开始创建一个名为hello的应用推荐使用 Phoenix ExpressmacOS/Ubuntu$ curl https://new.phoenixframework.org/hello | shWindows PowerShellcurl.exe -fsSO https://new.phoenixframework.org/hello.bat; .\hello.bat如果上述命令不可用请参考 installation.md然后运行$ mix phx.new hello按屏幕提示完成后续步骤并在编辑器中打开生成的hello项目即可进入下一个章节。源码级剖析生成器背后的 Context 模板生成器产出的 context 模块并非魔法其形态完全由仓库中的 EEx 模板决定。查看 context.ex.eex 可以看到一个新 context 模块的骨架defmodule % inspect context.module % do moduledoc The % context.name % context. import Ecto.Query, warn: false alias % inspect schema.repo %% schema.repo_alias % end也就是说初始 context 只是一个带moduledoc文档、引入Ecto.Query并别名仓库模块的空壳随后 schema_access.ex.eex 模板会把标准 CRUD 函数注入其中list_plural/0Repo.all(Schema)列出所有记录get_singular!/1按主键获取单条记录不存在时抛出Ecto.NoResultsErrorcreate_singular/1用Schema.changeset/2构建变更集并Repo.insertupdate_singular/2用 changeset 校验后Repo.updatedelete_singular/1Repo.delete删除记录change_singular/2返回用于表单回显的%Ecto.Changeset{}。每个函数都带doc与## Examples的 doctest 示例。生成器通过inject_schema_access/3把这段代码注入到模块的最后一个end之前见 phx.gen.context.ex若 context 文件尚不存在则先由ensure_context_file_exists/3基于模板创建。此外生成器还会同步产出 context 测试context_test.exs.eex与测试夹具fixtures.ex.eex并注入到test/目录对应文件中——这也是为什么从生成器开始能同时获得可运行代码与可运行测试。从这套模板可以清晰地看出 Phoenix 的设计取向生成器首先是学习工具和起点。它把职责划分的思考方式内建到代码生成中——schema 只描述数据形状与校验规则context 负责对外暴露意图明确的业务 API而doc false标注的changeset/2则提示调用方请经由 context 使用变更集。为什么边界重要Web 层与业务逻辑解耦生成器把控制器与 context 的职责切分得十分干净控制器是Web 界面负责解析请求、渲染响应context 是业务 API负责数据获取与持久化。控制器只关心告诉应用去执行某项工作而不关心底层是 SQL 查询还是全文检索引擎——这正是 your_first_context.md 中深入展开的内容例如index动作调用Catalog.list_products/0、create动作调用Catalog.create_product/1而 context 内部才使用Repo。这种解耦让 context 代码可以被 channel、mix task 或后台进程等任意接口复用。在 in_context_relationships.md 中你会看到如何在Catalogcontext 内继续生长用mix phx.gen.context追加Category资源、用 join 表建立多对多关系、再通过Ecto.Changeset.put_assoc/4把关联写回变更集——所有代码仍然围绕同一个 context 边界展开。结语与系列导航Context 是 Phoenix 应用把职责画清楚的第一块基石。通过生成器快速起步借助良好命名的模块封装数据访问与校验你的应用就能在边界清晰的前提下自然增长。本系列指南应按顺序阅读后续章节依次为your_first_context.md动手创建第一个 Catalog contextin_context_relationships.mdcontext 内的资源关联cross_context_boundaries.md跨 context 边界more_examples.md 与 faq.md更多示例与常见问题。【免费下载链接】phoenixPeace of mind from prototype to production项目地址: https://gitcode.com/gh_mirrors/ph/phoenix创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Atlas 300V AI推理加速卡:YOLO模型从零部署与性能调优实战

Atlas 300V AI推理加速卡:YOLO模型从零部署与性能调优实战

1. 这块“运算加速卡”,到底解决了什么问题先给你吃一颗定心丸:Atlas 300V 24G 不是我们常说的那种跑训练的大显卡,它是一张面向推理场景的专用加速卡,官方定位是数据中心和边缘侧的人工智能推理。很多人第一次看到“24G”这个数字…

2026/9/20 21:21:32 阅读更多 →
ComfyUI 工作流中文合集:16 个预设模板,导入即可出图

ComfyUI 工作流中文合集:16 个预设模板,导入即可出图

ComfyUI 工作流中文合集:16 个预设模板,导入即可出图 【免费下载链接】ComfyUI-Workflows-ZHO 我的 ComfyUI 工作流合集 | My ComfyUI workflows collection 项目地址: https://gitcode.com/GitHub_Trending/co/ComfyUI-Workflows-ZHO ComfyUI-Wo…

2026/9/20 21:21:32 阅读更多 →
AI漫剧制作工具全攻略:从一站式工作台到量产变现

AI漫剧制作工具全攻略:从一站式工作台到量产变现

2026年了,漫剧在短视频赛道上已经不是新鲜词。所谓漫剧,就是用动态漫画的形式讲一个短剧故事,单集1到3分钟,强冲突、快反转,剧情密度比传统动画高一截,特别适合碎片化刷视频的用户。以前做漫剧是专业团队的…

2026/9/20 21:20:31 阅读更多 →

最新新闻

10年装修避坑指南:史上最详细的装修日记拆解

10年装修避坑指南:史上最详细的装修日记拆解

10年装修避坑指南:史上最详细的装修日记拆解 满屏的红色报错信息堆在眼前,StackTrace 长得像天书,这种窒息感我懂。很多刚入行的兄弟,拿着手机对着复杂的施工现场或者代码逻辑发呆,觉得底层原理高不可攀。其实,把“史上最详细的装修日记”…

2026/9/21 22:58:55 阅读更多 →
QQ空间历史说说导出指南:3 条命令,把翻不到的旧动态全部找回

QQ空间历史说说导出指南:3 条命令,把翻不到的旧动态全部找回

QQ空间历史说说导出指南:3 条命令,把翻不到的旧动态全部找回 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 想翻几年前的说说,QQ 空间页面却只能往前…

2026/9/21 22:58:55 阅读更多 →
claude-seo 结构化数据迁移指南:Schema.org 已弃用富媒体结果类型全览(2024–2026)

claude-seo 结构化数据迁移指南:Schema.org 已弃用富媒体结果类型全览(2024–2026)

【免费下载链接】claude-seo Universal SEO skill for Claude Code. 25 sub-skills 18 sub-agents covering technical SEO, E-E-A-T, schema, GEO/AEO, backlinks, local SEO, maps intelligence, semantic clustering, e-commerce SEO, international SEO, Google APIs, and…

2026/9/21 22:58:55 阅读更多 →
华为p6-u06源码解析:3步搞定环境配置痛点

华为p6-u06源码解析:3步搞定环境配置痛点

华为p6-u06源码解析:3步搞定环境配置痛点 配置环境就卡半天?华为p6-u06的调试器一挂,整个开发节奏全乱。别急,直接看源码解析,比看文档快十倍。 入口定位:找到调试器启动点 华为p6-u06的调试功能藏在 debugger…

2026/9/21 22:58:55 阅读更多 →
Lively Wallpaper让Windows 桌面灵动起来!

Lively Wallpaper让Windows 桌面灵动起来!

Lively Wallpaper让Windows 桌面灵动起来! 办公Windows电脑更换动态壁纸教程Lively Wallpaper让Windows 桌面灵动起来!1. 精美动态壁纸来源2. 应用商店安装 Lively Wallpaper二编:新增扩展屏后壁纸设置1. 精美动态壁纸来源 哲风壁纸有很多精…

2026/9/21 22:58:55 阅读更多 →
停在昨天源码拆解,搞定高频面试题不再卡壳

停在昨天源码拆解,搞定高频面试题不再卡壳

停在昨天源码拆解,搞定高频面试题不再卡壳 配置环境就卡半天,这是多少开发者的噩梦?明明照着文档敲,结果报了一堆错,折腾到深夜还是没跑通。更让人头大的是,很多 高频面试题…

2026/9/21 22:57:54 阅读更多 →

日新闻

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and …

2026/9/21 0:00:01 阅读更多 →
gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析 【免费下载链接】gin-vue-admin 🚀ViteVue3Gin拥有AI辅助的基础开发平台,企业级业务AI开发解决方案,内置mcp辅助服务,内置skills管理,…

2026/9/21 0:00:01 阅读更多 →
Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

桌面应用AI 应用插件系统 【免费下载链接】Wox A cross-platform launcher that simply works 项目地址: https://gitcode.com/gh_mirrors/wo/Wox 点击查看 免费下载 全功能插件(Full-featured Plugin)是 Wox 三类插件实现方式中能力最完整的…

2026/9/21 0:00:01 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/21 3:13:20 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/21 2:19:36 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/21 4:51:05 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/21 15:36:51 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/21 15:36:51 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →