2017-06-21 11 views
1

をプリロードスローを保つ私はここにいくつかの関連のコードが表示されますが、あなたは完全なコードが必要な場合、あなたはGitHubの上でそれを見つけることができます:https://github.com/maple-leaf/phoenix_todoフェニックス:has_manyのにモデルを投稿エラー

user_model:

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

    @derive {Poison.Encoder, only: [:name, :email, :bio, :todos]} 

    schema "users" do 
    field :name, :string 
    field :age, :integer 
    field :email, :string 
    field :bio, :string 

    has_many :todos, PhoenixTodo.Todo 

    timestamps() 
    end 

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

todo_model:

defmodule PhoenixTodo.Todo do 
    use PhoenixTodo.Web, :model 

    @derive {Poison.Encoder, only: [:title, :content]} 

    schema "todos" do 
    field :title, :string 
    field :content, :string 

    belongs_to :user, PhoenixTodo.User 

    timestamps() 
    end 

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

user_controller:

defmodule PhoenixTodo.UserController do 
    use PhoenixTodo.Web, :controller 

    alias PhoenixTodo.User 

    def index(conn, _params) do 
     json(conn, User |> Repo.all() |> Repo.preload(:todos)) 
    end 

    def show(conn, %{"id" => id}) do 
     json(conn, User|> Repo.get(id) |> Repo.preload(:todos)) 
    end 

    def create(conn, data) do 
     user = User.changeset(%User{}, data) 
     #user = User.changeset(%User{}, %{name: "xxx", todos: [%PhoenixTodo.Todo{}]}) 
     json conn, user 
    end 
end 

:index:showからすべてのユーザーまたはクエリを取得できますが、:createは常に約associationというエラーを発生させます。

リクエストで:curl -H "Content-Type: application/json" -X POST -d '{"name": "abc"}' http://localhost:4000/api/users

エラーは次のように提起:cannot encode association :todos from PhoenixTodo.User to JSON because the association was not loaded. Please make sure you have preloaded the association or remove it from the data to be encoded

:todosとき:createをプリロードする方法は?また、ユーザー作成時にtodosは必須フィールドではありませんが、その関連付けは無視できますか?

+0

あなたは 'Repo.insert'を忘れましたか?チェンジセットを作成しても、ユーザーはデータベースに挿入されません。 – Dogbert

+0

@Dogbert私はそれが 'Repo.insert'によって引き起こされたものではないと思います。しかし、私はそれをjsonを返す前に追加し、同じエラーが発生しました。そして、 ':create'のコードは' user = User.changeset(%User {}、data)Repo.insert(user)json conn user'のようになります。 – tjfdfs

+0

はい、あなたが理解したように、チェンジセットではなく、 'Repo.insert'を' json'に追加しました。 – Dogbert

答えて

0

最後に、私はそれを動作させる。

これは、json conn userが重要であることが判明しました。 jsonは、Ecto.ChangesetEcto.Modelではなく、changesetでエンコードするようにPoisonと呼びます。したがって、Ecto.Modelをjsonに渡す必要があります。

ここで私はそれをやっています。

user = User.changeset(%User{}, data) 
IO.inspect user # Ecto.Changeset 
{:ok, u1} = Repo.insert(user) 
IO.inspect u1 # Model!! 
json conn, u1 |> Repo.preload(:todos) # now we can successfully preload :todos 
関連する問題