Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
DATABASE_URL=postgres://phoenix-app:s3cR3+@db/phoenix_in_docker_development
APP_PORT=8000
DATABASE_URL=postgres://phoenix-app:s3cR3+@db:5431/phoenix_in_docker_development
POSTGRES_USER=phoenix-app
POSTGRES_PASSWORD=s3cR3+
POSTGRES_PORT=5431
3 changes: 3 additions & 0 deletions .formatter.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
]
61 changes: 25 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,49 +1,38 @@
# Rumbl

To start your Phoenix app:
## Generating Resources

* Install dependencies with `mix deps.get`
* Create and migrate your database with `mix ecto.create && mix ecto.migrate`
* Install Node.js dependencies with `npm install`
* Start Phoenix endpoint with `mix phoenix.server`
* `phoenix.gen.html` - HTML scaffold
* `phoenix.gen.json` - JSON scaffold

Now you can visit [`localhost:4000`](http://localhost:4000) from your browser.

## Commands

initial setup
generate a video resource

```bash
$ mix phoenix.new . --app rumbl
$ mix ecto.create
$ mix phoenix.server
$ dc run app \
mix phoenix.gen.html Video videos \
user_id:references:users \
url:string \
title:string \
description:text
$ dc run app \
mix ecto.migrate
```

## Users

```bash
$ iex -S mix
> alias Rumbl.User
> alias Rumbl.Repo
> Repo.all(User)
> Repo.get(User, "1")
> Repo.get_by(User, name: "Chris")
```

## Editor

![](./editor.png)
## Formatting Code

## Browser
[[source](https://hexdocs.pm/mix/master/Mix.Tasks.Format.html)]

![](./browser.png)
**file**: `.formatter.exs`

---

## Editor (show user)

![](./editor-show-user.png)
```
[
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
]
```

## Browser (show user)
run the following without `--check-formatted` to auto-format code

![](./browser-show-user.png)
```bash
$ dc run app \
mix format --check-formatted
```
Binary file removed browser-show-user.png
Binary file not shown.
Binary file removed browser.png
Binary file not shown.
5 changes: 2 additions & 3 deletions config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ config :rumbl, Rumbl.Endpoint,
url: [host: "localhost"],
secret_key_base: "GNZ5YJlxIcD0NT9SljGs6umArMSddNL96oHBGw7b/muSr5jyOoVBI1DALeWzzbSH",
render_errors: [view: Rumbl.ErrorView, accepts: ~w(html json)],
pubsub: [name: Rumbl.PubSub,
adapter: Phoenix.PubSub.PG2]
pubsub: [name: Rumbl.PubSub, adapter: Phoenix.PubSub.PG2]

# Configures Elixir's Logger
config :logger, :console,
Expand All @@ -24,4 +23,4 @@ config :logger, :console,

# Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above.
import_config "#{Mix.env}.exs"
import_config "#{Mix.env()}.exs"
7 changes: 4 additions & 3 deletions config/dev.exs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use Mix.Config

config :rumbl, Rumbl.Endpoint,
http: [port: 4000],
http: [port: System.get_env("APP_PORT")],
debug_errors: true,
code_reloader: true,
check_origin: false,
watchers: [node: ["node_modules/brunch/bin/brunch", "watch", "--stdin",
cd: Path.expand("../", __DIR__)]]
watchers: [
node: ["node_modules/brunch/bin/brunch", "watch", "--stdin", cd: Path.expand("../", __DIR__)]
]

config :rumbl, Rumbl.Endpoint,
live_reload: [
Expand Down
6 changes: 5 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,24 @@ services:
context: .
dockerfile: Dockerfile.development
ports:
- "4000:4000"
- "${APP_PORT}:${APP_PORT}"
volumes:
- .:/app
environment:
- APP_PORT=${APP_PORT}
- DATABASE_URL=${DATABASE_URL}
depends_on:
- db
db:
image: postgres:9.3
ports:
- "${POSTGRES_PORT}:${POSTGRES_PORT}"
volumes:
- db-data:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_USER=${POSTGRES_USER}
command: -p ${POSTGRES_PORT}

volumes:
db-data:
Binary file removed editor-show-user.png
Binary file not shown.
Binary file removed editor.png
Binary file not shown.
2 changes: 1 addition & 1 deletion lib/rumbl.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ defmodule Rumbl do
# Start the Ecto repository
supervisor(Rumbl.Repo, []),
# Start the endpoint when the application starts
supervisor(Rumbl.Endpoint, []),
supervisor(Rumbl.Endpoint, [])
# Start your own worker by calling: Rumbl.Worker.start_link(arg1, arg2, arg3)
# worker(Rumbl.Worker, [arg1, arg2, arg3]),
]
Expand Down
34 changes: 21 additions & 13 deletions lib/rumbl/endpoint.ex
Original file line number Diff line number Diff line change
@@ -1,42 +1,50 @@
defmodule Rumbl.Endpoint do
use Phoenix.Endpoint, otp_app: :rumbl

socket "/socket", Rumbl.UserSocket
socket("/socket", Rumbl.UserSocket)

# Serve at "/" the static files from "priv/static" directory.
#
# You should set gzip to true if you are running phoenix.digest
# when deploying your static files in production.
plug Plug.Static,
at: "/", from: :rumbl, gzip: false,
plug(
Plug.Static,
at: "/",
from: :rumbl,
gzip: false,
only: ~w(css fonts images js favicon.ico robots.txt)
)

# Code reloading can be explicitly enabled under the
# :code_reloader configuration of your endpoint.
if code_reloading? do
socket "/phoenix/live_reload/socket", Phoenix.LiveReloader.Socket
plug Phoenix.LiveReloader
plug Phoenix.CodeReloader
socket("/phoenix/live_reload/socket", Phoenix.LiveReloader.Socket)
plug(Phoenix.LiveReloader)
plug(Phoenix.CodeReloader)
end

plug Plug.RequestId
plug Plug.Logger
plug(Plug.RequestId)
plug(Plug.Logger)

plug Plug.Parsers,
plug(
Plug.Parsers,
parsers: [:urlencoded, :multipart, :json],
pass: ["*/*"],
json_decoder: Poison
)

plug Plug.MethodOverride
plug Plug.Head
plug(Plug.MethodOverride)
plug(Plug.Head)

# The session will be stored in the cookie and signed,
# this means its contents can be read but not tampered with.
# Set :encryption_salt if you would also like to encrypt it.
plug Plug.Session,
plug(
Plug.Session,
store: :cookie,
key: "_rumbl_key",
signing_salt: "xwQbpobV"
)

plug Rumbl.Router
plug(Rumbl.Router)
end
67 changes: 42 additions & 25 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,58 @@ defmodule Rumbl.Mixfile do
use Mix.Project

def project do
[app: :rumbl,
version: "0.0.1",
elixir: "~> 1.2",
elixirc_paths: elixirc_paths(Mix.env),
compilers: [:phoenix, :gettext] ++ Mix.compilers,
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
aliases: aliases(),
deps: deps()]
[
app: :rumbl,
version: "0.0.1",
elixir: "~> 1.2",
elixirc_paths: elixirc_paths(Mix.env()),
compilers: [:phoenix, :gettext] ++ Mix.compilers(),
build_embedded: Mix.env() == :prod,
start_permanent: Mix.env() == :prod,
aliases: aliases(),
deps: deps()
]
end

# Configuration for the OTP application.
#
# Type `mix help compile.app` for more information.
def application do
[mod: {Rumbl, []},
applications: [:phoenix, :phoenix_pubsub, :phoenix_html, :cowboy, :logger, :gettext,
:phoenix_ecto, :postgrex, :comeonin]]
[
mod: {Rumbl, []},
applications: [
:phoenix,
:phoenix_pubsub,
:phoenix_html,
:cowboy,
:logger,
:gettext,
:phoenix_ecto,
:postgrex,
:comeonin
]
]
end

# Specifies which paths to compile per environment.
defp elixirc_paths(:test), do: ["lib", "web", "test/support"]
defp elixirc_paths(_), do: ["lib", "web"]
defp elixirc_paths(_), do: ["lib", "web"]

# Specifies your project dependencies.
#
# Type `mix help deps` for examples and options.
defp deps do
[{:phoenix, "~> 1.2.5"},
{:phoenix_pubsub, "~> 1.0"},
{:phoenix_ecto, "~> 3.0"},
{:postgrex, ">= 0.0.0"},
{:phoenix_html, "~> 2.6"},
{:phoenix_live_reload, "~> 1.0", only: :dev},
{:gettext, "~> 0.11"},
{:cowboy, "~> 1.0"},
{:comeonin, "~> 2.0"}]
[
{:phoenix, "~> 1.2.5"},
{:phoenix_pubsub, "~> 1.0"},
{:phoenix_ecto, "~> 3.0"},
{:postgrex, ">= 0.0.0"},
{:phoenix_html, "~> 2.6"},
{:phoenix_live_reload, "~> 1.0", only: :dev},
{:gettext, "~> 0.11"},
{:cowboy, "~> 1.0"},
{:comeonin, "~> 2.0"}
]
end

# Aliases are shortcuts or tasks specific to the current project.
Expand All @@ -48,8 +63,10 @@ defmodule Rumbl.Mixfile do
#
# See the documentation for `Mix` for more info on aliases.
defp aliases do
["ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
"ecto.reset": ["ecto.drop", "ecto.setup"],
"test": ["ecto.create --quiet", "ecto.migrate", "test"]]
[
"ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
"ecto.reset": ["ecto.drop", "ecto.setup"],
test: ["ecto.create --quiet", "ecto.migrate", "test"]
]
end
end
22 changes: 20 additions & 2 deletions notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,27 @@ $ dc up

visit <http://localhost:4000/>

drop into a console
drop into an interactive elixir console

```bash
$ dc run app /
$ dc exec app /
iex -S mix
```

drop into an interactive shell console

```bash
$ dc exec app /usr/bin/env bash
```

drop into a postgres console

```bash
$ psql $DATABASE_URL
```

list application routes

```bash
$ mix phoenix.routes
```
16 changes: 16 additions & 0 deletions priv/repo/migrations/20210316170506_create_video.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
defmodule Rumbl.Repo.Migrations.CreateVideo do
use Ecto.Migration

def change do
create table(:videos) do
add :url, :string
add :title, :string
add :description, :text
add :user_id, references(:users, on_delete: :nothing)

timestamps()
end
create index(:videos, [:user_id])

end
end
2 changes: 1 addition & 1 deletion test/controllers/page_controller_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ defmodule Rumbl.PageControllerTest do
use Rumbl.ConnCase

test "GET /", %{conn: conn} do
conn = get conn, "/"
conn = get(conn, "/")
assert html_response(conn, 200) =~ "Welcome to Phoenix!"
end
end
Loading