Elixir 在回显查询中,用该结构的其他值动态替换该结构的某些值的最佳方法
我有一个功能:Elixir 在回显查询中,用该结构的其他值动态替换该结构的某些值的最佳方法,elixir,Elixir,我有一个功能: def listAll(dataSchema, fields) do dataSchema |> order() |> Repo.all() end 返回如下所示的查询结果: [%Skeleton.Data.Evento{__meta__: #Ecto.Schema.Metadata<:loaded, "eventos">, date: "dewfwef", date_de:
def listAll(dataSchema, fields) do
dataSchema |> order() |> Repo.all()
end
返回如下所示的查询结果:
[%Skeleton.Data.Evento{__meta__: #Ecto.Schema.Metadata<:loaded, "eventos">,
date: "dewfwef", date_de: nil, date_es: nil, date_fr: nil, date_pt: nil,
id: nil, inserted_at: nil, text: "hello", text_de: nil,
text_es: nil, text_fr: "Bonjour", text_pt: "Olá", title: "Good morning", title_de: nil, title_es: nil, title_fr: nil, title_pt: "Bom dia"},
%Skeleton.Data.Evento{__meta__: #Ecto.Schema.Metadata<:loaded, "eventos">,
date: "ds", date_de: nil, date_es: nil, date_fr: nil, date_pt: nil, id: nil,
inserted_at: nil, text: "Bye", text_de: nil, text_es: nil,
text_fr: nil, text_pt: "Adeus", title: "Good evening", title_de: nil, title_es: nil, title_fr: nil, title_pt: "Boa noite"}]
如何用text\u pt
(或字段中传递的任何键/键)的值自动替换日期、文本、标题(相同的键名,但没有后缀)的所有值?
请注意,我们事先不知道我们有哪些键,因为它们是作为参数逐例传递的,我希望在EXTO查询中执行此操作,而不是在生成的结构列表中执行此操作。下面是我如何执行此操作的,假设字段包含带字符串的区域设置键,例如“pt”
:
这将用动态计算字段的值替换text
的值
注意:您应该确保在某个时候使用白名单验证区域设置
。如果用户可以发送任意区域设置,那么创建atom会使VM崩溃。那就是:插值相当于String.to_atom(“text_35;{locale}”)
对于编辑后的问题:函数的API在我看来很奇怪。也许有一种更好的方法来实现你想要实现的目标。但如果你真的需要这样做,下面是我现在能想到的最简单的方法:
def listAll(dataSchema, fields) do
dataSchema
|> select([m], %{m | text: field(m, ^text_field)})
|> order()
|> Repo.all()
|> Enum.map(fn record ->
Enum.reduce(fields, record, fn field, record ->
# You might want to replace the Regex with something faster like `:binary.match` + `:binary.part` since you only need to find a '_' and remove everything after that.
without_suffix = field |> Atom.to_string |> String.replace(~r/_.*/, "") |> String.to_existing_atom
Map.put(record, without_suffix, Map.get(record, field))
end)
end)
end
为什么不动态访问您需要的字段而不是替换它们?因此,相反,调用my\u event[text\u language\u field]
,其中text\u language\u field
是:text\u de
,:text\u es
等变量之一。您的字段中似乎已经包含了该信息。@JustinWood是,但是像我要求的那样做,允许我简化我的模板,因为在迭代数据时,我总是只需调用I.text
,确保它包含我想要的翻译,因为它正在控制器中复制。抱歉,但直到现在我才意识到我无法完全解释我的需要。我刚刚编辑了这个问题。道伯特可以私下和你联系吗?@Dogbert你说得对。然而,每次我偶然发现一个问题,我都试图从我的角度理解一个解决方案,并将其与专家自己的观点进行比较,以便我真正学到东西。此外,我认为这些问题(我指的是你的精彩答案)可能会成为新来者了解长生不老药和凤凰城的一个很好的指南,因此通过问他们,我们正在记录他们(这也让我能够在一段时间后了解我的问题时跟踪我的发展):)所以,非常感谢!
def listAll(dataSchema, %{locale: locale}) do
text_field = :"text_#{locale}"
dataSchema
|> select([m], %{m | text: field(m, ^text_field)})
|> order()
|> Repo.all()
end
def listAll(dataSchema, fields) do
dataSchema
|> select([m], %{m | text: field(m, ^text_field)})
|> order()
|> Repo.all()
|> Enum.map(fn record ->
Enum.reduce(fields, record, fn field, record ->
# You might want to replace the Regex with something faster like `:binary.match` + `:binary.part` since you only need to find a '_' and remove everything after that.
without_suffix = field |> Atom.to_string |> String.replace(~r/_.*/, "") |> String.to_existing_atom
Map.put(record, without_suffix, Map.get(record, field))
end)
end)
end