elixir - 如何将条件管道添加到管道中?

时间:2016-05-07 04:33:22

标签: elixir ecto

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

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

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

所以,我的问题是:“我怎么能这样做?”

3 个答案:

答案 0 :(得分:14)

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

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

答案 1 :(得分:5)

管道非常适合无法运行的操作,并且所有这些操作都将被随身携带。如果你想停止管道,你就不能。你必须编写这样的函数:

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部分。

答案 2 :(得分:1)

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

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

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