Can the Ecto schema field name different from column name?

时光毁灭记忆、已成空白 提交于 2019-12-11 12:55:35

问题


I've got a legacy database that I'm trying to pull into Ecto. In it there's an orders table which has an order_status_id column. order_status_id maps to a set of constants in the legacy system.

I'd like to have the MyApp.Order struct contain an order_status field, which has a custom type that converts the integer IDs to meaningful atoms. I've got the custom type working, but I can't figure out how to map a field named order_status to a column named order_status_id.

The legacy system is still online and using the database, so changing the DB schema is not an option. Is there any way to get this working?


回答1:


I'm not sure if it was possible when the question was first asked, but it is possible now (Elixir 1.5). See https://hexdocs.pm/ecto/Ecto.Schema.html In particular the @field_source_mapper and :source options. The :source option is pretty easy -- just include it in your schema definition something like this:

  schema "orders" do

    field :foo, :string, [source: :legacy_foo_db_column]
    field :status, :integer, [source: :order_status]

  end

In the above example, the existing database table has columns named "legacy_foo_db_column" and "order_status", but internally in the Elixir app, the schema and changeset etc. will use attributes named "foo" and "status"




回答2:


I think, it is currently not possible to simply associate model field with different column name.

If you really want to use name order_status, you can create additional virtual field. Those fields are not persisted to database. Then your cast function should be responsible for changing order_status_id based on params.

def changeset(model, params \\ :empty) do
  model
  |> cast(params, @required_fields, @optional_fields)
  |> put_order_status_id
end

defp put_order_status_id(changeset) do
  case changeset do
    %Ecto.Changeset{valid?: true, changes: %{order_status: status}} ->
      put_change(changeset, :order_status_id, id_from_status(status))
    _ ->
      changeset
  end
end

In theory, you can also use changeset function to do the opposite operation: set order_status based on order_status_id, but it adds complexity.

In my opinion, the best solution would be to simply accept order_status_id name.



来源:https://stackoverflow.com/questions/36319893/can-the-ecto-schema-field-name-different-from-column-name

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!