使用表名获取模型名称的惯用方法

时间:2018-01-05 05:04:10

标签: elixir ecto

阅读Ecto.schema.metadata时,我发现我们可以使用模型名称来获取该模型的表格,如下所示:

[
  Ecto.Schema.Metadata,
  nil,
  {nil, table_name},
  :built
] = Map.values(model_name.__struct__.__meta__)

我的问题是我们可以使用表名来获取该表的模型吗?

2 个答案:

答案 0 :(得分:2)

我们可以获取应用程序的所有模块,并找到定义了__schema__/1函数的模块,该函数在使用:source调用时返回表名:

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

答案 1 :(得分:1)

AFAIK,没有明确的方法来实现这一点,但由于我们在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`