Create function to update a value from another table

Before asking the question, I will go over how is my database structure …
Table user = user, email, password, profile_id
Profile table = first name, last name, avatar

Question:
How do I create a function inside the profile controller, to update the profile_id from the User table?

I currently did this.
But it did not work.
can you help me?

profile_controller.ex

  def create(conn, %{"profile" => profile_params}) do

      case Structure.create_profile(profile_params) do
      {:ok, profile} ->
        conn
        |> ProjectWeb.ProfileController.update_profileid()
        |> put_flash(:info, "Perfil criado com sucesso.")
        |> redirect(to: Routes.profile_path(conn, :show, profile))

      {:error, %Ecto.Changeset{} = changeset} ->
        render(conn, "new.html", changeset: changeset)
    end
  end

  def update_profileid(_, %{"id" => id}) do
    profile = Structure.get_profile!(id)
    user = Repo.get!(User, 1)
    changeset = User.changeset(user, %{"profile_id" => profile})
    Repo.update!(changeset)
  end

Hi @gilbertosj,
Why didn’t it work? Were there errors. If so, could you post them.

From a brief code inspection it looks like

changeset = User.changeset(user, %{"profile_id" => profile})

should be

changeset = User.changeset(user, %{"profile_id" => profile.id})

But if you are setting up associations properly in Ecto there are other different methods for creating the links between entities (e.g. put_assoc), but you don’t need to if you are happy to update the id’s directly.

Hi @mindok

The error and this one below

[debug] QUERY OK db=73.4ms
INSERT INTO “profiles” (“department_id”,“group_id”,“name”,“role”,“surname”,“inserted_at”,“updated_at”) VALUES ($1,$2,$3,$4,$5,$6,$7) RETURNING “id” [1, 1, “Test1”, “test3”, “Test2”, ~N[2019-12-09 01:35:05], ~N[2019-12-09 01:35:05]]
[info] CONNECTED TO Phoenix.LiveView.Socket in 221µs
Transport: :websocket
Serializer: Phoenix.Socket.V2.JSONSerializer
Connect Info: %{}
Parameters: %{“vsn” => “2.0.0”}
[info] Sent 500 in 86ms
[error] #PID<0.1101.0> running ProjectWeb.Endpoint (connection #PID<0.1100.0>, stream id 1) terminated
Server: localhost:4000 (http)
Request: POST /profiles


** (exit) an exception was raised:
** (UndefinedFunctionError) function ProjectWeb.ProfileController.update_profileid/1 is undefined or private

Could you tell me how to call this function inside create?

has arity 2, ie the function is ProjectWeb.ProfileController.update_profileid/2

but you are calling it with only one argument, and you are passing in the connection not the profile.

Your code should probably look something like this (although the linking of user & profile probably shouldn’t happen in your controller anyway):

alias Structure.Profile 
def create(conn, %{"profile" => profile_params}) do

      case Structure.create_profile(profile_params) do
      {:ok, profile} ->
        profile 
        |> ProjectWeb.ProfileController.update_profileid()
        
        conn
        |> put_flash(:info, "Perfil criado com sucesso.")
        |> redirect(to: Routes.profile_path(conn, :show, profile))

      {:error, %Ecto.Changeset{} = changeset} ->
        render(conn, "new.html", changeset: changeset)
    end
  end

  def update_profileid(%Profile{}=profile) do
    user = Repo.get!(User, 1)
    changeset = User.changeset(user, %{"profile_id" => profile.id})
    Repo.update!(changeset)
  end

It really was that, everything went right here.
I had never done anything like it …

Thank you very much.

1 Like