peppy

peppy

How to pattern match list of structs from mysql results for multiple conditions?

I’m trying to build a simple function to see if a user is authorized to join a conversation. Basically, it needs to query the mysql database to get a list of all users in the conversation, and then compare the userid on the socket to the results list.

This is what I have so far:

 def join("conv:" <> convid, _message, socket) do
    if authorized?(convid, socket) do
      IO.inspect("join conversation " <> convid)
      send(self(), :after_join)
      {:ok, socket}
    else
      IO.inspect("not authorized to join room")
      :error
    end
  end

 defp authorized?(convid, socket) do
    IO.inspect("run conv auth function")
    results =
    from(m in GetUsersInConv, # use lib/app_web/schemas/usersinconv.ex
      where: m.id == ^convid,
      select: %{userid: m.userid, status: m.status}
    )
    |> Repo.all()
    userIdInSocket = socket.assigns.user_id
    IO.inspect("socket userid: " <> userIdInSocket)
    IO.inspect(results)
    # Need to add matching function next...
  end

These are the results I get, a list of all userids in the conversation and their status:

"run conv auth function"
[debug] QUERY OK source="conversations" db=0.7ms idle=1289.4ms
SELECT p0.`userid`, p0.`status` FROM `conversations` AS p0 WHERE (p0.`id` = ?) [107876]
"socket userid: 1"
[
  %{status: 0, userid: 1},
  %{status: 0, userid: 299},
  %{status: 0, userid: 664},
  %{status: 0, userid: 782},
  %{status: 0, userid: 1035},
  %{status: 0, userid: 4609},
  %{status: 0, userid: 4684},
  %{status: 0, userid: 5974},
  %{status: 0, userid: 6755},
  %{status: 0, userid: 6755},
  %{status: 0, userid: 8980},
  %{status: 0, userid: 9246},
  %{status: 0, userid: 10759},
  %{status: 0, userid: 15517},
  %{status: 0, userid: 16502},
  %{status: 0, userid: 32428},
  %{status: 0, userid: 61240},
  %{status: 0, userid: 79131},
  %{status: 0, userid: 98521},
  %{status: 3, userid: 145222}
]

If the userid of the socket is “1”, how can I build an Enum iteration function to match the following conditions:

  1. userid “1” is found within the result list of userids
  2. status != 3 AND status != 7 for that user as well.

If all those conditions are met, return “true”, otherwise “false” for the entire “authorized?” function.

I’m getting better and better at figuring out elixir, but syntax for enum and pattern matching is still a little tricky.

Thanks!

Marked As Solved

dimitarvp

dimitarvp

While I am not convinced that I understood your requirements well, this works:

defmodule UserChecks do
  def authorized?(user_id, %{userid: user_id, status: status}) when status not in [3, 7], do: true
  def authorized?(_user_id, %{userid: _other_user_id, status: _status}), do: false

  def any_authorized?(user_id, user_ids_and_statuses) when is_list(user_ids_and_statuses) do
    Enum.any?(user_ids_and_statuses, &authorized?(user_id, &1))
  end

  def test() do
    user_ids_and_statuses = [
      %{status: 0, userid: 1},
      %{status: 3, userid: 100},
      %{status: 7, userid: 200},
      %{status: 0, userid: 299},
      %{status: 0, userid: 664}
    ]

    IO.inspect(user_ids_and_statuses, label: "userids and statuses")
    IO.inspect(any_authorized?(1, user_ids_and_statuses), label: "Is userid 1 authorized?")
    IO.inspect(any_authorized?(2, user_ids_and_statuses), label: "Is userid 2 authorized?")
    IO.inspect(any_authorized?(100, user_ids_and_statuses), label: "Is userid 100 authorized?")
    IO.inspect(any_authorized?(200, user_ids_and_statuses), label: "Is userid 200 authorized?")
    IO.inspect(any_authorized?(299, user_ids_and_statuses), label: "Is userid 299 authorized?")
    IO.inspect(any_authorized?(664, user_ids_and_statuses), label: "Is userid 664 authorized?")
  end
end

authorized? basically emulates the match? you are trying to do. IMO a function with multiple pattern-matching heads reads better. Notice how user_id is specified twice in the first head; this a neat trick that matches only when there’s the same value in the first function argument and the userid field of the map.

But if you really must know how does it look with match?, here you go:

  def authorized?(searched_user_id, %{userid: _user_id, status: _status} = userid_and_status) do
    match?(
      %{userid: ^searched_user_id, status: status} when status not in [3, 7],
      userid_and_status
    )
  end

Also Liked

al2o3cr

al2o3cr

Both of these are expressible in SQL - for instance, you could rephrase the above as:

“does a row exist with user_id = 1 and status != 3 and status != 7”

Check out Repo.exists?.

Where Next?

Popular in Questions Top

sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
pgiesin
This should be a simple problem but I just can’t seem to figure it out. I have a standalone Elixir app that won’t find the database. Dep...
New
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
dokuzbir
Hello, I am trying to convert my lists to string without losing brackets.For start i have 3 map. They look like these buyer = %{ id: ...
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New

Other popular topics Top

shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
977 41022 311
New
AstonJ
You’re a programmer, so you don’t need spoon feeding with the conventional drivel about “this is an integer.” No. You need to know what’s...
New
_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 42633 214
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New

We're in Beta

About us Mission Statement