phoenixframework / phoenix

Peace of mind from prototype to production
https://www.phoenixframework.org
MIT License
21.44k stars 2.88k forks source link

** (CompileError) iex: undefined function from/2, inadequate error message #1665

Closed thedanotto closed 8 years ago

thedanotto commented 8 years ago

Hi, new to elixir and phoenix. I watched videos on elixir and phoenix and noted both creators said that inadequate error messages is a bug. As a relative beginner, I believe the error message I experienced left me in the dark.

Here's how it went... I created a phoenix app, created the database, created a model/scaffold by running a phoenix generator, added the routes, created the migration, ran the server, added some data, I opened the interactive elixir shell with $ iex -S mix

I then ran the query

iex(1)> BlogPhoenix.Repo.all(
...(1)>   from p in BlogPhoenix.Post,
...(1)>   select: p)

and received this error...

** (CompileError) iex:2: undefined function from/2

I found that error, to be unhelpful, that could be due to a lack of understanding of elixir, of course. I eventually found the answer by reading blog posts about querying in Ecto and Elixir, it took a long time to solve. A couple questions,

1) Where would I put import Ecto.query within my application to not experience this error?

2) why is this not input by default when I run a phoenix generator? Because in my head I think, of course, when I have a model I want to query it, so I'm not sure why this seemingly essential line of code isn't input into my models by default, especially if I run a generator.

Expected behavior

Run phoenix generator, be able to query the model out of the box.

Actual behavior

Ran phoenix generator, needed additional code to be able to query and did not receive a highly specific error message.

Environment

chrismccord commented 8 years ago

Hi, new to elixir and phoenix.

Greetings!

both creators said that inadequate error messages is a bug

Accurate statement :) but...

...unfortunately in this case, the error message can't be helped because Ecto.Query has not been imported, unless Elixir's compiler could walk beams and look for any module that exposes a from/2 function, but since it's at compile time, it can be a chicken/egg problem because we don't necessarily have beams to crawl if we can't compile.

1) Where would I put import Ecto.query within my application to not experience this error?

In Elixir, imports are lexically scoped, and you cannot use global imports to make from available any place in the app. You must explicitly import Ecto.Query where you'd like to use the functions within it. If you look in web.ex in your application, Phoenix does indeed import Ecto.Query when you use MyApp.Web, :controller/:channel/etc, but we can't import things globally or into iex. You could define a .iex.exs file which contains import Ecto.Query, which would save you from typing it in iex, but it also breaks normal iex shells, so you must always run iex -S mix when it in the app directory.

2) why is this not input by default when I run a phoenix generator? Because in my head I think, of course, when I have a model I want to query it, so I'm not sure why this seemingly essential line of code isn't input into my models by default, especially if I run a generator.

As I mentioned in 1, we do include convenience imports of Ecto.Query so you don't constantly have to import it in all controllers or channels, but in Elixir in general, we favor being explicit with our code, be it module imports, aliases, configuration, etc. Once you get used to this idea, the slight increase in keystrokes is far exceeded by having an immediate overview of what functions are available in your file, and what aliases exist.

Hope that helps and welcome aboard! Hop on elixir-lang irc if you'd like to chat more about this. Thanks!

thedanotto commented 8 years ago

Thanks for your high quality response. It makes sense now!

backiya-priska commented 5 years ago

** (CompileError) lib/phoenix_trello_web/views/layout_view.ex:12: undefined function static_path/2