建立 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 更改为不唯一。

两件事:

  1. 您希望 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 声明应该在 CountryCodeLanguageCode 模式中。

  2. 您要在迁移中指定的选项是 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