Skip to content

将教程更新为 phoenix 1.5.9 可用的版本 #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 12, 2022
Merged
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
2 changes: 1 addition & 1 deletion 00-prepare/00-prepare.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ $ mix local.hex --force
## 安装 Phoenix

```bash
$ mix archive.install https://github.com/phoenixframework/archives/raw/master/phx_new.ez
mix archive.install hex phx_new 1.5.9
```

## 安装 Node.js(>=5.0.0)
Expand Down
37 changes: 20 additions & 17 deletions 04-user-register/00-prepare.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,32 +42,35 @@

但这样的手动添加过程太麻烦,还容易出错,应该有便捷的方法。

是的,Phoenix 提供了一系列的 mix 工具包。我们要接触的这个是 [`mix phoenix.gen.html`](https://hexdocs.pm/phoenix/Mix.Tasks.Phoenix.Gen.Html.html)。
是的,Phoenix 提供了一系列的 mix 工具包。我们要接触的这个是 [`mix phx.gen.html`](https://hexdocs.pm/phoenix/Mix.Tasks.Phoenix.Gen.Html.html)。

请在命令行窗口下切换到 `tv_recipe` 目录,然后执行 `mix phoenix.gen.html` 命令:
请在命令行窗口下切换到 `tv_recipe` 目录,然后执行 `mix phx.gen.html` 命令:

```
$ cd tv_recipe
$ mix phoenix.gen.html User users username:string:unique email:string:unique password:string
$ mix phx.gen.html Users User users username:string:unique email:string:unique password:string
```
![mix phoenix.gen.html 命令](/img/02-mix-phoenix.gen.html.png)
![mix phx.gen.html 命令](/img/02-mix-phoenix.gen.html.png)

执行命令后的输出如下:

```bash
* creating web/controllers/user_controller.ex
* creating web/templates/user/edit.html.eex
* creating web/templates/user/form.html.eex
* creating web/templates/user/index.html.eex
* creating web/templates/user/new.html.eex
* creating web/templates/user/show.html.eex
* creating web/views/user_view.ex
* creating test/controllers/user_controller_test.exs
* creating web/models/user.ex
* creating test/models/user_test.exs
* creating lib/tv_recipe_web/controllers/user_controller.ex
* creating lib/tv_recipe_web/templates/user/edit.html.eex
* creating lib/tv_recipe_web/templates/user/form.html.eex
* creating lib/tv_recipe_web/templates/user/index.html.eex
* creating lib/tv_recipe_web/templates/user/new.html.eex
* creating lib/tv_recipe_web/templates/user/show.html.eex
* creating lib/tv_recipe_web/views/user_view.ex
* creating test/lib/tv_recipe_web/controllers/user_controller_test.exs
* creating lib/tv_recipe/users/user.ex
* creating priv/repo/migrations/20170123145857_create_user.exs
* creating lib/tv_recipe/users.ex
* injecting lib/tv_recipe/users.ex
* creating test/lib/tv_recipe/users_test.exs
* injecting test/tv_recipe/users_test.exs

Add the resource to your browser scope in web/router.ex:
Add the resource to your browser scope in lib/tv_recipe_web/router.ex:

resources "/users", UserController

Expand Down Expand Up @@ -122,13 +125,13 @@ Generated tv_recipe app
11:08:12.067 [info] == Migrated in 0.0s
```

操作完上述两步后,因为某些编辑器可能导致的代码重载问题,你需要重启 Phoenix 服务器 - 按两次 Ctrl-C,然后重新执行 `mix phoenix.server`。
操作完上述两步后,因为某些编辑器可能导致的代码重载问题,你需要重启 Phoenix 服务器 - 按两次 Ctrl-C,然后重新执行 `mix phx.server`。

之后在浏览器中打开网址 `http://localhost:4000/users/new`:

![创建用户页面截图](/img/04-users-new-page.png)

有了。是不是很惊讶?我们用 `mix phoenix.gen.html` 命令生成的样板,功能已经很完善:增删改查功能全都有了。我们需要的,只是在样板基础上做点修改。
有了。是不是很惊讶?我们用 `mix phx.gen.html` 命令生成的样板,功能已经很完善:增删改查功能全都有了。我们需要的,只是在样板基础上做点修改。

[接下来](/04-user-register/01-username-required.md)几章,我们将一步步完成本章开头列出的限制条件。

Expand Down
43 changes: 27 additions & 16 deletions 04-user-register/01-username-required.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# username 必填

[上一章](/04-user-register/00-prepare.md)里,我们用 `mix phoenix.gen.html` 命令创建出完整用户界面,并且具备增加、删除、更改、查询用户的功能。
[上一章](/04-user-register/00-prepare.md)里,我们用 `mix phx.gen.html` 命令创建出完整用户界面,并且具备增加、删除、更改、查询用户的功能。

这一章,我们将实现 `username` 的第一个规则:`username` 必填,如果未填写,提示用户`请填写`。

Expand All @@ -20,7 +20,7 @@
让我们加上试试:

```elixir
diff --git a/web/models/user.ex b/web/models/user.ex
diff --git a/tv_recipe/users/user.ex b/tv_recipe/users/user.ex
index b7713a0..87ce321 100644
--- a/web/models/user.ex
+++ b/web/models/user.ex
Expand All @@ -43,7 +43,7 @@ index b7713a0..87ce321 100644

又或者,我们可以用 Phoenix 生成的测试文件来验证。

打开 `test/models/user_test.exs` 文件,默认内容如下:
打开 `test/tv_recipe/users_test.exs` 文件,默认内容如下:

```elixir
defmodule TvRecipe.UserTest do
Expand All @@ -68,10 +68,10 @@ end
文件中有两个变量,`@valid_attrs` 表示有效的 `User` 属性,`@invalid_attrs` 表示无效的 `User` 属性,我们按本章开头拟定的规则修改 `@valid_attrs`:

```elixir
diff --git a/test/models/user_test.exs b/test/models/user_test.exs
diff --git a/test/tv_recipe/users_test.exs b/test/tv_recipe/users_test.exs
index 1d5494f..7c73207 100644
--- a/test/models/user_test.exs
+++ b/test/models/user_test.exs
--- a/test/tv_recipe/users_test.exs
+++ b/test/tv_recipe/users_test.exs
@@ -3,7 +3,7 @@ defmodule TvRecipe.UserTest do

alias TvRecipe.User
Expand All @@ -83,42 +83,53 @@ index 1d5494f..7c73207 100644
test "changeset with valid attributes" do
```

接着,在 `user_test.exs` 文件中添加一个新测试:
接着,在 `users_test.exs` 文件中添加一个新测试:

```elixir
diff --git a/test/models/user_test.exs b/test/models/user_test.exs
index 7c73207..4c174ab 100644
--- a/test/models/user_test.exs
+++ b/test/models/user_test.exs
--- a/test/tv_recipe/users_test.exs
+++ b/test/tv_recipe/users_test.exs
@@ -15,4 +15,9 @@ defmodule TvRecipe.UserTest do
changeset = User.changeset(%User{}, @invalid_attrs)
refute changeset.valid?
end
+
+ test "username should not be blank" do
+ attrs = %{@valid_attrs | username: ""}
+ assert {:username, "请填写"} in errors_on(%User{}, attrs)
+ assert %{username: ["请填写"] } = errors_on(%User{}, attrs)
+ end
end
```

这里,`%{@valid_attrs | username: ""}` 是 Elixir 更新映射(Map)的一个方法。

至于 `errors_on` 函数,它定义在 `tv_recipe/test/support/model_case.ex` 文件中:
至于 `errors_on/2` 函数,它需要新增在 `test/support/data_case.ex` 文件中:

```elixir
def errors_on(struct, data) do
struct.__struct__.changeset(struct, data)
|> Ecto.Changeset.traverse_errors(&TvRecipe.ErrorHelpers.translate_error/1)
|> Enum.flat_map(fn {key, errors} -> for msg <- errors, do: {key, msg} end)
def errors_on(changeset) do
Ecto.Changeset.traverse_errors(changeset, fn {message, opts} ->
Regex.replace(~r"%{(\w+)}", message, fn _, key ->
opts |> Keyword.get(String.to_existing_atom(key), key) |> to_string()
end)
end)
end
+
+ def errors_on(struct, attrs) do
+ changeset = struct.__struct__.changeset(struct, attrs)
+ errors_on(changeset)
+ end
end
```

是否很吃惊?要知道,如果是在 JavaScript 里写两个同名函数,后一个函数会覆盖前一个的定义,而 Elixir 下,我们可以定义多个同名函数,它们能处理不同的状况,而又互不干扰。

它检查给定数据中的错误消息,并返回给我们。

现在在命令行下运行:

```bash
$ mix test test/models/user_test.exs
$ mix test test/tv_recipe/users_test.exs
```
结果如下:

Expand Down
Loading