著者:清水赳(香川大学SLP)
こんにちは。香川大学工学部 学部3 年の清水です。今回は、前回に引き続き、Elixir 製のWebアプリケーションフレームワーク Phoenix を紹介します。Elixir はRuby によく似た文法を持っています。更にPhoenix は、MVC
フレームワークを採用するなど、Ruby on Rails に大きく影響を受けています。その他にも影響を受けた点は多く、非常に近い感覚でコーディングが行えます。
前回はPhoenix の紹介として、モデルが1 つだけの簡単な掲示板アプリケーションを作成しました。今回はもう一歩踏み込んでみます。自分の蔵書を管理できるアプリケーションを作りながら、2 つ以上のモデルを関連付ける方法を紹介します。
記事本文掲載のシェルスクリプトマガジンvol.50は以下リンク先でご購入できます。
1 2 3 4 5 6 |
schema "genres" do has_many :books, Bookcollection.Book, on_delete: :delete_all # この行を追加 field :name, :string timestamps() end |
1 2 3 4 5 6 7 8 |
schema "books" do field :title, :string field :isbn, :string field :store_loc, :string field :genre_id, :integer # この行を削除 belongs_to :genre, Bookcollection.Genre, foreign_key: :genre_id # この行を追加 timestamps() end |
1 2 3 4 5 6 |
scope "/", Bookcollection do pipe_through :browser # Use the default browser stack get "/", PageController, :index # この行を削除する resources "/books", BookController # この行を追加する resources "/genres", GenreController # この行を追加する end |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
defmodule Bookcollection.GenreController do use Bookcollection.Web, :controller def index(conn, _params) do genres = Repo.all(Bookcollection.Genre) render conn, "index.html", genres: genres end def new(conn, _params) do genre = Bookcollection.Genre.changeset(%Bookcollection.Genre{}, %{}) render conn, "new.html", genre: genre end def create(conn, _params) do genre = Bookcollection.Genre.changeset(%Bookcollection.Genre{}, _params["genre"]) case Repo.insert(genre) do {:ok, genre} -> redirect conn, to: "/genres" {:error, genre} -> render(conn, "new.html", genre: genre) end end def delete(conn, _params) do genre = Repo.get(Bookcollection.Genre, _params["id"]) Repo.delete_all(from(b in Bookcollection.Book, where:b.genre_id == ^genre.id)) Repo.delete(genre) redirect conn, to: "/genres" end end |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
defmodule Bookcollection.BookController do use Bookcollection.Web, :controller def index(conn, _params) do books = Repo.all(Bookcollection.Book) render conn, "index.html", books: books end def new(conn, _params) do book = Bookcollection.Book.changeset(%Bookcollection.Book{}, %{}) genre = Enum.map(Repo.all(Bookcollection.Genre), &{&1.name, &1.id}) render conn, "new.html", book: book, genre: genre end def create(conn, _params) do book = Bookcollection.Book.changeset(%Bookcollection.Book{}, _params["book"]) case Repo.insert(book) do {:ok, book} -> redirect conn, to: "/books" {:error, book} -> genre = Enum.map(Repo.all(Bookcollection.Genre),&{&1.name, &1.id}) render(conn, "new.html", book: book, genre: genre ) end end def delete(conn, _params) do book = Repo.get(Bookcollection.Book, _params["id"]) Repo.delete(book) redirect conn, to: "/books" end end |
1 2 3 |
defmodule Bookcollection.BookView do use Bookcollection.Web, :view end |
1 2 3 |
defmodule Bookcollection.GenreView do use Bookcollection.Web, :view end |
<%= for book <- @books do %> <% end %>
<%= book.title %> | <%= link ” 削除”, to: book_path(@conn, :delete,book.id), method: :delete %> |
<%= form_for @book, book_path(@conn, :create), fn f ->%>
タイトル <%= text_input f, :title, placeholder: ” タイトル”,class: “form-control” %>
ISBN <%= text_input f, :isbn, placeholder: “ISBN”, class:”form-control” %>
蔵書の場所 <%= text_input f, :store_loc, placeholder: ” 蔵書の場所”, class: “form-control” %>
<%= select f, :genre_id, @genre %>
<%= submit ” 登録” %>
<% end %>
<%= for genre <- @genres do %> <% end %>
<%= genre.name %> | <%= link ” 削除”, to: genre_path(@conn, :delete, genre.id), method: :delete %> |
<%= form_for @genre, genre_path(@conn, :create), fn f-> %>
<%= text_input f, :name, placeholder: ” ジャンル名”,class: “form-control” %>
<%= submit ” 作成” %>
<% end %>