[Elixir+Phoenix+MongoDB]掲示板(もどき)を作成するだけの簡単なお仕事！

#目的

Elixir+Phoenix+MongoDBを使って最小限の掲示板(もどき)を作成し、
Phoenixの基本的な機能のおさらいを実施する。

#実施環境

OS： Windows8.1
Erlang： Eshell V6.4, OTP-Version 17.5
Elixir： v1.0.4
Phoenix Framework： v0.13.1
elixir-mongo： v0.5.1
MongoDB：v3.0.3

#始める前に

Phoenix Frameworkを使い掲示板(もどき)を作成します。
個人的には一番作成が簡単で基本機能のおさらいになると思っているので・・・
毎度、新しい言語とWebフレームワークを使う時は私の恒例行事となっています(笑)

プロジェクトは以下の通り作成した。

```iex
>cd プロジェクト作成ディレクトリ
>mix phoenix.new phoenix_bbs
>cd phoenix_bbs
>mix phoenix.server (localhost:4000)
>Ctrl+c
```

※ MongoDB等の実行環境はご自身で整えておいて下さい。

#目次

1. 作業一覧
2. ソースコード一覧
3. まとめ

##1. 作業一覧

-プロジェクト作成

-/web/router.exへスコープとルーティング先を追加
  --アクションは"index"と"create"を指定

-新規のコントローラ作成
  --フォームの入力値を取得
  --リダイレクトの設定
  --indexアクションにコレクションの内容を全表示する処理を追加
  --createアクションにコレクションへ入力内容を挿入する処理を追加

-新規のビュー作成

-新規のテンプレート作成
  --レンダリングするディレクトリを作成
  --レンダリングするテンプレートを作成
  --テンプレートにフォームを追加
  --フォームを使ったページ遷移
  --データを繰り返して表示する処理を作成

-MongoDB
  --MongoDB起動

##2. ソースコード一覧

作成または編集したソースコードは以下の通り。

mix.exs
依存関係の設定。
:mongoを追加している。

```ex:mix.exs
defmodule PhoenixBbs.Mixfile do
  use Mix.Project

  def project do
    [app: :phoenix_bbs,
     version: "0.0.1",
     elixir: "~> 1.0",
     elixirc_paths: elixirc_paths(Mix.env),
     compilers: [:phoenix] ++ Mix.compilers,
     build_embedded: Mix.env == :prod,
     start_permanent: Mix.env == :prod,
     deps: deps]
  end

  # Configuration for the OTP application
  #
  # Type `mix help compile.app` for more information
  def application do
    [mod: {PhoenixBbs, []},
     applications: [:phoenix, :phoenix_html, :cowboy, :logger,
                    :phoenix_ecto, :postgrex]]
  end

  # Specifies which paths to compile per environment
  defp elixirc_paths(:test), do: ["lib", "web", "test/support"]
  defp elixirc_paths(_),     do: ["lib", "web"]

  # Specifies your project dependencies
  #
  # Type `mix help deps` for examples and options
  defp deps do
    [{:phoenix, "~> 0.13.1"},
     {:phoenix_ecto, "~> 0.4"},
     {:postgrex, ">= 0.0.0"},
     {:phoenix_html, "~> 1.0"},
     {:phoenix_live_reload, "~> 0.4", only: :dev},
     {:cowboy, "~> 1.0"},
     {:mongo, "~> 0.5.1"}]
  end
end
```

/web/router.ex
ルーティング先の追加。
新しくスコープを作成して記述してます。

```ex:router.ex
defmodule PhoenixBbs.Router do
  use PhoenixBbs.Web, :router

  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_flash
    plug :protect_from_forgery
  end

  pipeline :api do
    plug :accepts, ["json"]
  end

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

    get "/", PageController, :index
  end

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

    get "/", BbsController, :index
    post "/comment_input", BbsController, :create
  end

  # Other scopes may use custom stacks.
  # scope "/api", PhoenixBbs do
  #   pipe_through :api
  # end
end
```

/web/controllers/bbs_controller.ex
ルーティング先に定義したアクションを作成。
また、Modelクラスは作成していないので、DBの処理はここへべた書き。

```ex:bbs_controller.ex
defmodule PhoenixBbs.BbsController do
  use PhoenixBbs.Web, :controller

  plug :action

  def index(conn, _params) do
    docs = Mongo.connect!
           |> Mongo.db("phoenix_bbs")
           |> Mongo.Db.collection("comments")
           |> Mongo.Collection.find
           |> Enum.to_list

    render conn, "bbs.html", comments: docs
  end

  def create(conn, params) do
    collection = Mongo.connect! |> Mongo.db("phoenix_bbs") |> Mongo.Db.collection("comments")

    %{name: params["name"],
      title: params["title"],
      comment: params["comment"]
     } |> Mongo.Collection.insert_one!(collection)

    redirect conn, to: "/bbs"
  end
end
```

/web/view/bbs_view.ex
ビューは作成しただけ、特に処理は追加していない。

```ex:bbs_view.ex
defmodule PhoenixBbs.BbsView do
  use PhoenixBbs.Web, :view
end
```

/web/templates/bbs/bbs.html.eex
テンプレートの大きな処理は、
コメントの一覧を表示することとコメントを入力する部分を表示すること。
一部、eexの記述(<%= %>)でElixirコードを実行している。

```ex:bbs.html.eex
<div class="jumbotron">
  <h2>Welcome to Phoenix BBS!</h2>
</div>

<div>
  <table>
    <%= for comment <- @comments do %>
      <tr>
        <td>name: <%= comment[:name] %></td>
        <td>title: <%= comment[:title] %></td>
      </tr>
      <tr>
        <td>comment: <%= comment[:comment] %></td>
        <td></td>
      </tr>
    <% end %>
  </table>
</div>

<div>
<%= form_tag("/bbs/comment_input", method: :post) %>
  <table>
    <tr>
      <td>Your Name</td>
      <td><input type="text" name="name" size="40"></td>
    </tr>
    <tr>
      <td>Title</td>
      <td><input type="text" name="title" size="40"></td>
    </tr>
    <tr>
      <td>Comment</td>
      <td><textarea name="comment" rows="3" cols="85"></textarea></td>
    </tr>
    <tr>
      <td><input type="submit" value="send"></td>
      <td><input type="reset" value="reset"></td>
    </tr>
  </table>
</form>
</div>
```

実行します。
`>mix phoenix.server`
アクセスページ： `http://localhost:4000/bbs`

こんな感じの画面が出ます。
![phoenix_bbs_result.png](https://qiita-image-store.s3.amazonaws.com/0/80934/2db4f163-12a6-9175-0623-204014ec4a64.png)

##3. まとめ

作成中に少々の問題は起こったが日数2日間で完成～
(これを遅いと見るか、速いと見るか・・・さてどうだろ・・・)

デザインが残念なのは気にしないで下さい。
CSSは殆ど無知に等しいので(笑)

ソースコード一式は以下のGithubリポジトリにあります。
よかったらどうぞ～
[Github - phoenix_bbs](https://github.com/darui00kara/darui_works/tree/master/elixir_space/phoenix_bbs)

#参考文献
なし！！