4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Phoenixのルーティング定義を変更してみる

Posted at

最初に

この文章は、Phoenixのガイドを斜めに読みながら試した結果を書いています。
元文章の読み間違い等がありましたらコメントお願いします。

ネストしたリソースに対するルーティング定義

設定ファイルの修正

デモアプリ作成時、ある記事へコメントを投稿する機能に

POST /posts/:id/comment

というルートを割り当てるために、

scope "/", PhoenixSample do
  pipe_through :browser # Use the default browser stack

  get "/", PageController, :index
  resources "/posts", PostController
  post "/posts/:id/comments", PostController, :add_comment  # add comment route
end

という形で定義を行った。
しかし、こういったネストしたリソースに対しては

  scope "/", PhoenixSample do
    pipe_through :browser # Use the default browser stack

    get "/", PageController, :index

    resources "/posts", PostController do
      resources "/comments", CommentController
    end

#    post "/posts/:id/comments", PostController, :add_comment
  end

という形で定義することができるようだ。
試しにルート一覧を見てみると、

        page_path  GET     /                                  PhoenixSample.PageController :index
        post_path  GET     /posts                             PhoenixSample.PostController :index
        post_path  GET     /posts/:id/edit                    PhoenixSample.PostController :edit
        post_path  GET     /posts/new                         PhoenixSample.PostController :new
        post_path  GET     /posts/:id                         PhoenixSample.PostController :show
        post_path  POST    /posts                             PhoenixSample.PostController :create
        post_path  PATCH   /posts/:id                         PhoenixSample.PostController :update
                   PUT     /posts/:id                         PhoenixSample.PostController :update
        post_path  DELETE  /posts/:id                         PhoenixSample.PostController :delete
post_comment_path  GET     /posts/:post_id/comments           PhoenixSample.CommentController :index
post_comment_path  GET     /posts/:post_id/comments/:id/edit  PhoenixSample.CommentController :edit
post_comment_path  GET     /posts/:post_id/comments/new       PhoenixSample.CommentController :new
post_comment_path  GET     /posts/:post_id/comments/:id       PhoenixSample.CommentController :show
post_comment_path  POST    /posts/:post_id/comments           PhoenixSample.CommentController :create
post_comment_path  PATCH   /posts/:post_id/comments/:id       PhoenixSample.CommentController :update
                   PUT     /posts/:post_id/comments/:id       PhoenixSample.CommentController :update
post_comment_path  DELETE  /posts/:post_id/comments/:id       PhoenixSample.CommentController :delete

ずらりとcomment関係のルーティングが追加されていることがわかる。
しかし、今回欲しいのはコメント追加の機能だけなので、更に定義を変更。

  scope "/", PhoenixSample do
    pipe_through :browser # Use the default browser stack

    get "/", PageController, :index

    resources "/posts", PostController, expect: [:delete] do
      resources "/comments", CommentController, only: [:create]
    end

#    post "/posts/:id/comments", PostController, :add_comment
  end

必要なコメント追加のルートだけを追加し、ついでにもともと不要だった記事の削除のルートを除外する。
再び確認してみると、

        page_path  GET     /                         PhoenixSample.PageController :index
        post_path  GET     /posts                    PhoenixSample.PostController :index
        post_path  GET     /posts/:id/edit           PhoenixSample.PostController :edit
        post_path  GET     /posts/new                PhoenixSample.PostController :new
        post_path  GET     /posts/:id                PhoenixSample.PostController :show
        post_path  POST    /posts                    PhoenixSample.PostController :create
        post_path  PATCH   /posts/:id                PhoenixSample.PostController :update
                   PUT     /posts/:id                PhoenixSample.PostController :update
        post_path  DELETE  /posts/:id                PhoenixSample.PostController :delete
post_comment_path  POST    /posts/:post_id/comments  PhoenixSample.CommentController :create

想定通り、コメント追加だけが追加されている。

その他修正

あとは、テンプレートの修正とコントローラの追加を行う。

mixコマンドにはコントローラだけを作成するようなタスクは存在しない模様。
(ググるとphoenix.gen.controllerというものが出てくるが、おそらく古いバージョンのもの)
しょうがないので、web/controller/post_controller.ex必要な部分だけコピペし、
create関数だけ

  def create(conn, %{"post_id" => post_id, "comment" => post_params}) do
    post = Repo.get!(Post, post_id)
    changeset = Comment.changeset(%Comment{post_id: post.id}, post_params)

    case Repo.insert(changeset) do
      {:ok, _post} ->
        conn
        |> put_flash(:info, "Comment create successfully.")
        |> redirect(to: post_path(conn, :show, post))
      {:error, changeset} ->
	conn
	|> put_flash(:info, "Error occured.")
        |> redirect(to: post_path(conn, :show, post))
    end
  end

と、先日作成したadd_comment関数を移植したものに書き換えて終了。

テンプレートについては、web/template/post/show.eexのコメント投稿フォームのアクションを

<%= form_for @comment_changeset, post_comment_path(@conn, :create, @post), fn f -> %>

と新たに定義された関数に差し替えて終了。
これで、新しい定義でも動くようになるはずです。

prefixを含んだルートを定義する

例えば、api用のルートはすべて

  /api/xxx/yyy

と先頭に/apiというprefixをつけて定義したい場合は

  scope "/api", PhoenixSample do
    pipe_through :api

    resources "/posts", ApiPostController
  end

このようにスコープを作り、その内部で定義すると、

    api_post_path  GET     /api/posts                PhoenixSample.ApiPostController :index
    api_post_path  GET     /api/posts/:id/edit       PhoenixSample.ApiPostController :edit
    api_post_path  GET     /api/posts/new            PhoenixSample.ApiPostController :new
    api_post_path  GET     /api/posts/:id            PhoenixSample.ApiPostController :show
    api_post_path  POST    /api/posts                PhoenixSample.ApiPostController :create
    api_post_path  PATCH   /api/posts/:id            PhoenixSample.ApiPostController :update
                   PUT     /api/posts/:id            PhoenixSample.ApiPostController :update
    api_post_path  DELETE  /api/posts/:id            PhoenixSample.ApiPostController :delete

このように、スコープで指定したprefix込のルートが定義される。

参考サイト

Phoenix GUIDE : http://www.phoenixframework.org/docs/routing

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?