Skip to content
This repository was archived by the owner on Sep 5, 2018. It is now read-only.
4 changes: 2 additions & 2 deletions A_up_and_running.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,6 @@ By default Phoenix accepts requests on port 4000. If we point our favorite web b

If your screen looks like the image above, congratulations! You now have a working Phoenix application. In case you can't see the page above, try accessing it via [http://127.0.0.1:4000](http://127.0.0.1:4000) and later make sure your OS has defined "localhost" as "127.0.0.1".

Locally, our application is running in an iex session. To stop it, we hit ctrl-c twice, just as we would to stop iex normally.
Locally, our application is running in an `iex` session. To stop it, we hit `ctrl-c` twice, just as we would to stop `iex` normally.

The next step is customizing our application just a bit to give us a sense of how a Phoenix app is put together.
The [The next step step](http://www.phoenixframework.org/docs/adding-pages) is customizing our application just a bit to give us a sense of how a Phoenix app is put together.
2 changes: 1 addition & 1 deletion C_routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ page_path GET / HelloPhoenix.PageController :index
```
The output tells us that any HTTP GET request for the root of the application will be handled by the `index` action of the `HelloPhoenix.PageController`.

`page_path` is an example of a what Phoenix calls a path helper, and we'll talk about those very soon.
`page_path` is an example of what Phoenix calls a path helper, and we'll talk about those very soon.

### Resources

Expand Down
2 changes: 1 addition & 1 deletion D_controllers.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Phoenix controllers act as intermediary modules. Their functions - called actions - are invoked from the router in response to HTTP requests. The actions, in turn, gather all the necessary data and perform all the necessary steps before invoking the view layer to render a template or returning a JSON response.

Phoenix controllers also build on the Plug package, and are themselves plugs. Controllers provide the functions to do almost anything we need to in an action. If we do find ourselves looking for something that Phoenix controllers don't provide, however, we might find what we're looking for in Plug itself. Please see the [Plug Guide](http://www.phoenixframework.org/docs/understanding-plug) or [Plug Documentation](http://hexdocs.pm/plug/) for more information.
Phoenix controllers also build on the Plug package, and are themselves plugs. Controllers provide the functions to do almost anything we need to in an action. If we do find ourselves looking for something that Phoenix controllers don't provide; however, we might find what we're looking for in Plug itself. Please see the [Plug Guide](http://www.phoenixframework.org/docs/understanding-plug) or [Plug Documentation](http://hexdocs.pm/plug/) for more information.

A newly generated Phoenix app will have a single controller, the `PageController`, which can be found at `web/controllers/page_controller.ex` and looks like this.

Expand Down
6 changes: 3 additions & 3 deletions H_ecto_models.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ def changeset(model, params \\ :empty) do
end
```

At this point, we only have one transformation in our pipeline. This `cast/4` function's main job is to separate required fields from optional ones. We define the fields for each category in the module attributes `@required_fields` and `@optional_fields`. By default all of the fields are required.
At this point, we only have one transformation in our pipeline. This `cast/3` function's main job is to separate required fields from optional ones. We define the fields for each category in the module attributes `@required_fields` and `@optional_fields`. By default all of the fields are required.

Let's take a look at two ways to validate that this is the case. The first and easiest way is to simply start our application by running the `mix phoenix.server` task at the root of our project. Then we can go to the [new users page](http://localhost:4000/users/new) and click the "submit" button without filling in any fields. We should get an error telling us that something went wrong and enumerating all the fields which can't be blank. That should be all the fields in our schema at this point.

Expand Down Expand Up @@ -593,12 +593,12 @@ We can use our newly declared relationships in our `web/controllers/user_control
defmodule HelloPhoenix.UserController do
. . .
def index(conn, _params) do
users = User |> Repo.all |> Repo.preload [:videos]
users = User |> Repo.all |> Repo.preload([:videos])
render(conn, "index.html", users: users)
end

def show(conn, %{"id" => id}) do
user = User |> Repo.get!(id) |> Repo.preload [:videos]
user = User |> Repo.get!(id) |> Repo.preload([:videos])
render(conn, "show.html", user: user)
end
. . .
Expand Down
4 changes: 2 additions & 2 deletions bonus_guides/D_mix_tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ $ mix ecto.create
** (Mix) The database for HelloPhoenix.Repo couldn't be created, reason given: psql: FATAL: role "postgres" does not exist
```

We can fix this by creating the "postgres" role with the permissions needed to log in and create a database.
We can fix this by creating the "postgres" role in the `psql` console with the permissions needed to log in and create a database.

```console
=# CREATE ROLE postgres LOGIN CREATEDB;
Expand Down Expand Up @@ -536,7 +536,7 @@ $ mix ecto.create
** (Mix) The database for HelloPhoenix.Repo couldn't be created, reason given: ERROR: permission denied to create database
```

To fix this, we need to change the permissions on our "postgres" user to allow database creation.
To fix this, we need to change the permissions on our "postgres" user in the `psql` console to allow database creation.

```console
=# ALTER ROLE postgres CREATEDB;
Expand Down
2 changes: 1 addition & 1 deletion bonus_guides/G_static_assets.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ Important detail: according to the default configuration there is no ES6 support

#### JavaScript Libraries

We may need to use a JavaScript library like jQuery or underscore in our application. As we mentioned above, we could copy the libraries into `web/static/vendor`. It may be a little bit easier to use `npm` to install it: We can simply add `"jquery": ">= 2.1"` to the dependencies in the `package.json` file in our projects root and run `npm install --save`. Now we can `import $ from "jquery"` in our `app.js`.
We may need to use a JavaScript library like jQuery or underscore in our application. As we mentioned above, we could copy the libraries into `web/static/vendor`. It may be a little bit easier to use `npm` to install it: We can simply add `"jquery": ">= 2.1"` to the dependencies in the `package.json` file in our projects root and run `npm install --save`. If the `npm` section in our `brunch-config.js` has a `whitelist` property, we will also need to add "jquery" to that. Now we can `import $ from "jquery"` in our `app.js`.

#### Brunch Plugin Pipeline

Expand Down
2 changes: 1 addition & 1 deletion bonus_guides/I_sending_email.md
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ We'll also need a new `email` directory in `web/templates` with a `welcome.html.
> Note: If we need to use any path or url helpers in our template, we will need to pass the endpoint instead of a connection struct for the first argument. This is because we won't be in the context of a request, so `@conn` won't be available. For example, we will need to write this
```elixir
alias HelloPhoenix
Router.Helpers.page_path(Endpoint, :index)
Router.Helpers.page_url(Endpoint, :index)
```
instead of this.
```elixir
Expand Down
14 changes: 14 additions & 0 deletions bonus_guides/P_using_ssl.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,17 @@ Without the `otp_app:` key, we need to provide absolute paths to the files where
```elixir
Path.expand("../../../some/path/to/ssl/key.pem", __DIR__)
```

Releasing with Exrm:

In order to build and run a release with exrm, make sure you also include the ssl app in `mix.exs`:

```elixir
def application do
[mod: {HelloPhoenix, []},
applications: [:phoenix, :phoenix_html, :cowboy, :logger, :gettext,
:phoenix_ecto, :postgrex, :ssl]]
end
```

Else you might run into errors: `** (MatchError) no match of right hand side value: {:error, {:ssl, {'no such file or directory', 'ssl.app'}}}`
13 changes: 11 additions & 2 deletions deployment/E_heroku.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ config :hello_phoenix, HelloPhoenix.Repo,
ssl: true
```

Finally, we need to decrease the timeout for the websocket transport:
Finally, we need to decrease the timeout for the websocket transport in `web/channels/user_socket.ex`:

```elixir
defmodule HelloPhoenix.UserSocket do
Expand All @@ -169,6 +169,13 @@ end

This ensures that any idle connections are closed by Phoenix before they reach Heroku's 55 second timeout window.

Lastly, we'll need to create a [Procfile](https://devcenter.heroku.com/articles/procfile) with the following:

```
web: MIX_ENV=prod mix phoenix.server

```

## Creating Environment Variables in Heroku

The `DATABASE_URL` config var is automatically created by Heroku when we add the [Heroku Postgres add-on](https://elements.heroku.com/addons/heroku-postgresql). We can create the database via the heroku toolbelt:
Expand All @@ -194,6 +201,8 @@ Setting config vars and restarting mysterious-meadow-6277... done, v3
SECRET_KEY_BASE: xvafzY4y01jYuzLm3ecJqo008dVnU3CN4f+MamNd1Zue4pXvfvUjbiXT8akaIF53
```

If you need to make any of your config variables available at compile time you will need to explicitly define which ones in a configuration file. Create a file `elixir_buildpack.config` in your applications root directory and add a line like: `config_vars_to_export=(DATABASE_URL MY_VAR)`. See [here](https://github.com/HashNuke/heroku-buildpack-elixir#specifying-config-vars-to-export-at-compile-time) for more information.

## Deploy Time!

Our project is now ready to be deployed on Heroku.
Expand Down Expand Up @@ -282,7 +291,7 @@ remote: -----> Finalizing build
remote: Creating runtime environment
remote:
remote: -----> Discovering process types
remote: Procfile declares types -> (none)
remote: Procfile declares types -> (web)
remote: Default types for Multipack -> web
remote:
remote: -----> Compressing... done, 82.1MB
Expand Down
11 changes: 7 additions & 4 deletions deployment/I_exrm_releases.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Let's separate our release process into a few tasks so we can keep track of wher

## Add exrm as a Dependency

To get started, we'll need to add `{:exrm, "~> 0.19.9"}` into the list of dependencies in our `mix.exs` file.
To get started, we'll need to add `{:exrm, "~> 1.0"}` into the list of dependencies in our `mix.exs` file.

```elixir
defp deps do
Expand All @@ -34,7 +34,7 @@ To get started, we'll need to add `{:exrm, "~> 0.19.9"}` into the list of depend
{:phoenix_html, "~> 2.3"},
{:phoenix_live_reload, "~> 1.0", only: :dev},
{:cowboy, "~> 1.0"},
{:exrm, "~> 0.19.9"}]
{:exrm, "~> 1.0"}]
end
```

Expand Down Expand Up @@ -65,19 +65,22 @@ Doing this helps us overcome one of [exrm's common issues](https://hexdocs.pm/ex

Even if we list all of our dependencies, our application may still fail. Typically, this happens because one of our dependencies does not properly list its own dependencies. A quick fix for this is to include the missing dependency or dependencies in our list of applications. If this happens to you, and you feel like helping the community, you can create an issue or a pull request to that project's repo.

We also need to configure our Endpoint to act as a server in `config/prod.exs`.
Within `config/prod.exs` we need to make two changes. First we must configure our Endpoint to act as a server `server: true`. Additionally we must set the root to be `.`.

```elixir
# Configures the endpoint
config :hello_phoenix, HelloPhoenix.Endpoint,
http: [port: 8888],
url: [host: "example.com"],
root: ".",
cache_static_manifest: "priv/static/manifest.json",
server: true
```

When we run `mix phoenix.server` to start our application, the `server` parameter is automatically set to true. When we're creating a release, however, we need to configure this manually. If we get through this release guide, and we aren't seeing any pages coming from our server, this is a likely culprit.

When generating a release and performing a hot upgrade, the static assets being served will not be the newest version without setting the root to `.`. If you do not set root to `.` you will be forced to perform a restart so that the correct static assets are served, effectively changing the hot upgrade to a rolling restart.

If we take a quick look at our `config/prod.exs` again, we'll see that our port is set to `8888`.

```elixir
Expand Down Expand Up @@ -246,7 +249,7 @@ drwxr-xr-x 8 lance staff 272 May 13 18:47 0.0.1
-rw-r--r-- 1 lance staff 9 May 13 18:47 start_erl.data
```

The `hello_phoenix-0.0.1.tar.gz` tarball in `rel/hello_phoenix` is our release in archive form, ready to be shipped off to our hosting environment.
The `hello_phoenix-0.0.1.tar.gz` tarball in `rel/hello_phoenix/releases/0.0.1` is our release in archive form, ready to be shipped off to our hosting environment.

### Testing Our Release

Expand Down
6 changes: 6 additions & 0 deletions introduction/E_installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,9 @@ Postgrex is a direct Phoenix dependency, and it will be automatically installed
This is a Linux-only filesystem watcher that Phoenix uses for live code reloading. (Mac OS X or Windows users can safely ignore it.)

Linux users need to install this dependency. Please consult the [inotify-tools wiki](https://github.com/rvoicilas/inotify-tools/wiki) for distribution-specific installation instructions.

### Skeleton Installation

Sometimes you want an installation without anything except the bare minimum phoenix setup. The follow command will give you that.

`mix phoenix.new web --no-brunch --no-ecto`