Elixir + Amnesia:如何阅读属性?

时间:2016-12-06 16:55:43

标签: elixir phoenix-framework

我正在尝试使用此十六进制包: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对象响应的方法?

2 个答案:

答案 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