我正在开展凤凰项目。我有以下型号:
defmodule MyApp.Exam do
use MyApp.Web, :model
alias Ecto.Changeset
alias MyApp.Repo
alias MyApp.TimexHelper
alias Timex.Date
import Ecto.Query
schema "exams" do
field :start_time, Timex.Ecto.DateTime
belongs_to :student, Student
timestamps
end
@required_fields ~w(student_id start_time)
def changeset(model, params \\ :empty) do
model
|> cast(params, @required_fields, @optional_fields)
|> assoc_constraint(:student)
|> is_in_future(:start_time)
end
def is_in_future(changes, field) do
new_time = Changeset.get_field(changes, field)
valid = TimexHelper.compare(new_time, Date.now)
if !valid, do: changes = Changeset.add_error(changes, field, "should be in the future")
changes
end
end
如何仅在is_in_future
操作期间对字段start_time
进行自定义验证insert
?
我尝试在if
中添加is_in_future
条件,以检查start_time
是否可用。但我认为这不是一个更好的解决方案。
我正在寻找类似的东西:
# Rails model field validation
validates_presence_of :start_time, :on => :create
答案 0 :(得分:1)
我不确定,但我认为没有类似rails的解决方案。您将在数据库调用之前创建变更集和验证。之后,您自己插入/更新模型。验证后,强制转换方法没有关于数据库调用的信息。
我的想法是在变更集函数中添加类似布尔值或原子的参数来定义验证类型。
func changeset(model, params \\ :empty, type \\ :insert) do
changeset = model
|> cast(params, @required_fields, @optional_fields)
|> assoc_constraint(:student)
case type do
:insert ->
is_in_future(changeset, :start_time)
:update ->
changeset
end
end
然后你应该致电changeset(model, params, :insert)
或changeset(model, params, :update)
。
希望它有所帮助。
编辑:
另一个想法是检查模型的id
是否设置为nil
。这与现有start_time
字段的想法相似。