You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Ecto中定义无迁移、不持久化的虚拟模型?

在Ecto中创建无需持久化的虚拟模型

当然可以!在Ecto里完全能实现这种不需要迁移文件、也不持久化到数据库的「虚拟模型」,正好匹配你在iex中测试独立函数的需求。核心就是用embedded_schema来定义——你提到的embedded schema确实是实现这种需求的最佳方案,它本身就设计为不需要对应数据库表,下面给你一步步演示具体实现:

1. 定义虚拟模型

直接用embedded_schema创建模型,不需要任何迁移文件,所有字段都不会被持久化到数据库。你还可以根据需要添加virtual: true的字段,或者普通字段都没问题:

defmodule VirtualTestModel do
  use Ecto.Schema
  import Ecto.Changeset

  embedded_schema do
    # 普通字段(不会存数据库)
    field :name, :string
    field :age, :integer
    # 虚拟字段,仅在内存中存在
    field :greeting, :string, virtual: true
  end

  # 定义changeset用于数据校验和转换
  def changeset(model, params \\ %{}) do
    model
    |> cast(params, [:name, :age])
    |> validate_required([:name])
    |> validate_number(:age, greater_than: 0)
    # 可以在changeset里给虚拟字段赋值
    |> put_change(:greeting, "Hello from virtual model!")
  end
end

2. 在iex中测试使用

你可以直接在iex里加载这个模型(如果是在项目里,直接启动iex即可;如果是临时测试,也可以把代码粘贴到iex中),然后用它来测试你的独立函数:

# 创建空模型实例
empty_model = %VirtualTestModel{}

# 用参数生成校验后的changeset
valid_changeset = VirtualTestModel.changeset(empty_model, %{name: "Bob", age: 28})
valid_changeset.valid? # 返回 true
valid_changeset.changes # 查看处理后的字段值

# 将changeset转换为可用的模型实例
processed_model = Ecto.Changeset.apply_changes(valid_changeset)
processed_model.greeting # 输出 "Hello from virtual model!"

# 测试你的独立函数示例
defmodule MyBusinessLogic do
  def format_user_info(user) do
    "#{user.name} is #{user.age} years old - #{user.greeting}"
  end
end

MyBusinessLogic.format_user_info(processed_model)
# 输出 "Bob is 28 years old - Hello from virtual model!"

关键说明

  • embedded_schema 不需要依赖任何数据库连接,也不需要创建迁移文件,完全在内存中运行,非常适合快速测试。
  • 你可以像使用普通Ecto Schema一样定义changeset,做数据校验、字段转换,完美模拟真实场景下的数据处理逻辑。
  • 如果只是临时测试,甚至不需要把模型写到项目文件里,直接在iex中定义后就能使用。

内容的提问来源于stack exchange,提问作者script

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:38:17