I am trying to allow users to select multiple resource_types. They have a many-to-many relationship with a Resource. My relationships all work, but I can’t see them at all in my Liveview template. Here is the code I’m using in the template:
<%= inputs_for f, :resource_types, fn i -> %>
<div class="form-group">
<%= label i, :resource_types, "Select a resource type:" %>
<%= multiple_select i, :resource_types, Enum.map(@all_resource_types, &{&1.type, &1.id}) %>
<%= error_tag i, :resource_types %>
</div>
<% end %>
I can’t see ANYTHING in that inputs_for. Not even the label “Select a resource type:” shows up on my form.
In reading Jose Valim’s article on Working with Ecto Associations and Embeds, I realized that my problem may be that my “update” function was creating an empty Resource changeset without the associations set. Really quickly, here’s the basic resource-resource_type relationship:
schema "resources" do
field :begin_datetime, :naive_datetime
field :delete_after_endtime, :boolean, default: false
field :description, :string
field :end_datetime, :naive_datetime
field :image_url, :string
field :is_event, :boolean, default: false
field :is_free, :boolean, default: false
field :is_private, :boolean, default: false
field :publish_date, :date
field :resource_url, :string
field :title, :string
field :usage_count, :integer
many_to_many :resource_types, Resourcetype, join_through: "join_resources_resourcetypes", on_delete: :delete_all
timestamps()
end
@doc false
def changeset(resource, attrs) do
resource
|> cast(attrs, [:title, :description, :image_url, :resource_url, :publish_date, :begin_datetime, :end_datetime, :is_event, :is_free, :is_private, :delete_after_endtime, :usage_count])
|> validate_required([:title, :description, :resource_url, :is_free])
|> unsafe_validate_unique(:resource_url, SketchLinks.Repo, message: "Resource with this url already exists.")
|> unique_constraint(:resource_url)
|> put_assoc(:resource_types, required: true)
end
So I updated my “update” function to put_assoc an empty resource_type in hopes that the form would finally display the inputs_for section in the template … but I still have nothing.
Update function code:
def update(%{resource: resource} = assigns, socket) do
changeset = Resources.change_resource(resource)
changeset = Ecto.Changeset.put_assoc(changeset, :resource_types, [%Resourcetype{}])
IO.puts "FormComponent UPDATE changeset"
IO.inspect changeset
IO.puts "Resource inside changeset"
IO.inspect changeset.data
# changeset = Resource.changeset(%Resource{resource_types: [%Resourcetype{}]})
{:ok,
socket
|> assign(assigns)
|> assign(changeset: changeset)
|> assign(all_resource_types: Resourcetypes.list_resource_types())
}
end
The output from those debug inspects show that I do have an empty changeset and the data inside the changeset (the Resource) does not have any resource_types set. But that is despite me setting an empty Resourcetype.
FormComponent UPDATE changeset
#Ecto.Changeset<
action: nil,
changes: %{},
errors: [
resource_types: {"is invalid", [type: {:array, :map}]},
title: {"can't be blank", [validation: :required]},
description: {"can't be blank", [validation: :required]},
resource_url: {"can't be blank", [validation: :required]}
],
data: #MyApp.Resources.Resource<>,
valid?: false
>
Resource inside changeset
%MyApp.Resources.Resource{
__meta__: #Ecto.Schema.Metadata<:built, "resources">,
begin_datetime: nil,
delete_after_endtime: false,
description: nil,
end_datetime: nil,
id: nil,
image_url: nil,
inserted_at: nil,
is_event: false,
is_free: false,
is_private: false,
publish_date: nil,
resource_types: #Ecto.Association.NotLoaded<association :resource_types is not loaded>,
resource_url: nil,
title: nil,
updated_at: nil,
usage_count: nil
}
I don’t know what else to try to get the input_for to work. Without that, I can’t allow the user to select resource_types. I also need to figure out how to show “pre-selected” types when I’m in edit mode.
How do I get inputs_for to work so that 1) a user can see the form and select resource types while setting up a new resource AND 2) a user can see pre-selected resource_types when doing an edit?