belongs_toの関係を持つモデルを、 #show で描画するところのcontroller層の話です。そのとあるコードをテストする時、従属の関係にあるモデルをDBに生成しておく必要があるのですが、そのコードを書くにあたりEctoの知識が欠如しててつまづいていたけれど、うまくかけた、というメモ。
Userモデルは、Pageモデルの一部に従属(belongs_to)しているので、Userモデルの要素を取得する場合、PageモデルをDBに生成しておく必要がある、というコードです。
以下のshowがテスト対象となるもので、UserのRepoを取得してきて、それに対してSQLの IN (Repo.preload)をしてきて、その結果を描画するという内容。
alias MyExample.Repo
def show(conn, %{"id" => id}) do
user = Repo.get!(User, id)
|> Repo.preload(:page)
render(conn, "show.html", user: user)
end
それに対して、Repo.insertでPageを作成、その次に従属の関係を作るためにpage_idに生成したpageのidを代入したUserを用意する。
最後に、Repoを更新すると、最低限のデータが揃うので、showで表示する要素としては十分なデータが揃えられる、というものです。
alias MyExample.Repo
@page_attrs %MyExample.Page{description: "some content", title: "some content"}
test "shows chosen resource", %{conn: conn} do
page = Repo.insert! @page_attrs
user = Repo.insert! %User{}
user = %{user | page_id: page.id}
user = Repo.update! user
conn = get conn, user_path(conn, :show, user)
assert html_response(conn, 200) =~ "Show user"
end
test "renders page not found when id is nonexistent", %{conn: conn} do
page = Repo.insert! @page_attrs
assert_raise Ecto.NoResultsError, fn ->
get conn, user_path(conn, :show, -1)
end
end
Ectoの理解があるとひょいひょいっとできるのですが、そこが欠如していた時はどう書けば良いかよくわからなかったのですよね…