How can I refactor this elixir code

I would like to refactor the following code.
The first thing that comes to my mind is to extract the case block into a new method,
but maybe there is a better solution?

  def start_conversation(chat_id, user_id, participant) do
    {first_user_id, second_user_id} =
      case participant.gender do
        "female" -> {participant.user_id, user_id}
        "male" -> {user_id, participant.user_id}
      end

    params = %{
      chat_id: chat_id,
      start_time: DateTime.utc_now,
      first_user_id: first_user_id,
      second_user_id: second_user_id
    }
    Db.Conversation.create(params)
  end

Extracting the case statement to a function would also mandate that function have 2 parameters: participant and user_id. And since your case statement is only 5 lines long I don’t think the extraction would make the code better in any way.

I think the code is fine. Do always run mix format though, I’d write DateTime.utc_now() and not DateTime.utc_now – always put parentheses even when calling functions without an argument.

2 Likes

I’d split it into few more specific functions so that each of them does less and has less variables, something like this:

def start_conversation(chat_id, user_id, %{gender: "female", user_id: participant_user_id}) do
  create_conversation(chat_id, participant_user_id, user_id)
end

def start_conversation(chat_id, user_id, %{gender: "male", user_id: participant_user_id}) do
  create_conversation(chat_id, user_id, participant_user_id)
end

defp create_conversation(chat_id, first_user_id, second_user_id) do  
  Db.Conversation.create(%{
      chat_id: chat_id,
      start_time: DateTime.utc_now,
      first_user_id: first_user_id,
      second_user_id: second_user_id
    })
end
4 Likes