akrisanov
9/11/2018 - 10:07 AM

Phoenix Random Notes

Generators & IEx

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.

Ecto

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()
  • Ecto Fragments: from u in User, where: fragment(“lower(username) = ?”, ^String.downcase(name))
  • Ecto Query: 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}

Constraint

An explicit database constraint. This might be a uniqueness constraint on an index, or an integrity constraint between primary and foreign keys.

Constraint error

The Ecto.ConstraintError, which you saw when we tried to add a category twice.

Changeset constraint

A constraint annotation added to the changeset that allows Ecto to convert constraint errors into changeset error messages.

Changeset error messages

Beautiful error messages for the consumption of humans.

Auth

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.

Helpers

  • Phoenix.HTML – helpers like link, submit button

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.