Ecto简单外键

时间:2017-12-08 04:49:08

标签: elixir phoenix-framework

在我的Phoenix应用程序中,我有一个Contact表和一个Address表。联系方案是:

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配对都有一个条目,但我宁愿避免这样做,因为我认为这会增加一定程度的不必要的复杂性和抽象。

编辑:谢谢你的答案,我意识到我只需要在发布后的几分钟内反复考虑它。当把它想象成一个地址有很多联系人而联系人有一个地址时,这种关系是有意义的。我不禁认为地址属于联系人,但这不一定是真的。

2 个答案:

答案 0 :(得分:1)

如果Contact只能有一个AddressAddress可以在多个Contact中,并且address_id字段中有contacts个字段在belongs_to表中,您需要Contact中的has_many关系和Contact中的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 这样的地址:

.....
self.bottom = float(self.rect.bottom)
self.moving_up = False
self.moving_down = False

def update(self):
    .....
    # check if the ship is moving up and stop the ship to move up if 
    # it's top edge position is less than 
    # screen's top (top right corner is 0,0) position
    if self.moving_up and self.rect.top > self.screen_rect.top:
        self.bottom -= self.ai_settings.ship_speed_factor

    # check if the ship is moving down and stop the ship when it's
    # bottom position is greater than the screen bottom edge position.
    if self.moving_down and self.rect.bottom < self.screen_rect.bottom:
        self.bottom += self.ai_settings.ship_speed_factor

    self.rect.bottom = self.bottom

答案 1 :(得分:0)

这是正常的一对多关联。您应该使用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

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