前面的章节里,我们完成了后端系统最重要的部分:用户。接下来我们要进入菜谱模块的开发。
我们先来确认下,菜谱有哪些属性需要保存:
| 属性名 | 类型 | 备注 | 是否必填 | 默认值 |
|---|---|---|---|---|
| name | string | 菜谱名 | 必填 | |
| title | string | 节目名 | 必填 | |
| season | integer | 第几季 | 必填 | 1 |
| episode | integer | 第几集 | 必填 | 1 |
| content | text | 内容 | 必填 | |
| user_id | integer | 关联用户 id | 必填 |
这里我们可以直接使用 mix phx.gen.html 命令来生成菜谱相关的所有文件:
$ mix phx.gen.html Recipes Recipe recipes name title season:integer episode:integer content:text user_id:references:users
* creating web/controllers/recipe_controller.ex
* creating web/templates/recipe/edit.html.eex
* creating web/templates/recipe/form.html.eex
* creating web/templates/recipe/index.html.eex
* creating web/templates/recipe/new.html.eex
* creating web/templates/recipe/show.html.eex
* creating web/views/recipe_view.ex
* creating test/controllers/recipe_controller_test.exs
* creating web/models/recipe.ex
* creating test/models/recipe_test.exs
* creating priv/repo/migrations/20170206013306_create_recipe.exs
Add the resource to your browser scope in web/router.ex:
resources "/recipes", RecipeController
Remember to update your repository by running migrations:
$ mix ecto.migrate
我们先按照提示把 resources "/recipes", RecipeController 加入 web/router.ex 文件中:
diff --git a/web/router.ex b/web/router.ex
index e0811dc..a6d7cd5 100644
--- a/web/router.ex
+++ b/web/router.ex
@@ -20,6 +20,7 @@ defmodule TvRecipeWeb.Router do
get "/", PageController, :index
resources "/users", UserController, except: [:index, :delete]
resources "/sessions", SessionController, only: [:new, :create, :delete]
+ resources "/recipes", RecipeController
end但请不要着急执行 mix ecto.migrate,我们有几个需要调整的地方:
注: 运行了的话可使用 mix ecto.rollback 回撤修改
-
新建的
priv/repo/migrations/20170206013306_create_recipe.exs文件中,有如下一句代码:add :user_id, references(:users, on_delete: :nothing)
on_delete决定recipe关联的user被删时,我们要如何处置recipe。:nothing表示不动recipe,:delete_all表示悉数删除,这里我们使用:delete_all。 -
新建的
lib/tv_recipe/recipes/recipe.ex文件中,有一句代码要替换:-field :user_id, :id +belongs_to :user, TvRecipe.Users.User
因为
Recipe与User的关系是双向的,所以我们需要在user.ex文件中增加一句:has_many :recipes, TvRecipe.Recipes.Recipe
-
我们需要在
recipe.ex文件中给season与episode设置默认值:field :season, :integer, default: 1 field :episode, :integer, default: 1
现在,我们可以执行 mix ecto.migrate 了:
$ mix ecto.migrate
12:45:54.141 [info] == Running TvRecipe.Repo.Migrations.CreateRecipe.change/0 forward
12:45:54.141 [info] create table recipes
12:45:54.146 [info] create index recipes_user_id_index
12:45:54.149 [info] == Migrated in 0.0s我们运行下测试看看:
$ mix test
mix test
Compiling 24 files (.ex)
Generated tv_recipe app
...............................................
Finished in 0.5 seconds
47 tests, 0 failures新生成的测试目前悉数通过。