This commit is contained in:
Rico Sta. Cruz 2016-06-19 00:19:06 +08:00
parent b223efbeec
commit f33fb9da78
No known key found for this signature in database
GPG Key ID: CAAD38AE2962619A
8 changed files with 293 additions and 23 deletions

View File

@ -7,12 +7,14 @@ category: Ansible
- apt_key: id=AC40B2F7 url="http://..."
state=present
- apt: pkg=nodejs state=present
state=present # absent | latest
update_cache=yes
force=no
- apt: deb=https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb
- apt_repository: repo='deb https://... raring main'
state=present
@ -58,3 +60,7 @@ category: Ansible
- shell: apt-get install nginx -y
- script: /x/y/script.sh
### local_action
- name: do something locally
local_action: shell echo hello

8
css-system-font-stack.md Normal file
View File

@ -0,0 +1,8 @@
---
title: "CSS: System font stack"
category: CSS
---
```
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
```

View File

@ -25,3 +25,20 @@ RUN bundle install
```
WORKDIR /myapp
```
### Onbuild
```docker
ONBUILD RUN bundle install # when used with another file
```
### Commands
```docker
EXPOSE 5900
CMD ["bundle", "exec", "rails", "server"]
```
### Reference
- <https://docs.docker.com/engine/reference/builder/>

33
elixir-metaprogramming.md Normal file
View File

@ -0,0 +1,33 @@
---
title: Elixir metaprogramming
category: Elixir
---
## Kernel
Most of these magic is defined in [Kernel.SpecialForms](http://devdocs.io/elixir/elixir/kernel.specialforms).
### Pseudo-variables
```elixir
__DIR__ # current dir
__MODULE__ # current module
__CALLER__ # caller of the function
```
### [`__ENV__`](http://devdocs.io/elixir/elixir/kernel.specialforms#__ENV__/0)
```elixir
Map.keys(__ENV__)
[:__struct__, :aliases, :context, :context_modules, :export_vars, :file,
:function, :functions, :lexical_tracker, :line, :macro_aliases, :macros,
:module, :requires, :vars]
```
```elixir
__CALLER__.module |> Module.definitions_in |> IO.inspect
```
```elixir
apply(Enum, :reverse, [[1, 2, 3]])
```

View File

@ -191,7 +191,8 @@ Also see [Enum](#enum).
```js
import List
list = [ 1, 2, 3, 4 ]
list = [ 1 | list ] # unshift (prepend)
list = list ++ [5] # push (append)
list = [ 0 | list ] # unshift (prepend)
first(list)
last(list)

64
exunit.md Normal file
View File

@ -0,0 +1,64 @@
---
title: ExUnit
category: Elixir
---
```elixir
defmodule MyTest do
use ExUnit.Case
use ExUnit.Case, async: true # for async
test "the truth" do
assert 1 + 1 == 2
end
end
```
### Capture IO
```elixir
import ExUnit.CaptureIO
test "capture io" do
result = capture_io(fn ->
IO.puts "sup"
end)
assert result == "sup\n"
end
```
### Capture logs
```elixir
config :ex_unit, capture_logs: true
```
### Async
```elixir
defmodule AssertionTest do
# run concurrently with other test cases
use ExUnit.Case, async: true
end
```
### [Assertions](http://devdocs.io/elixir/ex_unit/exunit.assertions)
```elixir
assert x == y
refute x == y
assert_raise ArithmeticError, fn ->
1 + "test"
end
assert_raise ArithmeticError, "message", fn -> ...
assert_raise ArithmeticError, ~r/message/, fn -> ...
flunk "This should've been an error"
## Also see
- <http://devdocs.io/elixir/ex_unit/exunit#configure/1>

View File

@ -3,7 +3,8 @@ title: "Phoenix: Plug.Conn"
category: Elixir
---
## Request
Request
-------
```elixir
conn.host #=> "example.com"
@ -16,9 +17,19 @@ conn.scheme #=> :http
conn.peer #=> { {127, 0, 0, 1}, 12345 }
conn.remote_ip #=> { 151, 236, 219, 228 }
conn.req_headers #=> [{"content-type", "text/plain"}]
conn |> get_req_header("referrer")
```
## Response
### Updating
Usually only useful for tests.
```elixir
conn
|> put_req_header("accept", "application/json")
```
Response
--------
```elixir
conn.resp_body #=> "..."
@ -28,6 +39,64 @@ conn.resp_headers #=> ...
conn.status #=> ...
```
### Sending responses
```elixir
# Plug.Conn
conn
|> html("<html><head>...")
|> json(%{ message: "Hello" })
|> text("Hello")
|> redirect(to: "/foo")
|> redirect(external: "http://www.google.com/")
|> halt()
|> put_resp_content_type("text/plain")
|> put_resp_cookie("abc", "def")
|> put_resp_header("X-Delivered-By", "myapp")
|> put_status(202)
|> put_status(:not_found)
|> put_private(:plug_foo, "...") # reserved for libraries
|> send_resp(201, "")
```
### Phoenix views
```elixir
# Phoenix.Controller
conn
|> render("index.html")
|> render("index.html", hello: "world")
|> render(MyApp.ErrorView, "404.html")
|> put_layout(:foo)
|> put_layout(false)
|> put_view(ErrorView)
|> put_secure_browser_headers()
# prevent clickjacking, nosniff, and xss protection
# x-frame-options, x-content-type-options, x-xss-protection
|> put_new_view(ErrorView) # if not set yet
|> put_new_layout(:foo)
```
```elixir
layout(conn)
```
Accepts
-------
```js
plug :accepts, ["html", "json"]
conn |> accepts(["html", "json"])
get_format(conn) #=> "html"
conn.accepts
```
## Misc
```elixir
@ -41,8 +110,8 @@ conn.state # :unset, :set, :file, :sent, :chunked
## Assigns
```elixir
conn = assign(conn, :user_id, 100)
conn.assigns[:hello]
conn |> assign(:user_id, 100)
```
```elixir
@ -50,7 +119,7 @@ conn = async_assign(conn, :location, fn -> geoip_lookup() end)
await_assign(conn, :location)
```
## Fetchables
## Session
```elixir
conn = fetch_session(conn) # or plug :fetch_session
@ -69,20 +138,4 @@ conn
```
```elixir
|> halt
|> put_resp_content_type("text/plain")
|> put_layout(false)
|> put_status(202)
|> put_status(:not_found)
|> render "index.html"
|> render "index.html", hello: "world"
|> render MyApp.ErrorView, "404.html"
|> redirect to: "/foo"
|> redirect external: "http://www.google.com/"
|> text "Hello"
|> send_resp(201, "")
```

View File

@ -3,6 +3,14 @@ title: "Phoenix: Ecto models"
category: Elixir
---
## Generating
```
$ mix phoenix.gen.html Profile profiles email:string age:integer
$ mix phoenix.gen.html User users email:string hashed_password:string
```
## Schema
```elixir
@ -12,6 +20,10 @@ defmodule User do
schema "users" do
field :name
field :age, :integer
# :id :binary :integer :float :boolean :string :binary
# {:array, inner_type} :decimal :map
field :password, virtual: true
end
end
```
@ -60,7 +72,7 @@ changeset.optional #=> [:body]
### Updating
```elixir
changeset
changeset #(or model)
|> change(title: "New title")
|> change(%{ title: "New title" })
|> put_change(:title, "New title")
@ -82,3 +94,79 @@ get_field(changeset, :title) #=> "hi" (even if unchanged)
fetch_change(changeset, :title) #=> {:ok, "hi"} | :error
fetch_field(changeset, :title) #=> {:changes | :model, "value"} | :error
```
## Ecto
### Get one
```elixir
Repo.get(User, id)
Repo.get_by(User, email: "john@hello.com") #=> %User{} | nil
# also get! get_by!
```
### Create/update
```elixir
changeset |> Repo.update
changeset |> Repo.insert
changeset |> Repo.insert_or_update
```
```
User
|> Ecto.Changeset.change(%{name: "hi"})
|> Repo.insert
```
## Many
### Queries
```elixir
from p in Post,
where: p.title == "Hello",
where: [state: "Sweden"],
limit: 1,
offset: 10,
order_by: c.name,
order_by: [c.name, c.title],
order_by: [asc: c.name, desc: c.title],
preload: [:comments],
preload: [comments: {c, likes: l}],
join: c in assoc(c, :comments),
join: p in Post, on: c.post_id == p.id,
group_by: p,
select: p,
select: {p.title, p.description},
select: [p.title, p.description],
```
### Get many
```elixir
Repo.all(User)
```
### Update many
```elixir
Repo.update_all(Post, set: [title: "Title"])
Repo.update_all(Post, inc: [views: 1])
```
### Chaining `_all` with queries
```elixir
from(p in Post, where: p.id < 10)
|> Repo.update_all(...)
from(p in Post, where: p.id < 10)
|> Repo.all()
```