How can I tell ecto that I don’t need an association. I have a user schema that has 2 associations
schema "users" do
field :email, :string
field :first_name, :string
field :last_name, :string
field :password, :string, virtual: true
field :hashed_password, :string
field :confirmed_at, :naive_datetime
belongs_to :space, Space
many_to_many :apps, App, join_through: "app_user", on_replace: :delete
timestamps()
end
When I try to list users
def list_space_users(space_id) do
query =
from u in User,
where: u.space_id == ^space_id,
select: u
Repo.all(query)
end
I get an association not loaded error.
#Ecto.Association.NotLoaded<association :space is not loaded>
I know I can preload the association but in my case it’s not needed I just want the user schema without its associations.
This is not an error, it’s a special struct Ecto puts in the field as a placeholder. If you don’t need it, as long as you don’t access the field it shouldn’t create any problems.
def index(conn, _params) do
space_id = conn.assigns.current_user.space_id
case Oriio.Accounts.list_space_users(space_id) do
{:ok, users} ->
conn
|> put_status(:ok)
|> put_view(OriioWeb.UserView)
|> render("users.json", users: users)
{:error, changeset} ->
conn
|> put_status(:bad_request)
|> put_view(OriioWeb.ChangesetView)
|> render(:error, changeset: changeset)
end
end
The full error message though is.
no case clause matching: [#Oriio.Accounts.User<__meta__: #Ecto.Schema.Metadata<:loaded, "users">, apps: #Ecto.Association.NotLoaded<association :apps is not loaded>, confirmed_at: nil, email: "myemail@gmail.com", first_name: "updated", hashed_password: "$2b$12$hzqAJIzNTsKwvbfNkh8L7eNyjG/CLJRCGU7gpMcrBOyVyiufqGYx6", id: 3, inserted_at: ~N[2020-09-17 21:55:39], last_name: "updated", space: #Ecto.Association.NotLoaded<association :space is not loaded>, space_id: 25, updated_at: ~N[2020-10-08 20:30:56], ...>]
The true issue is {:ok, users} clause in the controller it should just be users.
I just skimmed through the error message and saw #Ecto.Association.NotLoaded<association :space is not . Automatically interpretted that as the main issue(I’m new to elixir). Instead I should just have read the first sentence of the error (no case clause matching) and everything would have made sense lol.
Thank you!! I have to say I’ve been learning Elixir now for about 3 weeks and the community has been amazing. Every time I post a question here I always get help and the responses are informative. As a total side note it would be nice if an IDE or even better the compiler could catch things like that . Do you have a list of editors/plugins you would recommend?
Yes I have found the community around Elixir to be excellent. I would really recommend the slack channel if you’re just getting started for even quicker help
Well, there is quite a bit of interest in a statically typed Elixir variant, which I think is what you would need for the compiler to catch that kind of thing, though I’m not sure. You can find various threads aroudn the forum on that issue. Otherwise, typespecs with dialyzer can help a lot.
I waited a while to get into typespecs after learning Elixir and I wish I had started earlier. They really are incredibly helpful for catching silly problems early, getting ahead on documentation, and refactoring more often.
One option: Dialyzer can help find errors like this one, where you have a function that returns a list() but a case that’s trying to match {:ok, list()}. I hear the VSCode / ElixirLS combo is a good IDE-ish experience.
Thank you! I’m gonna give it a try. I had come across Dialyzer but most ppl have iffy feeling about it so I wasn’t sure how idiomatic it was to use. WhatsApp announced they have a typed version of erlang coming out this November so that’s something exciting to keep an eye on. Slides from the talk