2016-06-26 107 views
0

有什麼辦法可以獲得嵌入式模式的唯一約束?嵌入式模式的唯一約束

下面給出的代碼給出了異常:

可以不加約束,以變更集,因爲它不具有源

name來自架構persons和現場emailaccounts

方案:

embedded_schema do 
    field :name 
    field :email 
end 

變更集:

struct 
    |> Ecto.Changeset.cast(params, [:name, :email]) 
    |> Ecto.Changeset.validate_required([:name, :email]) 
    |> Ecto.Changeset.unique_constraint(:email) 

我試着給模式accounts作爲參數,但沒有成功。

+0

你可以發佈你的模塊代碼嗎?你是否必須設置'使用App.Web,:model'? – Mohamad

回答

1

有什麼辦法可以得到一個嵌入式模式的唯一約束條件嗎?

簡短的回答是否定的。

Ecto的unique_constraint依賴於數據庫。爲了工作,您需要爲給定字段添加唯一索引。約束只會將數據庫錯誤轉換爲變更集錯誤。您可以在文檔https://hexdocs.pm/ecto/Ecto.Changeset.html#unique_constraint/3

編輯閱讀更多:

使用 embedded_schema意味着你不能對 email「場」唯一索引,因爲它不是一個字段本身。 Ecto使用單個 jsonb字段來存儲嵌入的數據。

您可以創建與數據庫相關的Account模式。然後,您可以手動將數據映射到帳戶更改集並在其上使用unique_constraint

+0

它不會被存儲爲JSON。 'name'字段存儲在'persons'表中,而'email'字段存儲在'accounts'表中。所以我想我可以使用這個約束。小背景信息:我正在嘗試'insert_all'(http://blog.plataformatec.com.br/2016/05/ectos-insert_all-and-schemaless-queries/)爲此我製作了一個表單來創建一個新的「人物'與一些帳戶信息,如「電子郵件」。 – Hatsjoem

+1

我明白了。您仍然無法在此更改集上使用'unique_constraint',因爲其架構與數據庫無關。您可以定義'Account'模式,並在賬戶變更集上設置'unique_constraint'。所以你必須手動將數據映射到一個'account'變更集,它將使用唯一的約束。 – ventsislaf

+0

那就是我要做的事情。但我認爲,如果沒有將其映射到「帳戶」模型/ – Hatsjoem