Это известная проблема с UUID
, Binary
и другими ecto типами, которые должны соответствовать определенному стандарту ( Это функция, а не ошибка ™ ️ ).Как и в случае @ TheAnh , вы можете использовать Ecto.UUID.dump/1
, чтобы проверить, действителен ли id
, но я бы предпочел спасти его прямо:
def get_user(id) do
Repo.get(User, id)
rescue
Ecto.Query.CastError -> nil
end
Override Repo
Приведенный выше пример может быть утомительным, потому что вам придется rescue
везде, где вы звоните get
.Поэтому я переопределяю функцию get/3
в MyApp.Repo
:
# lib/my_app/repo.ex
defoverridable [get: 2, get: 3]
def get(query, id, opts \\ []) do
super(query, id, opts)
rescue
Ecto.Query.CastError -> nil
end
Использование fetch
для формата кортежа
Вы должны использовать fetch_*
имена методов вместо get_*
чтобы вернуть значения в формате tuple
(чтобы избежать путаницы с методами по умолчанию Repo
):
# lib/my_app/repo.ex
def fetch(query, id, opts \\ []) do
case get(query, id, opts) do
nil -> {:error, :not_found}
schema -> {:ok, schema}
end
end
И вызвать это так в вашей основной функции:
def fetch_user(id) do
Repo.fetch(User, id)
end