2016-07-18 5 views
1

現在、Phoenixプログラミングのコードを実行しています。親の作成時にEcto.InvalidChangesetErrorがhas_manyリレーションで発生する

私はRumbl.TestHelpers.insert_user

** (Ecto.InvalidChangesetError) could not perform insert because changeset is invalid. 

* Changeset changes 

%{name: "Some user", password: "supersecret", password_hash: "$2b$12$ZaSx6WcTZnrRGrneHsrNF.oMx8if3yMNssnx1B/lGBD5/GPj17Ym6", username: "user50853EBB5B75FC40"} 

* Changeset params 

%{"name" => "Some user", "password" => "supersecret", "username" => "user50853EBB5B75FC40"} 

* Changeset errors 

[videos: "is invalid"] 

(ecto) lib/ecto/repo/schema.ex:121: Ecto.Repo.Schema.insert!/4 

Rumbl.TestHelpers.insert_userはこのようになります実行したときに、私は次のエラーを取得する:

alias Rumbl.Repo 

def insert_user(attrs \\ %{}) do 
    changes = Dict.merge(%{ 
     name: "Some user", 
     username: "user#{Base.encode16(:crypto.rand_bytes(8))}", 
     password: "supersecret" 
        }, attrs) 

    %Rumbl.User{} 
    |> Rumbl.User.registration_changeset(changes) 
    |> Repo.insert!() 
end 

Rumbl.User

defmodule Rumbl.User do 
    use Rumbl.Web, :model 

    schema "users" do 
    field :name, :string 
    field :username, :string 
    field :password, :string, virtual: true 
    field :password_hash, :string 
    has_many :videos, Rumbl.Video 

    timestamps 
    end 

    def changeset(model, params \\ :invalid) do 
    model 
    |> cast(params, ~w(name username), []) 
    |> validate_length(:username, min: 1, max: 20) 
    |> unique_constraint(:username) 
    end 

    def registration_changeset(model, params) do 
    model 
    |> changeset(params) 
    |> cast(params, ~w(password), []) 
    |> validate_length(:password, min: 6, max: 100) 
    |> put_pass_hash() 
    end 

    defp put_pass_hash(changeset) do 
    case changeset do 
     %Ecto.Changeset{valid?: true, changes: %{password: pass}} -> 
     put_change(changeset, :password_hash, Comeonin.Bcrypt.hashpwsalt(pass)) 
     _ -> changeset 
    end 
    end 
end 

そして最後にRumbl.Video

defmodule Rumbl.Video do 
    use Rumbl.Web, :model 

    schema "videos" do 
    field :url, :string 
    field :title, :string 
    field :description, :string 
    belongs_to :user, Rumbl.User 
    belongs_to :category, Rumbl.Category 

    timestamps() 
    end 

    @doc """ 
    Builds a changeset based on the `struct` and `params`. 
    """ 
    def changeset(struct, params \\ %{}) do 
    struct 
    |> cast(params, [:url, :title, :description], [:category_id]) 
    |> validate_required([:url, :title, :description]) 
    |> assoc_constraint(:category) 
    end 
end 

私はこのエラーがなぜ発生するのかを明らかにすることができる人に本当に感謝しています。

+0

'insert_user'をどのような引数で呼びますか? – Dogbert

+0

@Dogbert none、デフォルトのみ。 –

+0

どこかにあなたが渡している:videosキーは、ユーザーの作成時に無効です。あなたはそれを検索する必要があります。また、補足として、DictはMapを支持して非難されています。 – greggreg

答えて

1

それをすべて修正したものが実行中でしたmix do deps.clean --all, deps.get, deps.compile && mix test

+1

'' mix.exs'の 'エイリアス'に '' reset ':["deps.clean --all"、 "deps.get"、 "deps.compile"] 'を' ;) – Frost

1

問題は、あなたのチェンジである:

デフチェンジ(モデル、のparams \\:無効)

あなたのデフォルト値は:invalid原子で行います。私はまた、あなたが渡すことができると言うプログラミングフェニックスに従った:空または:無効な原子。しかし、:emptyはもう許可されていません。だから私も:invalidをテストしました。

問題が発生したときに、引数を渡さないと、invalidはエラーメッセージに表示されるように無効なチェンジセット全体を無効にします。

私の場合の解決策は、:invalid%{}に変更すると、変更セットのパラメータは空のマップになりますが、それでも有効です。そしてそれはあなたの挿入物の中で働くでしょう。

+0

残念ながら、それは正しくありません。 'TestHelpsers.insert_user'は、変更をparamsとしてregistration_changesetに送ります。これは、それをchangesetに渡します。つまり、paramsは常に以下のデータを持つ辞書になります: '%{name:" Some user "、パスワード:" supersecret "、username:" user "}'。 'has_many:videos'行を削除するとすべてうまく動作します。 –

+0

あなたのビデオをinsert_videoで追加した場合、それは機能しますか? –

+1

私は同様の問題を抱え、 ':invalid'の代わりに'%{} 'を使って解決しました。ありがとう! – cruppstahl

関連する問題