Преобразуйте свойство набора изменений, прежде чем оно войдет в базу данных. - PullRequest
0 голосов
/ 22 октября 2018

Я добавил textarea в форму Elixir и установил значение string и получил строку в столбце метаданных базы данных, который имеет тип jsonb.Строка в textarea Я хочу разделить на новую строку и сохранить array из strings вместо одной большой строки.

С тех пор я изменил тип следующим образом.

field :names, {:array, :string} 

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

Я смотрел:

Кажется, что я могу добавить validation функцию к схеме, это моя попытка.

def changeset(schema, params \\ %{}) do
    schema
    |> cast(params, @required, @optional)
    |> validate_name()
end

defp validate_names(changeset) do
    # fetch_field(changeset, :names)
    # Map.put(changeset, :names, String.split(:names, "\r\n"))
end

Как изменить значение одного свойства в объекте Elixir?

Обновление:

person_metadata.ex

defmodule DB.PersonMetadata do
  use DB.Schema

  embedded_schema do
    field :names, :string
  end

  @required ~w()
  @optional ~w(names)

  def changeset(schema, params \\ %{}) do
    schema
    |> cast(params, @required, @optional)
    |> validate_names()
  end

  defp validate_names(changeset) do
    case get_field(changeset, :names) do
      # Don't do anything if names don't exist
      nil ->
        changeset

      # Update names if they do exist
      names ->
        new_names = String.split(names, "\n")
        put_change(changeset, :names, new_names)
    end
  end

  def types, do: @types
end

Ответы [ 2 ]

0 голосов
/ 14 апреля 2019

Кажется, что теперь вся пользовательская функция может (с каких пор?) Быть заменена на Ecto.Changeset.update_change / 3

 |> update_change(:names, fn
     nil -> nil # or preferably []?
     names -> String.split(names, ~r{\r?\n})
    end)

или в стиле

 |> update_change(:names, &my_name_splitter/1)
0 голосов
/ 22 октября 2018

Попробуйте это:

defp validate_names(changeset) do
  case get_field(changeset, :names) do
    # Don't do anything if names don't exist
    nil ->
      changeset

    # Update names if they do exist
    names ->
      new_names = String.split(names, "\r\n")
      put_change(changeset, :names, new_names)
  end
end
...