【问题标题】:How to check if struct is persisted or not?如何检查结构是否持久化?
【发布时间】:2017-03-25 04:53:01
【问题描述】:

有没有办法判断 struct 是否持久化?我开始为 Ecto 的insert_or_update 挖掘源代码,但没有运气,因为它遇到了一些私有方法。我想完成这样的事情:

def changeset(struct, params \\ %{}) do
  struct
  |> cast(params, [:whatever]
  |> do_a_thing_on_unsaved_struct 
end

defp do_a_thing_on_unsaved_struct(struct) do
  case ARE_YOU_PERSISTED?(struct) do
    :yes -> struct
    :no  -> do_things(struct)
  end
end

这可能吗,还是我在做一些愚蠢的事情?

【问题讨论】:

    标签: phoenix-framework ecto


    【解决方案1】:

    您可以检查结构的.__meta__.state。如果是新的(未持久化),则为:built,如果从数据库加载(持久化),则为:loaded

    iex(1)> Ecto.get_meta(%Post{}, :state)
    :built
    iex(2)> Ecto.get_meta(Repo.get!(Post, 1), :state)
    :loaded
    

    【讨论】:

    • 就是这样。谢谢。我还找到了Ecto.get_meta(struct, :state)。我的测试遇到了一些问题,但可能是我的工厂。
    • 实际上,我似乎以某种方式得到Ecto.Changeset,而不是我期望的结构:key :__meta__ not found in: #Ecto.Changeset<action: nil, changes: %{}, errors: [], data: #PedalApp.Waypoint<>, valid?: true>,即使它来自Repo.get!。这是怎么回事?
    • 没关系,我实际上是在传递变更集,而不是原始结构。
    • 你可以使用.data从变更集中获取结构,所以这将是Ecto.get_meta(changeset.data, :state)
    【解决方案2】:

    如果结构的主键是id,你可以检查struct.data.id

    defp do_a_thing_on_unsaved_struct(struct) do
      if struct.data.id, do: struct, else: do_things(struct)
    end
    

    【讨论】:

      猜你喜欢
      • 2018-03-18
      • 2017-12-04
      • 1970-01-01
      • 2016-12-16
      • 2013-04-12
      • 1970-01-01
      • 2011-03-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多