2017-08-02 60 views
0

我試圖保存更新到記錄(用戶)有一個父(州)。用戶記錄顯示正常(顯示,編輯),包括狀態。用戶記錄可以更新其自身的屬性,但用戶所選狀態的任何更改都不會持久。當從1更改用戶的狀態2,用戶PARAMS返回到控制器從視圖看起來不錯......從日誌 - >Ecto:變更集丟棄更新到父模型

%{"email" => 「[email protected]", "first_name" => 「Abe", 
"last_name" => 「Sam", "password" => 「foobar", "state_id" => "2"} 

但是,當這個被傳遞給用戶的變更,它回來換到STATE_ID下降......從日誌 - >

#Ecto.Changeset<action: nil, 
changes: %{password: "foobar", 
password_hash: 「xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx."}, 
errors: [], data: #SomeApp.User<>, valid?: true> 

控制器中的更新是:

def update(conn, %{"id" => id, "user" => user_params}) do 
    user = Repo.get!(User, id) 
    changeset = User.changeset(user, user_params) 
    case Repo.update(changeset) do 

...

相關的變更代碼是:

def changeset(model, params \\ %{}) do 
    model 
    |> cast(params, [:email, :first_name, :last_name, :password]) 
    |> assoc_constraint(:state) 
    |> validate_required([:email, :first_name, :last_name, :password]) 
    |> unique_constraint(:email) 
    |> validate_length(:password, min: 4, max: 100) 
    |> put_pass_hash() 
    end 

用戶的模式是:

schema "users" do 
    field :email, :string 
    field :password, :string, virtual: true 
    field :password_hash, :string 
    field :first_name, :string 
    field :last_name, :string 
    belongs_to :state, SomeApp.State 

    timestamps() 
    end 

什麼是我錯了這裏做什麼?我是否在我的變更集中丟失了將參數中的user_id轉換爲變更集的內容?我希望我做的事情簡單而愚蠢 - 我真的花了幾個小時試圖閱讀挑選這個分開,我卡住了!

回答

1

既然你想從params使用state_id,你需要在調用添加:state_id到允許列表cast。沒有:state_id在允許列表中,該值將被忽略,這就是現在正在發生的事情。

|> cast(params, [:email, :first_name, :last_name, :password]) 

應該

|> cast(params, [:email, :first_name, :last_name, :password, :state_id]) 
+0

三江源 - 我沒有嘗試已經,鳳凰拋出上一個錯誤說你需要使用cast_assoc鑄造協會。我會repro並得到確切的錯誤。但是,然後嘗試拋出一個單獨的錯誤,抱怨cast_assoc是針對兒童的。 –

+0

我錯了,現在完全可行,就像你說的。不知道爲什麼它以前沒有工作(也許我沒有在那裏assoc_constraint)。巨大的謝謝 - 你讓我的一天! –

+0

我想通了:我想我以前添加:狀態到演員而不是:state_id。我發現所屬的命名與實際的列約定(state vs state_id)並不直觀。我認爲我做對了嗎? –