【问题标题】:elixir - how to add conditional pipe into pipeline?长生不老药 - 如何将条件管道添加到管道中?
【发布时间】:2016-05-07 04:33:21
【问题描述】:

我在 elixir 中有一个小管道,它是关于更改 ecto 模型状态:

model
|> cast(params, ~w(something), ~w())
|> conditional
|> Repo.update

问题是我有 conditional 管道,它有时可以是 nil,所以在它为 nil 的情况下,它应该什么都不做并且可以工作(我想它会是 fn(x) -> x end

所以,我的问题是:“我该怎么做”?

【问题讨论】:

  • 所以conditional 是函数还是 nil?

标签: elixir ecto


【解决方案1】:
model
|> cast(params, ~w(something), ~w())
|> maybe_do_something(conditional)
|> Repo.update

defp maybe_do_something(changeset, nil), do: changeset

defp maybe_do_something(changeset, func) do
  # Do something with changeset
end

不确定我的问题是否正确,但也许这就是你要找的。​​p>

【讨论】:

    【解决方案2】:

    管道非常适合不会失败的操作,并且所有这些操作都将始终被携带。如果你想停止管道,你不能。您必须编写如下函数:

    maybe_repo_update(nil), do: nil
    maybe_repo_update(data), do: Repo.update(data)
    

    为了解决这个问题,Elixir 1.2 中有一个新的特殊形式,称为with。它可以在不匹配的那一刻停止管道:

    with changeset <- cast(model, params, ~w(something), ~w())
      {:ok, changeset} <- conditional_operation(changeset)
      {:ok, model} <- Repo.insert(changeset)
    

    这将确保如果条件操作返回 {:ok, changeset} 以外的其他内容,它将不会尝试运行最后一个 repo 插入。在 Elixir 1.3 中,您还可以使用 else 部分。

    但是对于变更集,更常见的是使用@JustMichael 建议的解决方案:

    def conditional(changeset) do
      if something_to_do do
        transform(changeset)
      else
        changeset
      end
    end
    

    此解决方案将始终运行 Repo.update 部分。

    【讨论】:

      【解决方案3】:

      我是Elixir新手,请不要太苛刻:)。

      为什么不为此使用匿名函数?

      model
      |> cast(params, ~w(something), ~w())
      |> (fn(n) -> conditional && n |> Repo.update || n end).()
      

      【讨论】:

      • 这是一个很好的问题? 在 Elixir 和其他函数式编程社区(如 Elm)中,普遍鼓励明确且易于阅读。这里有一个关于这个一般主题的好视频:youtube.com/watch?v=trgET9YU37M
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-29
      • 1970-01-01
      • 1970-01-01
      • 2016-02-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多