我目前正在开发凤凰项目,我对模板中的字段调用方式不满意。
架构是目前的
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
来调用结果
由于许多应用程序使用数据库,因此目前无法迁移数据库。
我相信这可以做到Ecto的field source mapper。
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
如果希望Ecto架构对引用camelCase列的列名使用snake_case,则需要创建一个视图。如果您的视图仅用于重命名列,则它将在Postgres / MySql / Microsoft SQL Server中为“updatable”。这意味着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”表,但是使用修改后的列名。
如果您使用的数据库支持schemas(例如Postgres,SQL Server),您可以为视图创建单独的模式,而不是命名所有的ecto视图“my_app_ [TABLE NAME]”。
:source - 定义要在此字段的数据库中使用的名称。
defmodule MyApp.Car do
use MyApp.Web, :model
schema "car" do
field :column_name, :string, source: :columnName
end
end