在Ecto中更新数组

时间:2017-05-01 14:14:59

标签: elixir

我有以下型号:

 schema "users" do
        field :email, :string
        field :subscriptions, {:array, :string}

        timestamps()
    end

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

我无法弄清楚如何从我的控制器更新subscriptions-array。我希望简单地将一个新字符串推送到数组:

def subscribe(conn, %{"category" => category} ) do
        IO.puts category # Will print "whatever_category"
        user = Repo.get(User, conn.assigns.user.id)
        changeset = User.changeset(user, ?)
        Repo.update(changeset)

我尝试过以下方法:

changeset = User.changeset(user, %{subscriptions: ["test"]})

这增加了" test"到数组但如果我添加另一个值将被替换。

谢谢!

1 个答案:

答案 0 :(得分:7)

由于您已经加载了旧值,因此最简单的方法是将值附加到旧列表并将其传递给User.changeset/2

User.changeset(user, %{subscriptions: user.subscriptions ++ ["test"]})

Ecto还支持push操作,该操作可以使用Repo.update将项目推送到数组,而无需加载旧值。记录此功能here。例如:

from(u in User, where: u.id == 123) |>
  Repo.update_all(push: [subscriptions: "test"])

from(u in User, where: u.id == 123, update: [push: [subscriptions: "test"]])) |>
  Repo.update_all([])