Update
This commit is contained in:
parent
b223efbeec
commit
f33fb9da78
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
```
|
|
@ -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/>
|
||||
|
|
|
@ -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]])
|
||||
```
|
|
@ -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)
|
||||
|
|
|
@ -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>
|
|
@ -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, "")
|
||||
```
|
||||
|
|
|
@ -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()
|
||||
```
|
||||
|
|
Loading…
Reference in New Issue