Ecto中的数据建模需要一些时间来适应,特别是对于大多数已经。
使用传统的“重型”ORM。
对于很多ECTO新手用户来说,与协会相关的操作成为第一块绊脚石。ECTO提供了多个。
用于建立和修改记录之间的关联的功能,每个记录都是针对特定用例量身定做的。
从StackOverflow上关于cast_assoc、put_assoc和build_assoc的问题数量来看。
在线社区,选择正确的社区往往很有挑战性,特别是在用户还不习惯的情况下。
ECTO官方文件中的技术术语。
这篇文章的目的是在几个最常见的问题上给出一个简短但明确的答案。
(也是最简单的)场景。
传统ORM承担着极其复杂的“掩饰”任务。
与数据相关的操作,给开发人员一种使用本机语言数据容器的错觉。
为了实现这一点,ORM通常在幕后执行复杂的转换,这有时会导致次优
数据库性能。从这个意义上说,ORMS提出了一种折衷方案,即在语言本地语法的便利性和。
手工创建的SQL查询的精确度。
ECTO本质上提供了相同的权衡,但更倾向于手工创建的SQL查询。
核心概念上的区别在于ECTO并不打算抽象数据库操作,相反,
它为自己创建SQL查询提供了一种灵丹妙药的语法。ECTO依赖于开发人员进行格式化。
并验证数据以符合数据库架构,编制高效使用索引的查询,将。
记录在一起,并执行ORM试图自动化的其他任务。结果就是学习曲线变得更高了,
但也大大提高了灵活性。要更深入地比较ActiveRecord和ECTO,
看看这篇出色的ActiveRecord vs.Ecto帖子。
使用关联并不一定总是很复杂。在您有目标ID的情况下,ecto让。
您可以将关系列视为普通数据库字段。
为了给出一个具体的例子,让我们假设我们使用两个模型,Post和Comment,其中多个评论可以
参考一个帖子。在这种情况下,你的模型应该是这样的。
1个。
2个。
3个。
4.。
5个。
6个
7个。
8个。
9个。
10个。
11个。
12个。
13个。
14.
15个。
16个。
定义模块博客。POST DO。
使用ecto。图式。
架构(";POST&34;DO)。
有很多:评论,博客。评论。
字段:标题,:字符串。
字段:正文,:字符串
端部。
端部。
定义模块博客。评论做。
使用ecto。图式。
架构(";POST&34;DO)。
归属于:帖子、博客。邮政。
字段:正文,:字符串
端部。
端部。
默认情况下,每个表都包含一个主字段ID。POST上的HAS_MANY字段未引用数据库字段,它。
它的存在只是为了向ECTO提示,可以使用评论的Belong_to字段为帖子预载评论。
另一方面,WORMERS_TO字段指代表架构中的现有字段。默认情况下,此文件的名称
表中的字段与ECTO模型中的名称不同:数据库字段的末尾有_id。
ECTO允许您以与修改任何其他字段相同的方式修改这些类型的关联字段。在埃托文中,
更改原语字段的值称为“强制转换”。如果您需要为特定帖子创建新评论,
您实际上不需要任何特定于关联的函数,只需转换主键的值:
这是在两个表之间创建关联的最简单、最直接的方法。
将CAST_ASSOC看作是在关联上工作的CAST的特殊版本是很有用的。
但是,强制转换关联可能比强制转换普通字段复杂得多。强制转换调用通常转换为。
或多或少直接插入到单个SQL查询中,而CAST_ASSOC可能会导致多个INSERT、UPDATE或。
删除查询。让我们假设上例中的数据库表包含以下内容:
由于Post模型包含要评论的HASS_MANY关联,因此预加载所有评论是微不足道的。
在特定的帖子上:
%帖子{。
";id";=>;1,
一个关于……的故事。
正文";=>;&34;从前...";,
";评论";=>;[。
%COMMENT{";id";=&>;10,";正文";=&>;精彩故事!";},
%COMMENT{";id";=&>;11,";Body";=&>;接下来发生了什么?";},
%COMMENT{";id";=&>;12,";Body";=&>}感谢您的文章,
],。
}。
Single CAST_ASSOC Call On:注释将替换整个关联。实际上,这意味着这些值。
您传递给cast_assoc的信息将在以后的预加载调用中返回。这并不一定意味着所有。
数据库行将被替换。ECCO比较状态前和状态后的状态,并执行所需的最小工作量。
才能达到理想的状态。为了说明这一点,请考虑以下更改集:
参数=%{备注:[。
%COMMENT{";id";=&>;11,";Body";=&>;接下来发生了什么?";},
%COMMENT{";id";=&>;12,";Body";=&>;谢谢您的帖子,
%Comment{";正文";=&>;有趣";},
]}。
邮政。
|>;cast(params,[])。
|>;cast_assoc(:评论)
执行此变更集将导致对数据库的三次调用:
-删除ID为10的评论。
-更新ID为12的评论,并将Body设置为“谢谢您的帖子”
-插入正文为“有趣”的评论,并为其分配一个新的id。
ID为11的行保持不变,因为它与预加载值匹配。这里需要注意的重要一点是。
ECTO本身不会预加载数据,因此要使用cast_assoc,您需要记住调用preload
事先。但是,您并不局限于预加载一个完整的关联。Cast_assoc的工作方式与。
当您使用预加载作为Repo.preload(:Comments,Query)记录的子集时。此功能对以下方面非常有用。
将CAST_ASSOC的影响限制在关联记录的子集。
乍一看,put_assoc在很多方面与cast_assoc相似:它也适用于整个关联。
并要求您预先加载要更新的记录。然而,仔细检查后发现,它几乎是。
与你使用它的方式相反。关键区别在于put_assoc旨在更新
关联是“引用”的,而不是数据。也就是说,当您想要连接时,通常会使用put_assoc。
数据库中已存在的一条或多条记录的记录。
Put_Assoc可用于将新评论与现有帖子相关联,类似于我们在“直接转换”中所做的操作。
部分,但不直接使用post_id字段:
这使得您的代码在具有复杂主字段的情况下更加简洁,因为Ecto负责所有的记账工作
为了你。
Build_Assoc是一个方便的函数,允许您通过关联创建相关记录。
在一张现有的唱片上。为了继续我们的帖子/评论示例,这里有另一种创建新评论的方法:
POST=回购。滚蛋!(7)。
..。
COMMENT_PARAMS=%{。
";标题";:";一个故事…";
";Body";:";曾几何时...";
}。
埃托。Build_assoc(POST,:Comments,Comment_Params)。
#%评论{post_id:7,标题:";一个故事...";,正文:";从前...";}。
Build_assoc的强大之处在于它的表现力:上面的代码清楚地向您展示了评论属于帖子。
与上面讨论的函数不同,Build_Assoc不在变更集上操作-它构建一个变更集。这意味着你会。
只有在想要创建新记录时才使用Build_Assoc。
虽然这篇文章并没有涵盖您在生产应用程序中可能遇到的各种用例,
我希望它能给你一个坚实的基础,让你开始寻找答案。如果你需要提神的话。
在未来,这里有一个简单的流程图,它将提醒您讨论的用例:
ECTO的关联函数是对数据库中的字段引用的相对精简的抽象。了解如何。
这些功能中的每一个都在数据库级别上工作,这对于成为专业的Elixir/Phoenix开发人员至关重要。幸运的是,
ECTO的构建方式是,每个功能都相对较小、确定,并且只有一个目的。您先。
掌握了基础知识之后,与传统ORM相比(至少在我的经验中是这样),您可以期待更少的“理解”
情况就是这样)。编码愉快!
附注:如果你想在文章发布后立即阅读《炼金术》,请订阅我们的《炼金术》时事通讯,不要错过任何一篇帖子!