mix phx.gen.context Accounts Credential credentials email:string:unique password_hash:string user_id:references:users
mix phx.gen.html Multimedia Video videos user_id:references:users url:string title:string description:text
mix phx.gen.json
mix phx.gen.shema Multimedia.Category categories name:string
mix ecto.gen.migration add_category_id_to_video
If you find yourself always issuing the same set of commands in a project directory,
you can include them in a file called .iex.exs
.
for u <- Repo.preload(Repo.all(User), :credential) do
Repo.update!(User.registration_changeset(u, %{credential: %{email: "#{u.username}@example.com", password: "temppass"}}))
end
Rumbl.Repo.preload(video, :user)
Repo.one(from u in User, where: u.username == ^username)
Repo.one doesn’t mean “return the first result.” It means “one result is expected, so if there’s more, fail.
Repo.one from u in User,
select: count(u.id),
where: ilike(u.username, ^”j%”) or
ilike(u.username, ^”c%”)
users_count = from u in User, select: count(u.id)
j_users = from u in users_count, where: ilike(u.username, ^"%j%")
User
|> select([u], count(u.id))
|> where([u], ilike(u.username, ^"j%") or ilike(u.username, ^"c%"))
|> Repo.one()
from u in User, where: fragment(“lower(username) = ?”, ^String.downcase(name))
Ecto.Adapter.SQL.query(Repo, “SELECT power($1, $2), [2, 10])
–
From the query result, you can fetch all kinds of information, such as the returned columns,
the number of rows, and the result set itself.Preload associations directly as part of a query, like this:
video = Repo.one(from v in Video, limit: 1, preload: [:user])
From the query result, you can fetch all kinds of information, such as the returned columns, the number of rows, and the result set itself:
Repo.all from v in Video,
join: u in assoc(v, :user),
join: c in assoc(v, :category)
where: c.name == “Comedy”,
select: {u, v}
An explicit database constraint. This might be a uniqueness constraint on an index, or an integrity constraint between primary and foreign keys.
The Ecto.ConstraintError
, which you saw when we tried to add a category twice.
A constraint annotation added to the changeset that allows Ecto to convert constraint errors into changeset error messages.
Beautiful error messages for the consumption of humans.
Comeonin.Bcrypt.dummy_checkpw()
When a user isn’t found, we use comeonin’s dummy_checkpw()
function to simulate a password check with variable timing. This hardens our authentication
layer against timing attacks, which is crucial to keeping our application secure.
To solve the form_for coupling problem, we defined a protocol named Phoenix.HTML.FormData, which separates the interface from the implementation. Ecto.Changeset implements this protocol to convert its internal data to the structure required by Phoenix forms, all properly documented in the Phoenix.HTML.FormData contract.
Because the user is stored in conn.assigns.current_user
, it’s automatically available as
@current_user
in our views.