我首先尝试使用简单的一级深度结构来播种我的数据库并且效果很好。但是,当我添加路径映射以匹配我的顶级结构路径字段时,我得到错误。
** (Postgrex.Error) ERROR 42703 (undefined_column): column "apis_id" of relation "paths" does not exist
我已经尝试删除apis_id,但我相信我需要该字段来预加载ApiController中的Path结构。也许问题出在我的has_many
/ belongs_to
语法中,虽然我相信我的方法是正确的,并且我已经尝试过淹没其他外键和引用而没有运气。
我也可能只是缺少一些非常愚蠢的东西,需要一些新鲜的眼睛,但我希望我对这种关系的理解可能搞砸了。
以下是我的迁移:
_create_api.exs
defmodule App.Repo.Migrations.CreateApi do
use Ecto.Migration
def change do
create table(:apis) do
add :basePath, :string
add :definitions, :string
add :paths, references(:paths)
timestamps()
end
end
end
_create_paths.exs
defmodule App.Repo.Migrations.CreatePath do
use Ecto.Migration
def change do
create table(:paths) do
add :apis_id, :string
add :route, :string
timestamps()
end
end
end
我的模特: api.ex
defmodule App.Api do
use App.Web, :model
schema "apis" do
field :basePath, :string
field :definitions, :string
has_many :paths, App.Path, foreign_key: :apis_id
timestamps()
end
end
path.ex
defmodule App.Path do
use App.Web, :model
schema "paths" do
belongs_to :apis, App.Api, references: :apis_id
field :route, :string
timestamps()
end
end
这里还有我的ApiController api_controller.ex
defmodule App.ApiController do
use App.Web, :controller
alias App.Api
def index(conn, _params) do
apis = Repo.all(Api) |> Repo.preload([:paths])
render conn, "index.json", apis: apis
end
end
最后我的种子.ex
alias App.Repo
alias App.Path
alias App.Api
api = %Api{
basePath: "v1",
definitions: "none",
paths: [
%Path{
apis_id: 1,
route: "/account"
}
]
}
Repo.insert! api
如果我删除%Path映射并将其设为空字符串,则此方法有效。
非常感谢任何以正确方向转向的帮助!
提前谢谢。
答案 0 :(得分:0)
您不应该将paths
引用到数据库中。一对多的关系只是单方面的 - 你只需要api_id
架构中的Path
,你不需要反过来。
但是Ecto
能够将Path
映射到Api
struct中的字段。您不需要的是paths
迁移中的_create_api
字段。
所以我认为正确的文件内容应该是:
_create_api.exs
defmodule App.Repo.Migrations.CreateApi do
use Ecto.Migration
def change do
create table(:apis) do
add :basePath, :string
add :definitions, :string
timestamps()
end
end
end
_create_paths.exs
defmodule App.Repo.Migrations.CreatePath do
use Ecto.Migration
def change do
create table(:paths) do
add :api_id, references(:apis)
add :route, :string
timestamps()
end
end
end
api.ex
defmodule App.Api do
use App.Web, :model
schema "apis" do
field :basePath, :string
field :definitions, :string
has_many :paths, App.Path
timestamps()
end
end
path.ex
defmodule App.Path do
use App.Web, :model
schema "paths" do
belongs_to :api, App.Api
field :route, :string
timestamps()
end
end
请注意,我已从模型中删除了references
和foreign_key
。我还将字段apis_id
的名称更改为api_id
以匹配标准命名。
编辑:添加了seeds.exs
alias App.Repo
alias App.Path
alias App.Api
api = Repo.insert! %Api{
basePath: "v1",
definitions: "none"
}
path = Repo.insert! %Path{
api_id: api.id,
route: "/account"
}
但我建议你使用变更集。