2016-11-26 22 views
2

什麼是正確的方式來執行驗證的結構與關聯明確傳遞?當Struct或nil通過時,Ecto validate_required on belongs_to

def changeset(model, params \\ %{}) do 
    model 
    |> cast(params, [:name]) 
    |> validate_required([:make, :name]) 
    |> update_change(:name, &String.downcase/1) 
    |> unique_constraint(:name, name: :models_name_make_id_index) 
end 

如何我會使用它:

changeset(%Model{make: make}, %{....}) 

在哪裏化妝可以是零。並且我想要正確的錯誤消息而不是:

** (UndefinedFunctionError) function nil.id/0 is undefined or private 

回答

1

驗證主要用於處理用戶輸入,而不是確保數據一致性。如果你以編程方式創建數據,驗證不是防止程序員錯誤的正確工具(如果有人忘記添加關聯) - 數據庫約束是。

當處理關聯的用戶輸入時,功能如cast_assoc/3cast_embed/3接受required: true選項來強制關聯的存在。

創建一個能夠正確執行並添加關聯的函數可能是一個好主意,而不是將該邏輯分散在控制器(或其他調用changeset函數的地方)上。

+0

好的,這是我想到的,最後以模式匹配提供的函數結束:(雖然會很好,但還是會將它永遠鎖定在一個地方 –

+0

@IvanYouroff你可以在這裏提供那個函數嗎? – Johannes

+0

它演變了我們創建了一個實現了Result和Option monadic類型的小型庫,它聽起來很花哨,但實際上它只是一個包含宏的元組ok(value )被轉換爲{:ok,value}和錯誤(e)爲{:error,e},它完全符合Erlang/Elixir庫的大部分。下面是庫:https://github.com/youroff/monex,這裏是要點,我在這種情況下如何使用它:https://gist.github.com/youroff/8812191758e8df0d69f7d8c94b650b33 –