使用 table 名称获取模型名称的惯用方法
Idiomatic way to get model name by using table name
阅读 Ecto.schema.metadata
时,我发现我们可以使用模型名称来获取该模型的 table,如下所示:
[
Ecto.Schema.Metadata,
nil,
{nil, table_name},
:built
] = Map.values(model_name.__struct__.__meta__)
我的问题是我们可以使用 table 名称来获取 table 的型号吗?
据我所知,没有明确的方法可以实现这一点,但由于我们在 Elixir 中,所以一切皆有可能:
with {:ok, mods} <- :application.get_key(:my_app, :modules) do
mods
|> Enum.filter(fn mod ->
try do
apply(mod, :__schema__, [:source]) == "users"
rescue
e in UndefinedFunctionError -> false
end
end)
|> hd()
end
#⇒ MyApp.User # OR `nil`
或者,更精确的检查:
with {:ok, mods} <- :application.get_key(:my_app, :modules) do
mods
|> Enum.filter(fn mod ->
if apply(mod, :__info__, [:functions])[:__schemas__],
do: apply(mod, :__schema__, [:source]) == "users"
end)
|> hd()
end
#⇒ MyApp.User # OR `nil`
我们可以获取应用程序的所有模块,并找到具有 __schema__/1
函数定义的模块,当使用 :source
调用时,returns 名称为 table:
table = "posts"
Application.spec(:my_app, :modules)
|> Enum.find(fn module ->
function_exported?(module, :__schema__, 1) &&
module.__schema__(:source) == table
end)
|> IO.inspect
输出:
MyApp.Post
阅读 Ecto.schema.metadata
时,我发现我们可以使用模型名称来获取该模型的 table,如下所示:
[
Ecto.Schema.Metadata,
nil,
{nil, table_name},
:built
] = Map.values(model_name.__struct__.__meta__)
我的问题是我们可以使用 table 名称来获取 table 的型号吗?
据我所知,没有明确的方法可以实现这一点,但由于我们在 Elixir 中,所以一切皆有可能:
with {:ok, mods} <- :application.get_key(:my_app, :modules) do
mods
|> Enum.filter(fn mod ->
try do
apply(mod, :__schema__, [:source]) == "users"
rescue
e in UndefinedFunctionError -> false
end
end)
|> hd()
end
#⇒ MyApp.User # OR `nil`
或者,更精确的检查:
with {:ok, mods} <- :application.get_key(:my_app, :modules) do
mods
|> Enum.filter(fn mod ->
if apply(mod, :__info__, [:functions])[:__schemas__],
do: apply(mod, :__schema__, [:source]) == "users"
end)
|> hd()
end
#⇒ MyApp.User # OR `nil`
我们可以获取应用程序的所有模块,并找到具有 __schema__/1
函数定义的模块,当使用 :source
调用时,returns 名称为 table:
table = "posts"
Application.spec(:my_app, :modules)
|> Enum.find(fn module ->
function_exported?(module, :__schema__, 1) &&
module.__schema__(:source) == table
end)
|> IO.inspect
输出:
MyApp.Post