montogeek

montogeek

Hi!

I ran the following command to create a resource:

mix phx.gen.html Main Activity activities name:string datetime_start:datetime datetime_end:datetime category_id:references:categories mood_id:references:moods

After some search I discovered that the inputs for the associations are not created automatically, so I tried to do it, for that I did:

  • Edit activity.ex schema and added:
+belongs_to :category, Categories
+belongs_to :mood, Moods
-field :category_id, :id
-field :mood_id, :id

Then I used the Main context functions to retrieve all categories and moods and pass it to the new.html form:

changeset = Main.change_activity(%Activity{})
+categories = Main.list_categories() |> Enum.map(fn c -> {c.name, c.id} end)
+moods = Main.list_moods() |> Enum.map(fn m -> {m.name, m.id} end)

+render(conn, "new.html", changeset: changeset, moods: moods, categories: categories)
+<%= label f, :category %>
+<%= select f, :category, @categories, prompt: "Choose" %>
+<%= error_tag f, :category %>
+
+<%= label f, :mood %>
+<%= select f, :mood, @moods, prompt: "Choose" %>
+<%= error_tag f, :mood %>

But when loading the page in the browser I get this error:

protocol Phoenix.HTML.Safe not implemented for #Ecto.Association.NotLoaded<association :category is not loaded> of type Ecto.Association.NotLoaded (a struct). This protocol is implemented for the following type(s): Decimal, Phoenix.LiveComponent.CID, Phoenix.LiveView.Component, Phoenix.LiveView.Comprehension, Phoenix.LiveView.JS, Phoenix.LiveView.Rendered, Time, Integer, Tuple, List, DateTime, NaiveDateTime, Float, Atom, Phoenix.HTML.Form, BitString, Date

What I am doing wrong?

Thanks!

Showing Posts 1 to 6

montogeek

montogeek OP

After looking for information about this error, I edited the Main.change_activity function:

def change_activity(%Activity{} = activity, attrs \\ %{}) do
Activity.changeset(activity, attrs)                                                                                                                         
+ |> Repo.preload(:category)
end

Now I get this error:

UndefinedFunctionError at GET /activities/new
function Ecto.Changeset.__schema__/2 is undefined or private
montogeek

montogeek OP

It seems that Phoenix is doing an internal mapping with the fields in the form, after renaming the field from category to category_id, the form loads correctly.

But I think this will break something when editing/showing/updating the entities.

What is the recommended way to do this?

montogeek

montogeek OP

I added to the changeset function the validation for the Category and Mood inputs:

+|> assoc_constraint(:category, name: :category_id)
+|> assoc_constraint(:mood, name: :mood_id)

But I am afraid it is not working since the values are being inserted in the database with NULL values.

montogeek

montogeek OP

I managed to save it with the correct values after adding category_id and mood_id to the cast function!

I edited the Main get_activity function to preload the relationships:

def get_activity!(id) do 
  Repo.get!(Activity, id) 
+ |> Repo.preload([:category, :mood])
end

After inspecting the object when showing it I get this:

%Main.Activity{
  __meta__: #Ecto.Schema.Metadata<:loaded, "activities">,
  category: %Flytte.Main.Categories{
    __meta__: #Ecto.Schema.Metadata<:loaded, "categories">,
    activities: #Ecto.Association.NotLoaded<association :activities is not loaded>,
    color: "#000000",
    id: 2,
    inserted_at: ~N[2022-01-01 19:39:45],
    name: "Sleep",
    updated_at: ~N[2022-01-01 19:39:45]
  },
  category_id: 2,
  datetime_end: ~N[2017-01-01 00:00:00],
  datetime_start: ~N[2017-01-01 00:00:00],
  id: 8,
  inserted_at: ~N[2022-01-01 22:15:28],
  mood: %Flytte.Main.Moods{
    __meta__: #Ecto.Schema.Metadata<:loaded, "moods">,
    activities: #Ecto.Association.NotLoaded<association :activities is not loaded>,
    emoji: ":)",
    id: 2,
    inserted_at: ~N[2022-01-01 19:43:52],
    name: "Fine",
    updated_at: ~N[2022-01-01 19:43:52]
  },
  mood_id: 2,
  name: "Test5",
  updated_at: ~N[2022-01-01 22:15:28]
}

Please note that there is a category but also category_id, It this ok, to have these 2 values there? Shouldn’t it be only one?

dimitarvp

dimitarvp

It is, that’s an implementation details of many ORM / data-mapper libraries. It’s quite fine.

stefanchrobot

stefanchrobot

That’s how Ecto works. Whenever you add an association, you’ll get both fields. This works nicely with preloads:

post = Repo.get(Post, 123) |> Repo.preload([:author, :topic])
# You can now access the associated data
foo = post.author.name
— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New

Latest on Elixir Forum

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews