如果外键之一是唯一字符串,则为“ many_to_many”

问题描述

我有2个主表:articlestags。它们具有“通过articles_to_tags表的“ many_to_many_关系。问题是,tagsarticles通过其连接的tags的键的类型为string。他们的数据库级别如下:

tags:
  - id
  - name (unique)

articles
  - id
  - title
  - body

articles_to_tags:
  - article_id
  - tag_name /* !! */

在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

即使我用测试数据填充了数据库,该数据为文章分配了一些标签,但是在我的项目中,文章仍具有0个标签

article = Repo.get(Article,123) |> Repo.preload(:tags)
IO.puts("*** article tags len: #{length(article.tags)}")

为什么?

我尝试过玩join_keys,事实证明这很令人困惑,并且无法解决问题:

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?
      ]
    )

如何解决

通过“ tag.name”而不是“ tag.id”加入表是必需的。

解决方法

从文档中:https://hexdocs.pm/ecto/Ecto.Schema.html#many_to_many/3

:join_keys-..,预期有两个条目的关键字列表,第一个是联接表应如何到达当前架构,第二个是联接表应如何到达关联的架构。

因此,您应该尝试在“文章”架构中执行此操作:

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
      ]
    )

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...