Search code examples
elixirphoenix-frameworkectomultiple-selectchangeset

Post a form with belongs_to association elixir


I need create a User with many roles, so I follow these steps:

I created two models, the schemas are :

schema "roles" do
  field :name, :string
  belongs_to :user, Module.User

  timestamps()
end           

schema "users" do
  field :name, :string
  field :cnpj, :string
  has_many :roles, Module.Role

  timestamps()                                       
end

I am trying create a form to create a user with any roles, but unsucessful.

My create controller action looks like:

def create(conn, %{"user" => user_params}) do
  changeset = User.changeset(%User{},user_params)                            

  case Repo.insert(changeset) do
  ...

In my form to create User, I have added a field to multiple_select roles, but its generating a invalid changeset

<%= inputs_for f, :roles, fn i -> %>
  <div class="form-group">
    <%= label i, :name, gettext("Roles"), class: "control-label" %>
    <%= multiple_select(i, :name, ["Admin": "1", "User": "2", "Power": "3"]) %>
  </div>
<% end %>

The generated changeset with errors:

#Ecto.Changeset<action: :insert, changes: %{cnpj: "01578216908926", roles: [#Ecto.Changeset<action: :insert, changes: %{}, errors: [name: {"is invalid", [type: :string]}], data: #Module.Role<>, valid?: false>], name: "xxx"}, errors: [], data: #Module.User<>, valid?: false>

Is there any way to create it, or I'm going the wrong way?


Solution

  • You are creating one Role model where name is a List instead of few Role models each with String name. That is why there is an error (List instead of String for field name).

    Maybe you do not need a separate model for user roles an one additional filed (list of strings) in User model would be fine:

    schema "users" do
      field :name, :string
      field :cnpj, :string
      field :roles, {:array, :string}
    
      timestamps()                     
    end