Understanding Ecto query writing
If we go back and look at the list_poll() function that we just wrote, you can see that we have the Repo.all/1 query and that it gets passed into a Repo.preload/1 statement. Without really understanding what's going on here, this is all just going to feel a bit like magic. Nothing in Elixir should ever just be reduced to magic, so let's take a peek behind the curtains, so to speak.
In this case, when we call Repo.all, we're just passing it the name of the schema. If we run h Vocial.Repo.all in our IEx terminal, we'll see something like the following:
iex(2)> h Vocial.Repo.all
@callback all(queryable :: Ecto.Query.t(), opts :: Keyword.t()) :: [Ecto.Schema.t()] | no_return()
Fetches all entries from the data store matching the given query.
May raise Ecto.QueryError if query validation fails.
## Options
? :prefix - The prefix to run the query on (such as the schema path in
Postgres or the database in MySQL). This overrides the prefix set in the
query.
See the "Shared options" section at the module documentation.
## Example
# Fetch all post titles
query = from p in Post,
select: p.title
MyRepo.all(query)
Based on the documentation, we can see that the first argument that we pass in is something that is queryable. In our case, the schema name is queryable, so Ecto will convert Repo.all(Poll) into:
Repo.all(from p in Poll)
Returning back to our IEx terminal, let's verify the behavior here:
iex(5)> Repo.all(Poll)
[debug] QUERY OK source="polls" db=12.3ms
SELECT p0."id", p0."title", p0."user_id", p0."inserted_at", p0."updated_at" FROM "polls" AS p0 []
[]
We expect this to be the same as the longer form of writing out this query. If you've ever seen anything like LINQ syntax before, this is pretty similar:
iex(7)> Repo.all(from p in Poll)
[debug] QUERY OK source="polls" db=10.3ms
SELECT p0."id", p0."title", p0."user_id", p0."inserted_at", p0."updated_at" FROM "polls" AS p0 []
[]
You can see here that we get an identical query when we write out the query itself. We write it out as "from (alias) in (schema)". We could expand on this, as well. For example, let's say we want to include a where clause in our query:
iex(8)> Repo.all(from p in Poll, where: p.title == "Hello")
[debug] QUERY OK source="polls" db=34.9ms
SELECT p0."id", p0."title", p0."user_id", p0."inserted_at", p0."updated_at" FROM "polls" AS p0 WHERE (p0."title" = 'Hello') []
[]
If you want to learn more about Ecto query construction, you can type in h Ecto.Query at any point in your IEx shell to learn a lot more about query construction!