如何为基于Ecto Query的模式匹配选择不同的片段?

时间:2016-07-27 03:45:40

标签: elixir ecto

是否可以模式匹配Ecto fragment

  • 我想为我的查询添加额外字段
  • 其中一个是Place保存特定Visitors的次数 - 始终相同
  • 第二个是模式匹配的:
    • 如果Visitor保存了Place - true / false
    • ,我现在可以提前预约
    • 我需要检查Visitor's ID是否在保存此地点的Visitors ID列表中

我可以通过模式匹配来实现吗?

defmacrop saved_count(place_id) do
  quote do
    fragment(
      "(SELECT count(id) FROM \"saved_places\" WHERE place_id = ?)",
      unquote(place_id)
    )
  end
end

defmacrop saved_by_visitor?(place_id, saved_by_visitor)
when is_boolean(saved_by_visitor) do
  quote do
    fragment(
      "(?)::BOOLEAN",
      ^unquote(saved_by_visitor)
    )
  end
end

defmacrop saved_by_visitor?(place_id, visitor_id) do
  {:ok, binary_visitor_id} = Ecto.UUID.dump(visitor_id)

  quote do
    fragment(
      "(SELECT ? = ANY(array_agg(visitor_id)) FROM \"saved_places\" WHERE place_id = ?)",
      ^binary_visitor_id,
      unquote(place_id)
    )
  end
end

defp add_extra_fields(query, saved_by_visitor) do
  from places in query,
    group_by:  places.id,
    select:    %{places |
                 saved_count:     saved_count(places.id),
                 saved_by_visitor: saved_by_visitor?(places.id, saved_by_visitor)
               }
end

错误在于:

no match of right hand side value: :error

因为我无法直接将saved_by_visitor值传递给宏。

编辑:

我提出以下问题:

defmacrop saved_by_visitor?(place_id, saved_by_visitor)
when is_boolean(saved_by_visitor) do
  quote do
    fragment(
      "(?)::BOOLEAN",
      ^unquote(saved_by_visitor)
    )
  end
end

defmacrop saved_by_visitor?(place_id, visitor_id) do
  quote do
    fragment(
      "(SELECT ? = ANY(array_agg(visitor_id)) FROM \"saved_places\" WHERE place_id = ?)",
      ^Ecto.UUID.dump(unquote(visitor_id)),
      unquote(place_id)
    )
  end
end

defp add_extra_fields(query, saved_by_visitor) do
  from places in query,
    group_by:  places.id,
    select:    %{places |
                 saved_count:     saved_count(places.id),
                 saved_by_visitor: saved_by_visitor?(places.id, saved_by_visitor)
               }
end

但是当然还有保护和模式匹配的问题。

0 个答案:

没有答案