Hello everyone,
I’m asking for help or guide to properly insert or populate foreign keys in the third table in a many_to_many association.
I have Posts Entity and Tags Entity which are join through third table (Post_Tags)
//post_tags_migration
def change do
create table(:post_tags) do
add :post_id, references(:posts, on_delete: :delete_all)
add :tag_id, references(:tags, on_delete: :delete_all)
timestamps()
end
create index(:post_tags, [:post_id])
create index(:post_tags, [:tag_id])
create unique_index(:post_tags, [:post_id, :tag_id])
end
Post Schema
schema "posts" do
field :content, :string
field :title, :string
many_to_many :tags, Tags, join_through: PostTags
timestamps()
end
@doc false
def changeset(posts, attrs \\ %{}) do
posts
|> cast(attrs, [:title, :content])
|> validate_required([:title, :content])
|> put_assoc(:tags, parse_tags(attrs))
end
defp parse_tags(attrs) do
(attrs["tags"] || attrs[:tags] || "")
|> String.split(",")
|> Enum.map(&String.trim/1)
|> Enum.reject(& &1 == "")
|> insert_and_get_all()
end
defp insert_and_get_all([]), do: []
defp insert_and_get_all(names) do
now = NaiveDateTime.utc_now |> NaiveDateTime.truncate(:second)
maps = Enum.map(names, &%{name: &1, inserted_at: now, updated_at: now})
Repo.insert_all Tags, maps, on_conflict: :nothing
Repo.all from t in Tags, where: t.name in ^names
end
- Uses this blog as reference: Many to many example
Post Tags Schema
schema "post_tags" do
belongs_to :post, Posts, primary_key: true
belongs_to :tag, Tags, primary_key: true
timestamps()
end
@required_fields ~w(post_id tag_id)
@doc false
def changeset(post_tags, attrs) do
post_tags
|> cast(attrs, @required_fields)
|> validate_required(@required_fields)
end
My issue is Post_Tags table only populate the timestamps fields:
[debug] QUERY OK db=0.8ms
INSERT INTO "post_tags" ("inserted_at","updated_at") VALUES ($1,$2) RETURNING "id" [~N[2018-11-28 15:12:34], ~N[2018-11-28 15:12:34]]
[debug] QUERY OK db=0.2ms
INSERT INTO "post_tags" ("inserted_at","updated_at") VALUES ($1,$2) RETURNING "id" [~N[2018-11-28 15:12:34], ~N[2018-11-28 15:12:34]]
[debug] QUERY OK db=0.2ms
INSERT INTO "post_tags" ("inserted_at","updated_at") VALUES ($1,$2) RETURNING "id" [~N[2018-11-28 15:12:34], ~N[2018-11-28 15:12:34]]
Given I have this param:
%{
"content" => "This is a sample text to demonstrate multiple insertions of tags",
"tags" => "Erlang,Elixir,Phoenix",
"title" => "Dapps"
}
When I insert this post and tag are created based on the params given but not the third table.
I’m not best in explaining in detail as much as possible, feel free to ask if the information is not sufficient.
Thanks.