Programming Phoenix LiveView: pg 222(epub) invalid association `product` in schema Pento.Survey.Rating: associated schema Product does not exist lib/pento/survey/rating.ex:1: Pento.Survey.Rating (module)

(Phoenix 1.6.6, Ecto 3.7.2, Elixir 1.13)
When building the custom Survey context, we are told to then update the rating.ex file with the following:

  schema "ratings" do
    field :stars, :integer
    belongs_to :user, User
    belongs_to :product, Product
    timestamps()
  end

then, to update our changeset

  def changeset(rating, attrs) do
    rating
    |> cast(attrs, [:stars, :user_id, :product_id])
    |> validate_required([:stars, :user_id, :product_id])
    |> validate_inclusion(:stars, 1..5)
    |> unique_constraint(:product_id, name: :index_ratings_on_user_product)
  end

After, we then update demographic.ex with similar changes, we are told to mix.ecto.migrate - but I get this error:

Compiling 2 files (.ex)
warning: invalid association `product` in schema Pento.Survey.Rating: associated schema Product does not exist
  lib/pento/survey/rating.ex:1: Pento.Survey.Rating (module)

However, the requisite migration files etc. are still updated.
Creating a Survey rating in IEX works but shows these curious AssociationNotLoaded entries for Product & User:

 %Pento.Survey.Rating{
   __meta__: #Ecto.Schema.Metadata<:loaded, "ratings">,
   id: 1,
   inserted_at: ~N[2022-04-13 18:57:09],
   product: #Ecto.Association.NotLoaded<association :product is not loaded>,
   product_id: 1,
   stars: 5,
   updated_at: ~N[2022-04-13 18:57:09],
   user: #Ecto.Association.NotLoaded<association :user is not loaded>,
   user_id: 1
 }}

All seems fine until you create the the query.ex for Demographic & then spin it in IEX , which never finds the “user function” (Survey.get_demographic_by_user).

iex(2)> Survey.get_demographic_by_user(user)
** (CompileError) iex:2: undefined function user/0 (there is no such import)

If you try to proceed further anyways by use the Catalog.list_products_with_user_rating function in IEX, we get this error:

Catalog.list_products_with_user_rating(user)
** (UndefinedFunctionError) function Pento.Survey.Rating.Query.preload_user/1 is undefined (module Pento.Survey.Rating.Query is not available)
    Pento.Survey.Rating.Query.preload_user(#Pento.Accounts.User<__meta__: #Ecto.Schema.Metadata<:loaded, "users">, confirmed_at: nil, email: "mercutio@grox.io", id: 1, inserted_at: ~N[2022-04-08 22:24:37], updated_at: ~N[2022-04-08 22:24:37], username: nil, ...>)
    lib/pento/catalog/product/query.ex:15: Pento.Catalog.Product.Query.preload_user_ratings/2
    (pento 0.1.0) lib/pento/catalog.ex:106: Pento.Catalog.list_products_with_user_rating/1

It seems that the User & Product schemas relating to the belong_to are not being recognized in the Rating schema (?)

Is there a piece to this puzzle I’m missing? Everything up until this point in the book has gone off without a hitch with no errors & the Product & User schemas definitely exist.

I even tried switching the ordering of product & user in the belong_to in Rating schema to see if that helped, but got the same error but in reverse:

Compiling 2 files (.ex)
warning: invalid association `user` in schema Pento.Survey.Rating: associated schema User does not exist
  lib/pento/survey/rating.ex:1: Pento.Survey.Rating (module)

Any help to move past this would be great, as I am currently roadblocked - otherwise an excellent book! Thank you

UPDATE: This was fixed by:

  • Deleting ratings table & rating.ex file

  • Re-running context gen command for Rating

  • Updating the schema in rating.ex to the following:

belongs_to: :user, Pento.Accounts.User
belongs_to: :product, Pento.Catalog.Product
  • Update changeset along with the book

  • Re-run mix ecto.migrate

  • Keep all other files i.e. demographics etc. the same

Now all associations are loaded in survey/query & product/query correctly.
I’m not sure why the association has to be explicit in this case, but I’m finally to be free from the roadblock - FYI if you happen to see anything like this in future, Sophie/Bruce and all other readers.

Is it possible that you didn’t provide the appropriate aliases in your Rating module? You should have the following like this:

defmodule Pento.Survey.Rating do
 # ...
  alias Pento.Catalog.Product
  alias Pento.Accounts.User
# ...

We may have neglected to call that out specifically in prose, I’ll review and add if need be.

I had a similar issue with below error message.

** (ArgumentError) schema Pento.Catalog.Product does not have association or embed :ratings
    (elixir 1.14.3) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3
    (ecto 3.10.1) lib/ecto/repo/queryable.ex:235: Ecto.Repo.Queryable.execute/4
    (ecto 3.10.1) lib/ecto/repo/queryable.ex:19: Ecto.Repo.Queryable.all/3
    iex:37: (file)

Redoing the migration didn’t work.
I read elsewhere that restarting iex -S mix could get rid of these issues and it worked.

It seems the interactive mode doesn’t pick up the changes when running while contexts, schemas and migrations are created, even though recompile is executed.
Restarting iex -S mix fixed my issue.