2016-11-13 191 views
1

我有模式,看起來如下:構建HAS_ONE關係

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 

和第三臺

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

我不知道,如果架構國家是精心設計的?

在國家中的條目應該是這樣的:

"CH" | "EN" | "Switzerland" 
"DE" | "EN" | "Germany" 

這個記錄應zhcon失敗:

"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 

我希望,它是清楚我想要達到的目標。

UPDATE

我創建的表爲你傷心:

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 

當我執行混合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

兩件事情:

  1. 您在Countrybelongs_to因爲Country的表包含外鍵。您還需要在belongs_to中指定外部表的列名。

    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 
    
+0

如何HAS_ONE在'CountryCode'和'LanguageCode'模式應該樣子? –

+0

我更新了我的帖子。 –

+1

我想你還需要在'countries_code'中爲'alpha2'添加一個唯一索引,並在'languages_code'中爲'code'添加一個唯一索引。如果您編輯現有遷移以添加這些字段,請務必重新運行遷移。 – Dogbert