Elixir Ecto - 如何进行升值/增量

时间:2017-02-10 03:35:10

标签: elixir phoenix-framework ecto

我有一个模型,我想在Phoenix / Elixir中执行。该模型基本上计算用户花费的金额的总和。模型(Receipts)如下所示:

---------------
| ID | Amount |
---------------
| 1  |   0    |
| ...|  ...   |
| 5  |   4    |
---------------

ID上有一个唯一索引。我想在表中插入用户(我定义ID),然后在用户不存在时设置金额,否则将新金额添加到现有金额。例如,执行:

Repo.insert(Users.changeset(%Users{}, %{ID: 1, Amount: 10})

会导致:

---------------
| ID | Amount |
---------------
| 1  |   11   |
| ...|  ...   |
| 5  |   4    |
---------------

并执行Repo.insert(%Users {},Users.changeset(%{ID:6,Amount:5})将导致:

---------------
| ID | Amount |
---------------
| 1  |   11   |
| ...|  ...   |
| 5  |   4    |
| 6  |   5    |
---------------

我知道我应该用:on_conflict做点什么,但我有点迷失如何做对。有人能以正确的方式指出我吗?

3 个答案:

答案 0 :(得分:6)

当然,这是可能的。它看起来像这样:

iex> amount_to_add = 10
10
iex> Repo.get(User, 1)
nil
iex> Repo.insert(%User{id: 1, amount: amount_to_add}, conflict_target: :id, on_conflict: [inc: [amount: amount_to_add]])
...
iex> Repo.get(User, 1)
%User{id: 1, amount: 10, ...}
iex> Repo.insert(%User{id: 1, amount: amount_to_add}, conflict_target: :id, on_conflict: [inc: [amount: amount_to_add]])
...
iex> Repo.get(User, 1)
%User{id: 1, amount: 20, ...}

答案 1 :(得分:3)

$query = mysqli_query("SELECT COUNT(ID) From your-table",$conn);
$result = mysqli_fetch_array($query);
$total = $row[0];

if($total<20){
   //INSERT NEW ROW
   $query = "INSERT INTO your-table() values(...,...)";
   //etc ...
} else{
   // DELETE THE FIRST ROW
   $query = "DELETE FROM your-table ORDER BY ID ASC LIMIT 1";
   // Then insert new row, etc...
}

这是使用postgreSQL语法进行锁定的一种方法。我猜你会弄明白其余的。

答案 2 :(得分:0)

添加到第一个答案 更新后返回变量将防止并行问题。

iex> Repo.insert(%User{id: 1, amount: amount_to_add},  returning: [:amount], conflict_target: :id, on_conflict: [inc: [amount: amount_to_add]])