Articleは複数のCommentを持っているとします。ArticleとCommentに1:多の関係を作ります。
articleのスキーマをにhas_manyを加えます
schema "articles" do
field :body, :string
field :title, :string
timestamps()
has_many :comments, Blog.Articles.Comment #書き加える
end
commentsテーブルを作ります。
% mix ecto.gen.migration create_comments
内容は次のとおり
defmodule Blog.Repo.Migrations.CreateComments do
use Ecto.Migration
def change do
create table(:comments) do
add :body, :text
add :article_id, references(:articles) #これが大事
timestamps()
end
end
end
Commentのスキーマを作りますこちらはbelongs_toで関係を記述します。
defmodule Blog.Articles.Comment do
use Ecto.Schema
import Ecto.Changeset
schema "comments" do
field :body, :string
timestamps()
belongs_to :article, Blog.Articles.Article
end
@doc false
def changeset(comment, attrs) do
comment
|> cast(attrs, [:body])
|> validate_required([:body])
end
end
マイグレートしたら完成
% mix ecto.migrate
保存する
> article1 = Blog.Articles.get_article!(1)
> comment = Ecto.build_assoc(article1, :comments, %{body: "I like this article."})
%Blog.Articles.Comment{
__meta__: #Ecto.Schema.Metadata<:built, "comments">,
article: #Ecto.Association.NotLoaded<association :article is not loaded>,
article_id: 1,
body: "I like this article.",
id: nil,
inserted_at: nil,
updated_at: nil
}
> Blog.Repo.insert!(comment)
[debug] QUERY OK db=0.4ms idle=1362.8ms
INSERT INTO "comments" ("article_id","body","inserted_at","updated_at") VALUES (?,?,?,?) RETURNING "id" [1, "I like this article.", "2021-12-30T13:41:08", "2021-12-30T13:41:08"]
%Blog.Articles.Comment{
__meta__: #Ecto.Schema.Metadata<:loaded, "comments">,
article: #Ecto.Association.NotLoaded<association :article is not loaded>,
article_id: 1, #Article IDが紐つけられている
body: "I like this article.",
id: 1,
inserted_at: ~N[2021-12-30 13:41:08],
updated_at: ~N[2021-12-30 13:41:08]
}
参照
preloadが必要
def get_article!(id), do: Repo.get!(Article, id) |> Repo.preload(:comments
<h1>Show Article</h1>
<ul>
<li>
<strong>Title:</strong>
<%= @article.title %>
</li>
<li>
<strong>Body:</strong>
<%= @article.body %>
</li>
</ul>
<p>
<%= for comment <- @article.comments do %>
<%= comment.body %>
<%= end %>
</p>