Search code examples
elixirecto

Capitalised fields in an Ecto model


What's the best way to access Capitalised Fields using Ecto?

I have to deal with a rather messy schema. Some of the columns are capitalised.

I set up the following model:

defmodule SourcesApi.SourceStatus do
  use SourcesApi.Web, :model

  # schema "source_statuses" do
  schema "source_statuses" do
    field :Hours_UnderOver, :integer
    field :trafficlight, :string
    ...

    timestamps
  end

  @required_fields ~w(Hours_UnderOver trafficlight)
  @optional_fields ~w()

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

And a corresponding view:

defmodule SourcesApi.SourceStatusView do
  use SourcesApi.Web, :view

  def render("index.json", %{source_statuses: source_statuses}) do
    %{data: render_many(source_statuses, SourcesApi.SourceStatusView, "source_status.json")}
  end

  def render("source_status.json", %{source_status: source_status}) do
    %{status: source_status.trafficlight,
      delay: source_status.Hours_UnderOver,
  end
end

Accessing the Capitalised field produces the following error:

== Compilation error on file web/views/source_status_view.ex == ** (CompileError) web/views/source_status_view.ex:12: an alias must expand to an atom at compilation time, but did not in "source_status.Hours_UnderOver". Use Module.concat/2 if you want to dynamically generate aliases

The capitalised fields are ugly, but perfectly valid.

Should Ecto handle them?

Am I doing something wrong? I am very new to Elixir / Ecto.

Is there a way to inject a select statement at some point and rename the field? Create a scope?

Is there a consistent way to access all fields?


Solution

  • Just replace the field name:

    source_status.Hours_UnderOver
    

    by:

    source_status."Hours_UnderOver"
    

    And you should be good to go. Please open up an issue on Phoenix issues tracker so we can generate the proper code upfront.