I am using memento to wrap Mnesia functionality into my application.
I want to check if a record with a certain id exists and if not perform certain actions.
Documentation says read should return nil when record doesn’t exist. Howerver, the Memento.transation wrapper aborts with a :not_exists
exception therefore my application cannot proceed.
Here’s how my function looks like:
def find_conversation(user_id) do
Memento.transaction! fn ->
user_id
|> read
|> to_conversation
end
end
defp to_conversation(nil), do: nil
defp to_conversation(%@store{} = conversation) do
struct(Conversation, Map.from_struct(conversation))
end
I cannot test it now, but I think you need to call to_conversation/1
outside the Memento transaction.
This is how I do in my app…
To get a resource:
def get_todo!(uid) do
_read_transaction(uid)
end
To read it from Mnesia:
defp _read_transaction(uid) do
result = Memento.transaction fn -> Memento.Query.read(Todo, uid) end
_parse_fetch_result(result)
end
To parse the result of reading it from Mnesia:
defp _parse_fetch_result(result) do
case result do
{:ok, nil} ->
[]
{:ok, []} ->
[]
{:ok, todo} ->
todo
{:error, error} ->
Logger.error("_parse_resul/1: #{error}")
Todo.new_changeset()
end
end
To note that the returned values foreach case
are specific to my app.
Also bear in my mind that is app serves as a Learning path for me to know more about Mnesia and Elixir, thus I may also not doing it in the best way
1 Like
Thanks for your feedback. I followed your advise, no joy. This is how I did it but result is same
def find_conversation(user_id) do
results = Memento.transaction! fn -> read(user_id) end
results
|> to_conversation
end