Предварительная загрузка has_one ассоциации без учета регистра - PullRequest
0 голосов
/ 10 мая 2019

Мы сейчас находимся в процессе перехода с Ruby / Rails / MariaDB на Elixir / Phoenix / MariaDB, и я столкнулся с проблемой при предварительной загрузке ассоциации в Ecto, которую мы не видели в ActiveRecord.

У нас есть определенные отношения, определенные в нашем проекте Rails, которые имеют внешние ключи типа string (я знаю, что это не лучшая практика). Например, учетная запись имеет один тарифный план (как определено в новом проекте Elixir):

schema "accounts" do
  field(:name, :string)
  field(:email_address, :string)
  field(:active, :boolean)
  field(:billing_model, :string)
  has_one(:billing_plan, BillingPlan, foreign_key: :name, references: :billing_model)
end

schema "billing_plans" do
  field(:name, :string)
  field(:price, :integer)
end

Проблема возникает при несоответствии регистра, например, если в учетной записи Pro хранится как billing_model, а в таблице billing_plans - pro. Когда я пытаюсь выполнить предварительную загрузку ассоциации следующим образом: Repo.get(Account, 1234) |> Repo.preload(:billing_plan), Ecto возвращает nil для billing_plan. Принимая во внимание, что, если случаи совпадают, Ecto возвращает billing_plan, как и ожидалось.

Моей первоначальной мыслью было исправить это в базе данных так, чтобы случаи совпадали. Тем не менее, это не сработало, так как начали появляться новые примеры, и я понял, что это не проблема, уникальная для этой ассоциации - в нашей схеме есть много подобных отношений. Вот почему я хотел бы исправить это на более высоком уровне, чтобы он не вернулся, чтобы укусить нас позже. В идеале было бы хорошо передать флаг конфигурации БД или опции при определении ассоциации.

Кто-нибудь сталкивался с этим вопросом до того, как он мог предложить толчок в правильном направлении или разумное решение?

1 Ответ

0 голосов
/ 15 мая 2019

Как я понимаю, у вас есть строковые внешние ключи, которые не совпадают из-за верхнего / нижнего регистра.

Как насчет того, если вместо предварительной загрузки вы создадите свой собственный запрос, я не смогу проверить случайно это должно быть что-то вроде

(from a in Account, join: b in BillingPlan, where: a.billing_model == 1234 and a.billing_model == b.name, select: %{ a | billing_plan: b}) |> Repo.one()

Перед этим вы должны импортировать Ecto.Query.

Я надеюсь, что это работает.

...