Elixir - Phoenixで株価を表示する(前編)
MySQLに入っている株価データを表示する。
ページ構成としてはHome
(月別カレンダー)とVolume
(日別出来高ランキング)の2つ。
今回はHomeだけ。
Routing
ルーティングでのポイントは、HomeControllerへのルートは引数有り無しのに種類用意すること。
web/router.ex
が以下。
defmodule StockScraping.Router do use StockScraping.Web, :router pipeline :browser do plug :accepts, ["html"] plug :fetch_session plug :fetch_flash plug :protect_from_forgery plug :put_secure_browser_headers end scope "/", StockScraping do pipe_through :browser get "/", HomeController, :index get "/:date", HomeController, :index get "/volume/:date", VolumeController, :index end end
HomeController
ここでは引数で受けた文字列をDate
にキャストしている。
引数がない場合は、現在時刻を使用する。
(キャスト方法は本当にこれであってるんだろうか…)
render conn, "index.html", items: items
とすることでテンプレートで@items
を参照可能になる。
web/controllers/home_controller.ex
の最終形が以下。
defmodule StockScraping.HomeController do use StockScraping.Web, :controller def index(conn, params) do target_date = case params do %{"date" => date} -> case Date.from_iso8601(date) do {:ok, value} -> value end _ -> now() end items = Repo.all(StockScraping.YahooVolumeDate) |> Enum.filter(fn(x) -> x.date.year == target_date.year && x.date.month == target_date.month end) render conn, "index.html", items: items end end
HomeView
ViewへはDateをstringに変換する関数を作成し、テンプレートから呼び出す。
あえてパターンマッチングで実装してみた。
web/views/home_view.ex
が以下。
defmodule StockScraping.HomeView do use StockScraping.Web, :view def convert(date) do case Timex.format(date, "{YYYY}-{0M}-{D}") do {:ok, value} -> value end end end
HomeTemplete
UIおいといてとりあえず表示させる。
ポイントはvolume_path(@conn, :index, convert(item.date))
VolumeControllerのIndexアクションへのURLをクエスパラメータ付きでレンダリングする処理。
Routingのget "/volume/:date", VolumeController, :index
でルートを追加しないと例外でる。
<h3>カレンダー</h3> <ul> <%= for item <- @items do %> <li> <a href="<%= volume_path(@conn, :index, convert(item.date)) %>"><%= item.date %></a> </li> <% end %> </ul>
これで一旦株価を更新した日付の一覧を表示できた。