【发布时间】:2017-01-02 17:13:19
【问题描述】:
(代码引用已匿名)
在我的凤凰模型中,我有一些多余的方法,比如这个基本的:
def build(params) do
changeset(%__MODULE__{}, params)
end
由于我将它们放在我的模型模块中,它们工作正常,但我想避免代码重复,我想通过这样的帮助模块使它们可用于我的所有模型:
defmodule MyApp.Helpers.Model do
defmodule Changeset do
defmacro __using__(_opts) do
quote do
def build(params) do
changeset(%__MODULE__{}, params)
end
end
end
end
end
这样做,我得到一个错误:
== Compilation error on file lib/my_app/model/my_model.ex ==
** (CompileError) lib/my_app/model/my_model.ex:3: MyApp.Model.MyModel.__struct__/1 is undefined, cannot expand struct MyApp.Model.MyModel
(stdlib) lists.erl:1354: :lists.mapfoldl/3
相关模型基本上是这样的:
defmodule MyApp.Model.MyModel do
use MyApp.Helpers, :model
use MyApp.Helpers.Model.Changeset # here for comprehension, should be in MyApp.Helpers quoted :model method
schema "my_table" do
field :name, :string
timestamps()
end
@required_fields ~w(name)a
@optional_fields ~w()
@derive {Poison.Encoder, only: [:name]}
def changeset(model, params \\ %{}) do
model
|> cast(params, @required_fields)
|> cast(params, @optional_fields)
|> validate_required(@required_fields)
|> validate_format(:name, ~r/^[a-z]{3,}$/)
|> unique_constraint(:name)
end
end
我认为这是因为该模块尚未在宏中的编译时定义,但我不确定,也不知道如何解决此问题并使其正常工作。
非常感谢这里的一些灯,谢谢。
【问题讨论】:
-
你能把你
use这个模块所在的模块的代码贴出来吗? -
您可能应该在
MyModel模块中交换use MyApp.Helpers.Model和defstruct MyModel行,让后者(结构声明)先行。 -
好的,按照@mudasobwa 的建议,我将
use MyApp.Helpers.Model.Changeset放在schema调用之后,该调用在MyModel中生成结构,它可以工作。所以我想没有办法把这个use全局放在凤凰通常的MyApp.Helpers, :model中,因为我们需要先定义模式? -
@Dogbert 我在问题中添加了
MyModel定义,谢谢。 -
您可以使用
@after_compile回调来实现此功能。
标签: elixir phoenix-framework ecto