How to update given values in database

Hi guys! How can I update values in the database, with new values? Shortly about my app:
The user can give someone’s points (max. 50 per month). I have managed to create a system of grants with validation (check, whether a user may give some points, 'cause he may be running out of them for a given month).

I do have two functions, that are related with granting points:

  1. add()
  def add(conn, %{"user" => userID}) do
    changeSet = RewardappWeb.User.changeset(%RewardappWeb.User{}, %{})
    users = Rewardapp.Repo.all(RewardappWeb.User)
    IO.puts("I am in add ++++++++")
    #IO.inspect(params)
    IO.inspect(userID)

    render(conn, "add.html", changeSet: changeSet, users: users, userID: userID)
  end
  1. update()
 def update(conn, params) do
    changeSet = RewardappWeb.User.changeset(%RewardappWeb.User{}, %{})
    users = Rewardapp.Repo.all(RewardappWeb.User)
    IO.puts("I am in update function +++++")
    IO.inspect(params)
    user = params["user"]
    IO.inspect(user)
    points = String.to_integer(user["points"])
    IO.inspect(points)

    id = String.to_integer(params["id"])
    IO.inspect(id)

    #GETTING USER INFO FROM SESSION, TO TAKE VALUES TO UPDATE

    sessionUser = Plug.Conn.get_session(conn, :userInfo)
    IO.inspect(sessionUser)
    currentMonth = currentMonth(conn)
    IO.inspect(currentMonth)

    currentPoints = Map.get(sessionUser, String.to_atom(currentMonth))
    IO.inspect(currentPoints)


    #changeSet = RewardappWeb.User.changeset(Rewardapp.User, String.to_atom(currentMonth))

    case result = currentPoints - points do
      result when result < 0 ->
        IO.puts("THE RESULT IS LESS THEN ZERO")
        conn
        |> put_flash(:error, "You do not have enough points.")
        |> redirect(to: Routes.grant_path(conn, :add, %{"user" => id}))
      result when result >= 0 ->
        IO.puts("THE RESULT IS GREATER OR EQUAL ZERO")
        conn
        |> put_flash(:info, "Added points")
        |> redirect(to: Routes.grant_path(conn, :main))
        #|> Plug.Conn.delete_session(:userInfo)
    end
  end

Case statement in update function works correctly, and redirection as well. I do store logged user in session called :userInfo, and there is every single data taken from a database.
My goal is to delete points, that he has rewarded to some user (but deleted for this given month), and then update points (the same, for a given month) for the user, that was given a points.

This is how my :userInfo (value from session) looks like:

%RewardappWeb.User{
  __meta__: #Ecto.Schema.Metadata<:loaded, "users">,
  april: 50,
  august: 50,
  december: 50,
  february: 50,
  id: 1,
  january: 50,
  july: 50,
  june: 50,
  march: 50,
  may: 50,
  name: "mat",
  november: 50,
  october: 50,
  points: 0,
  role: "member",
  september: 50,
  surname: "osinski"
}

And here is my user.ex

defmodule RewardappWeb.User do
  use Ecto.Schema
  import Ecto.Changeset


  schema "users" do
    field :april, :integer
    field :august, :integer
    field :december, :integer
    field :february, :integer
    field :january, :integer
    field :july, :integer
    field :june, :integer
    field :march, :integer
    field :may, :integer
    field :name, :string
    field :november, :integer
    field :october, :integer
    field :points, :integer
    field :role, :string
    field :september, :integer
    field :surname, :string
  end

  @spec changeset(
          {map, map}
          | %{
              :__struct__ => atom | %{:__changeset__ => map, optional(any) => any},
              optional(atom) => any
            },
          :invalid | %{optional(:__struct__) => none, optional(atom | binary) => any}
        ) :: Ecto.Changeset.t()
  @doc false
  def changeset(user, attrs \\ %{}) do
    user
    |> cast(attrs, [:name, :surname, :role, :points, :january, :february, :march, :april, :may, :june, :july, :august, :september, :october, :november, :december])
    |> validate_required([:name, :surname, :role, :points, :january, :february, :march, :april, :may, :june, :july, :august, :september, :october, :november, :december])
  end
end

Could you guys give me any hints, on how could I update these values in my database? I would be glad for any help!!! <3

Changeset does not trigger the change itself but is just a representation of intended changes. You need to pass it to Repo.update in order for DB to apply it.

2 Likes

Thanks! I have done like you have said, but I got error :frowning:
Here is code:

 case result = currentPoints - points do
      result when result < 0 ->
        IO.puts("THE RESULT IS LESS THEN ZERO")
        conn
        |> put_flash(:error, "You do not have enough points.")
        |> redirect(to: Routes.grant_path(conn, :add, %{"user" => id}))
      result when result >= 0 ->
        IO.puts("THE RESULT IS GREATER OR EQUAL ZERO")

        post = Rewardapp.Repo.get!(RewardappWeb.User, sessionUser.id)
        post = Ecto.Changeset.change RewardappWeb.User, String.to_atom(currentMonth), result

        conn
        |> put_flash(:info, "Added points")
        |> redirect(to: Routes.grant_path(conn, :main))
        #|> Plug.Conn.delete_session(:userInfo)
    end
  end

And the error is function Ecto.Changeset.change/3 is undefined or private
Do you have any idea, what I have done wrong?

The error tells you what’s wrong: There is no Ecto.Changeset.change/3, but only a Ecto.Changeset.change/2. I’d suggest looking at the docs for the function to see how it’s intended to be used.