【问题标题】:Ecto Simple Foreign KeyEcto 简单外键
【发布时间】:2017-12-08 04:49:08
【问题描述】:

在我的 Phoenix 应用程序中,我有一个联系人表和一个地址表。联系人架构是:

schema "contacts" do
    field :name, :string
    field :number, :string
    has_one :address, App.Address, on_delete: :nothing

    timestamps()
end

地址架构是

schema "addresses" do
    field :name, :string
    field :lat, :decimal
    field :lng, :decimal

    timestamps()
end

我只想通过从数据库填充的地址下拉列表选择联系人中的 address_id。然而,凤凰又回来了

`App.Address.contact_id` in `where` does not exist in the schema in query:

from a in App.Address,
  where: a.contact_id == ^9435,
  select: {a.contact_id, a}

所以它试图在地址中查找contact_id 字段,但是我希望地址属于一个联系人或多个联系人,但我不希望地址表中的contact_id 字段。这如何通过 ecto 关联来实现?

我知道我可以使用一个中间表来执行此操作,该表为每个 contact_id 和 address_id 配对的条目,但我宁愿避免这样做,因为我认为这会增加不必要的复杂性和抽象级别。

编辑:谢谢你的回答,我意识到我只需要在发布几分钟后反过来想它。当将其视为一个地址有许多联系人并且一个联系人有一个地址时,这些关系是有意义的。我只是认为地址属于联系人,而这不一定是正确的。

【问题讨论】:

  • "但是我不想要地址表中的contact_id字段" 那么数据库中的记录如何关联呢?
  • 多个联系人可以共享一个地址。但是每个联系人只有一个地址。

标签: elixir phoenix-framework


【解决方案1】:

如果Contact 只能有一个Address,而Address 可以在多个Contacts 中,并且contacts 表中有一个address_id 字段,则您需要一个belongs_to 关系Contacthas_manyContact

schema "contacts" do
  belongs_to :address, App.Address
  ...
end

schema "addresses" do
  has_many :contact, App.Contact
  ...
end

现在您可以像这样获取Contact 的地址:

contact = Repo.get(Contact, 1234) |> Repo.preload([:address])
IO.inspect contact.address.name

【讨论】:

    【解决方案2】:

    这是一个正常的一对多关联。您应该使用belongs_to 而不是has_one。这就是定义外键的地方。你可以阅读更多关于它们之间的区别here

    您的联系人迁移应该有一个关联行,例如

    add :address_id, references(:addresses, on_delete: :nothing)

    那么你的架构应该有关系

    schema "contacts" do
      belongs_to :address, App.Address
    end
    
    schema "addresses" do
      has_many :contact, App.Contact
    end
    

    如果您在进行这些调整后仍然遇到错误,则可能是您的控制器/查询中的另一个错误,我们需要更多代码示例来帮助您

    【讨论】:

      猜你喜欢
      • 2016-10-26
      • 1970-01-01
      • 2016-05-10
      • 2016-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-13
      相关资源
      最近更新 更多