建立 has_one 关系
Build has_one relationship
我有架构,如下所示:
defmodule Busiket.LanguageCode do
use Busiket.Web, :model
schema "languages_code" do
field :code, :string
field :text, :string
timestamps
end
end
第二个模式:
defmodule Busiket.CountryCode do
use Busiket.Web, :model
schema "countries_code" do
field :alpha2, :string
field :alpha3, :string
timestamps
end
end
和第三个table
defmodule Busiket.Country do
use Busiket.Web, :model
alias Busiket.LanguageCode
alias Busiket.CountryCode
schema "countries" do
has_one :code, CountryCode
has_one :lang, LanguageCode
field :text, :string
timestamps
end
end
正如您在第三个模式中看到的那样,字段 code
应该取决于 country_code
具有字段 code
.
的模式
lang 字段应取决于 language_code
字段为 alpha2
的架构。
不知道schema country设计的好不好?
国家/地区的条目应如下所示:
"CH" | "EN" | "Switzerland"
"DE" | "EN" | "Germany"
这条记录应该失败了:
"YY" | "EN" | "Foo"
因为没有一个国家有 YY
iso 代码。
来自 language_code
的迁移文件如下所示:
defmodule Busiket.Repo.Migrations.CreateLanguageCode do
use Ecto.Migration
def change do
create table(:languages_code) do
add :code, :string, size: 3
add :text, :string
timestamps
end
end
end
和country_code
defmodule Busiket.Repo.Migrations.CreateCountryCode do
use Ecto.Migration
def change do
create table(:countries_code) do
add :alpha2, :string, size: 2
add :alpha3, :string, size: 3
timestamps
end
end
end
最后我尝试了 country
迁移:
defmodule Busiket.Repo.Migrations.CreateCountryTable do
use Ecto.Migration
def change do
create table(:countries) do
add :code, references(:countries_code), [name: :alpha2]
add :lang, references(:languages_code), [name: :code]
add :text, :string
timestamps
create unique_index(:countries, [:code, :lang])
end
end
end
我希望,很清楚我想要达到的目标。
更新
我创造了 table 为你难过:
defmodule Busiket.Repo.Migrations.CreateCountryTable do
use Ecto.Migration
def change do
create table(:countries) do
add :coun, references(:countries_code, column: :alpha2, type: :string)
add :lang, references(:languages_code, column: :code, type: :string)
add :text, :string
timestamps
end
create unique_index(:countries, [:coun, :lang])
end
end
当我执行 mix ecto.migrate 时,出现以下错误:
20:34:11.012 [info] create table countries
** (Postgrex.Error) ERROR (invalid_foreign_key): there is no unique constraint matching given keys for referenced table "countries_code"
我想,我必须将 :alpha3 更改为不唯一。
两件事:
您希望 Country
中的 belongs_to
因为 Country
的 table 包含外键。您还需要在 belongs_to
.
中指定外国 table 的列名
schema "countries" do
belongs_to :code, CountryCode, foreign_key: :alpha2
belongs_to :lang, LanguageCode, foreign_key: :code
...
end
has_one
声明应该在 CountryCode
和 LanguageCode
模式中。
您要在迁移中指定的选项是 column
,它应该在对 references
的调用中。 (您当前的代码正在使用 add
中没有 name
选项。)您还需要指定 type
.
create table(:countries) do
add :code, references(:countries_code, column: :alpha2, type: :string)
add :lang, references(:languages_code, column: :code, type: :string)
...
end
我有架构,如下所示:
defmodule Busiket.LanguageCode do
use Busiket.Web, :model
schema "languages_code" do
field :code, :string
field :text, :string
timestamps
end
end
第二个模式:
defmodule Busiket.CountryCode do
use Busiket.Web, :model
schema "countries_code" do
field :alpha2, :string
field :alpha3, :string
timestamps
end
end
和第三个table
defmodule Busiket.Country do
use Busiket.Web, :model
alias Busiket.LanguageCode
alias Busiket.CountryCode
schema "countries" do
has_one :code, CountryCode
has_one :lang, LanguageCode
field :text, :string
timestamps
end
end
正如您在第三个模式中看到的那样,字段 code
应该取决于 country_code
具有字段 code
.
lang 字段应取决于 language_code
字段为 alpha2
的架构。
不知道schema country设计的好不好?
国家/地区的条目应如下所示:
"CH" | "EN" | "Switzerland"
"DE" | "EN" | "Germany"
这条记录应该失败了:
"YY" | "EN" | "Foo"
因为没有一个国家有 YY
iso 代码。
来自 language_code
的迁移文件如下所示:
defmodule Busiket.Repo.Migrations.CreateLanguageCode do
use Ecto.Migration
def change do
create table(:languages_code) do
add :code, :string, size: 3
add :text, :string
timestamps
end
end
end
和country_code
defmodule Busiket.Repo.Migrations.CreateCountryCode do
use Ecto.Migration
def change do
create table(:countries_code) do
add :alpha2, :string, size: 2
add :alpha3, :string, size: 3
timestamps
end
end
end
最后我尝试了 country
迁移:
defmodule Busiket.Repo.Migrations.CreateCountryTable do
use Ecto.Migration
def change do
create table(:countries) do
add :code, references(:countries_code), [name: :alpha2]
add :lang, references(:languages_code), [name: :code]
add :text, :string
timestamps
create unique_index(:countries, [:code, :lang])
end
end
end
我希望,很清楚我想要达到的目标。
更新
我创造了 table 为你难过:
defmodule Busiket.Repo.Migrations.CreateCountryTable do
use Ecto.Migration
def change do
create table(:countries) do
add :coun, references(:countries_code, column: :alpha2, type: :string)
add :lang, references(:languages_code, column: :code, type: :string)
add :text, :string
timestamps
end
create unique_index(:countries, [:coun, :lang])
end
end
当我执行 mix ecto.migrate 时,出现以下错误:
20:34:11.012 [info] create table countries
** (Postgrex.Error) ERROR (invalid_foreign_key): there is no unique constraint matching given keys for referenced table "countries_code"
我想,我必须将 :alpha3 更改为不唯一。
两件事:
您希望
中指定外国 table 的列名Country
中的belongs_to
因为Country
的 table 包含外键。您还需要在belongs_to
.schema "countries" do belongs_to :code, CountryCode, foreign_key: :alpha2 belongs_to :lang, LanguageCode, foreign_key: :code ... end
has_one
声明应该在CountryCode
和LanguageCode
模式中。您要在迁移中指定的选项是
column
,它应该在对references
的调用中。 (您当前的代码正在使用add
中没有name
选项。)您还需要指定type
.create table(:countries) do add :code, references(:countries_code, column: :alpha2, type: :string) add :lang, references(:languages_code, column: :code, type: :string) ... end