Сделать имя поля схемы Ecto отличным от имени столбца исходной таблицы (Эликсир)

В настоящее время я работаю над проектом Phoenix, где меня не устраивает то, как я вызываю поля в шаблонах.

В настоящее время схема

defmodule MyApp.Car do
  use MyApp.Web, :model
  schema "car" do
    field :columnName, :string
  end
end

car = Repo.get!(Car, id)

Я хотел бы иметь возможность вызывать результат с помощью car.column_name, а не car.columnName

Миграция базы данных в настоящее время невозможна из-за ряда приложений, использующих базу данных.


person Tomos Rees    schedule 13.04.2016    source источник
comment
AFAIK это невозможно в настоящее время.   -  person josemrb    schedule 14.04.2016
comment
Я думаю, вы могли бы создать представление и использовать его в своей схеме, это один из способов сделать это, но я считаю, что он будет работать только с выборками.   -  person NoDisplayName    schedule 14.04.2016


Ответы (3)


Существует параметр source для field.

:source — определяет имя, которое будет использоваться в базе данных для этого поля.

defmodule MyApp.Car do
  use MyApp.Web, :model
  schema "car" do
    field :column_name, :string, source: :columnName
  end
end
person zwippie    schedule 11.04.2019

Я считаю, что это можно сделать с помощью сопоставителя источников полей от Ecto.

defmodule MyApp.Car do
  use Ecto.Schema

  @field_source_mapper fn
    :column_name -> :columnName
    x -> x
  end

  schema "car" do
    field :column_name, :string
  end
end
person mralexlau    schedule 10.04.2019

Если вы хотите, чтобы схема Ecto использовала snake_case для имен столбцов, которые ссылаются на столбцы camelCase, вам потребуется создать представление. Если ваше представление используется только для переименования столбцов, это будет "обновляемый" в Postgres/MySql/Microsoft SQL Server. Это означает, что INSERT, UPDATE и DELETE в представлении будут записывать в реальную таблицу, на которую ссылается представление.

Например, если ваше определение таблицы автомобилей выглядит так:

CREATE TABLE car(
   id             SERIAL PRIMARY KEY,
   modelName      VARCHAR(255),
   makeName       VARCHAR(255),
   manufacturerId INT REFERENCES manufacturer(id)
);

вы можете создать миграцию, которая создает представление, выбирающее из каждого столбца с псевдонимом snake_case:

defmodule MyApp.Repo.Migrations.CarView do
  use Ecto.Migration

  def up do
    execute """
      CREATE VIEW my_app_car
      AS
      SELECT
          id AS id,
          modelName AS model_name,
          makeName AS make_name,
          manufacturerId AS manufacturer_id
      FROM car; 
    """
  end

  def down do
    execute "DROP VIEW my_app_car;"
  end
end

и вашей Ecto Schema просто нужно будет использовать ваше представление в качестве источника («my_app_car» вместо «car»):

defmodule MyApp.Car do
  use MyApp.Web, :model
  schema "my_app_car" do
    field :model_name, :string
    field :make_name, :string
    belongs_to :manufacturer, MyApp.Manufacturer
  end
end

Затем вы можете использовать свою схему MyApp.Car Ecto, как если бы ее источником была исходная таблица "car", но с измененными именами столбцов.

Если вы используете базу данных, которая поддерживает схемы, ( например, Postgres, SQL Server), вы можете создать отдельную схему для своих представлений вместо того, чтобы называть все ваши экто-представления «my_app_[ИМЯ ТАБЛИЦЫ]».

person Tom Schuster    schedule 11.09.2017