Kyle Decot
Kyle Decot

Reputation: 20835

How to create changeset for nested resource w/ Ecto/Phoenix

I have a nested resource in my Phoenix application for which I'm trying to create a changeset. The problem is that Ecto.build_assoc expects the map to have atom keys but my params have string keys. What is the proper way to create a changeset for a nested resource?

def create(conn, %{"component" => component_params}, generator) do
  changeset = Ecto.build_assoc(generator, :components, component_params) # attributes don't get set
  ...
end

Upvotes: 2

Views: 1262

Answers (1)

naserca
naserca

Reputation: 378

Calling your changeset function will, if written conventionally, will handle the casting you're looking for using Ecto.Changeset.Cast/4.

Phoenix/Ecto intentionally distrust raw user input. Changesets are the "Ecto way" to handle this.

Here's a more conventional way to handle the operation your going for in your controller:

def create(conn, %{"component" => component_params}, generator) do
  changeset =
    generator
    |> Ecto.build_assoc(:components)
    |> Component.changeset(component_params)
  ...
end

Given that you have something like this in component.ex:

def changeset(model, params \\ :empty) do
  model
  |> cast(params, @required_fields, @optional_fields)
end

Upvotes: 3

Related Questions