前面的章节里,我们完成了后端系统最重要的部分:用户。接下来我们要进入菜谱模块的开发。
我们先来确认下,菜谱有哪些属性需要保存:
属性名 | 类型 | 备注 | 是否必填 | 默认值 |
---|---|---|---|---|
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
新生成的测试目前悉数通过。
更多建议: