I have 2 main tables: articles
and tags
. They have "many_to_many_ relationship via articles_to_tags
table. A thing is that a key of tags
via which articles
and tags
are connected is of type string
. On the level of database they look as follows:
tags:
- id
- name (unique)
articles
- id
- title
- body
articles_to_tags:
- article_id
- tag_name /* !! */
On the level of Ecto:
# articles_to_tags
@primary_key false
schema "articles_to_tags" do
belongs_to(:article, Article)
belongs_to(:tag, Tag, references: :name, foreign_key: :tag_name, type: :string)
end
Even though I've filled out a database with test data that's assigns some tags to an article, in my project an article still has 0 tags:
article = Repo.get(Article, 123) |> Repo.preload(:tags)
IO.puts("*** article tags len: #{length(article.tags)}")
Why?
I've tried to play with join_keys
, and it's turned out to be confusing and hasn't resolved the issue:
schema "articles" do
# ................
many_to_many(:tags, Tags, join_through: ArticleToTag,
join_keys: [
tag_name: :name, # 'name' of which table?
article_id: :id # 'id' of which table?
]
)
How to fix it?
Joining the tables via "tag.name" instead of "tag.id" is a requirement.
From the docs: https://hexdocs.pm/ecto/Ecto.Schema.html#many_to_many/3
:join_keys - ..,expects a keyword list with two entries, the first being how the join table should reach the current schema and the second how the join table should reach the associated schema.
So you should try doing this in your Articles schema:
schema "articles" do
# ................
many_to_many(:tags, Tags, join_through: ArticleToTag,
join_keys: [
article_id: :id # 'id' of current schema
tag_name: :name, # 'name' of associated schema
]
)