kayne
kayne

Reputation: 349

Ecto filter empty record

I have an embedded association with two models: User and Address, and I connect them like this:

defmodule App.Address do
  # ...

  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, [:address, :city])
  end
end

when I use:

 inputs_for :addresses, [append: [App.Address{}]], fn address ->
   text_input address, :address, class: ""
 end

and I enter empty data, it gets saved as nil, I'm hoping for a solution to filter out empty data and prevent them from getting saved, all I came up with is using Enum.filter in the controller which gets ugly as I think:

...
filtered_addresses = Enum.filter(user_params["addresses"], fn {x, map} ->
  map.address != "" and map.city != ""
end)

user_params = Map.put(user_params, :addresses, filtered_addresses)

is there is a more cleaner way using the model validations, or a cleaner way in the controller?

Upvotes: 3

Views: 900

Answers (2)

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121010

If I understood the question properly, you might be looking for Phoenix.Controller.scrub_params/2.

From the documentation linked above:

This function is useful to remove empty strings sent via HTML forms.

Also, this SO question seems to be similar to your question, but the goal is the opposite. Linking it here for the sake of hypertext.

Upvotes: 0

Justin Wood
Justin Wood

Reputation: 10061

You are going to want validations on the changeset. Something along the lines of

def changeset(struct, params \\ %{}) do
  struct
  |> cast(params, [:address, :city])
  |> validate_required([:address, :city])
end

This will make sure there is data in the columns address and city. If there is not, the record will not be saved.

You can read more about validations and constraints in the docs

Upvotes: 0

Related Questions