我正在尝试使用此十六进制包:https://github.com/meh/amnesia
这是我的架构:
use Amnesia
require Logger
require IEx
defdatabase Database do
deftable User, [{ :id, autoincrement }, :device_identifier, :match_history], type: :ordered_set, indices: [:device_identifier] do
@type t :: %User{ id: non_neg_integer, device_identifier: String.t, match_history: List.t }
...
end
end
这是错误发生的地方:
Amnesia.transaction do
// IEx.pry
queue = User.where(:device_identifier != device_identifier)
if queue do
Logger.info "dequeuing another user"
matched_user = List.first(queue.values)
matched_user |> User.delete
push socket, "match_found", %{ device_identifier: matched_user.device_identifier }
else
Logger.info "queuing user"
push socket, "queued", %{}
end
end
当我尝试拨打matched_user.device_identifier
时,它失败了。但这不是模型的属性吗?在github repo的README中,它在Message模型上调用content
,那么为什么我不能在我的User模型上对device_identifier
执行相同的操作呢?
我甚至尝试使用id
字段:
pry(8)> matched_user.id
** (UndefinedFunctionError) function Database.User.id/1 is undefined or private. Did you mean one of:
* id/0
有没有办法找出我的matched_user对象响应的方法?
答案 0 :(得分:3)
默认情况下,Amnesia会为每个匹配的条目返回一个元组,而不是相应的结构,例如,在您的情况下,它返回{Database.User, 2, "5pyia9cej4", nil}
。为了从原始查询结果中获取结构,Amnesia提供了一个方便的函数Amnesia.Selection.values/1
。以下更改应该有效:
替换
matched_user = List.first(queue.values)
与
matched_user = List.first(Amnesia.Selection.values(queue))
您可能还希望在此处使用模式匹配来使代码更加惯用:
[matched_user | _] = Amnesia.Selection.values(queue)
答案 1 :(得分:0)
@Edmund关于如何更新现有记录的评论中的问题。无法格式化评论中的代码,所以我发布了答案。刚刚接受它。这是一个小函数,似乎可以解决如何更新记录的问题。首先,您必须选择需要更新的记录。我是Elixir的新手,但我认为它并不是那么糟糕:
def update_value(entity_id) do
Amnesia.transaction do
entity = Entity.where entity_key == entity_id
end
|> Amnesia.Selection.values
|> Enum.each(fn e ->
Amnesia.transaction do
%Entity{e | status: :started} |>
Entity.write()
end
end)
end