我将一个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
试试这个:
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
似乎整个自定义函数现在可以(因为何时?)被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)