我正在学习灵丹妙药语言和凤凰网络框架。我有个主意。如果在web向导(多步表单)场景中,我将中间数据存储在ETS表中而不是关系数据库中,该怎么办?
所以我写了一个控制器:
defmodule PlayPhoenixWeb.ThingsController do
use PlayPhoenixWeb, :controller
require Logger
@moduledoc false
@form_ets :things_forms
alias PlayPhoenixWeb.Router.Helpers, as: Routes
alias PlayPhoenixWeb.Endpoint
def step_1_display(conn, _params) do
render(conn, "form_1.html")
end
def step_1_process(conn, params) do
data = Map.take(params, ["name", "vcode"])
key = make_key()
write_data(key, data)
Logger.debug inspect(data)
redirect(conn, to: Routes.thing_form_2_path(Endpoint, :step_2_display, key))
end
def step_2_display(conn, %{"key" => key}) do
render(conn, "form_2.html", key: key)
end
def step_2_process(conn, %{"key" => key} = params) do
{:ok, data} = get_data(key)
full_data = Map.take(params, ["description", "value"]) |> Map.merge(data)
# In production, processing full data would happen here
Logger.debug inspect(full_data)
redirect(conn, to: Routes.page_path(Endpoint, :index))
end
# This method is called by the Application on startup
def init_ets(), do: :ets.new(@form_ets, [:public, :named_table])
defp make_key(), do: :crypto.hash(:md5, DateTime.utc_now() |> DateTime.to_iso8601) |> :base64.encode
defp get_data(key) do
case :ets.lookup(@form_ets, key) do
[{^key, value}] -> {:ok, value}
_ -> {:not_found}
end
end
defp write_data(key, data) do
:ets.insert(@form_ets, {key, data})
end
defp delete_data(key), do: :ets.delete(@form_ets, key)
end(这纯粹是为了玩/研究,目前不存储或处理任何数据)。
这是灵丹妙药/凤凰城的方式吗?
非常感谢。
发布于 2019-03-07 17:46:00
是的,对这类临时数据使用ETS是完全正确的,当然,只要您意识到,只要您重新启动服务器时,所有的中间状态都会丢失。事实上,如果你稍微深入研究一下凤凰和药剂,你会看到很多ETS的使用--这并不是你在特殊情况下会用到的东西,而更多的是在相同级别(比如GenServer )的广泛工具箱中的一个工具。
发布于 2019-02-27 00:11:17
在药剂上不能说太多,但是,make_key -为什么要在当前的字符串格式(以什么分辨率)上使用MD5呢?几秒钟?因此,当你只需要生成一组固定长度的随机数时,你就会很快地得到副本。另外,您可能也可以传递随机数的来源,然后突然变得更容易测试(因为1.您不依赖于当前时间,2.您不是在全局随机数生成器上)。
https://codereview.stackexchange.com/questions/214140
复制相似问题