#Create element in database when we have a reference

33 messages ยท Page 1 of 1 (latest)

pliant stirrup
#

Hi folks,
I have two tables in my database, i created them using "mix phx.gen.json", for the second table i add "user:references:users" to the command.
It create a column "user" links to my users table, a foreign key if correctly understood.

My question is ho to add data to my table ?
When i do a POST request (default create function) with all the parameter (for the user i give the id of the user) it create a line in the table, but my user column is null.
Is there a specific thing to do for adding this type of column ?
Thanks

gilded pecan
#

Can you upload your code?

abstract frigate
pliant stirrup
#

Thanks for your 2 responses, I was writing a complete response with the code and i saw i was just missing :user in the "|> cast(attrs, [:start, :end, :user])". ๐Ÿคฆโ€โ™‚๏ธ
What the cast really is, i don't understand ?

gilded pecan
#

cast basically lets you do "mass assignment" usually from the POST body etc, and does some data conversion as well for you

#

so you should be careful because if you cast like that any user making a request can set the user, even if they are not the real user

pliant stirrup
#

Ok, is there a good practice for that ? or just i correctly verify that the user who make the post is the real user

gilded pecan
#

generally don't allow mass assignment/casting of associations or other fields with security implications (like an admin boolean on user)

#

use put_assoc after you know it's ok

#

like a user can log in and have their identity attached to the session. you can look up this current_user and pass it to the changeset fn. In the changeset fn you just put_assoc(changeset, :user, current_user)

abstract frigate
#

Or in the cast right? As long as the value is from the server and not client-side

#

I.e. to put the user_id into params before sending to any of the changeset functions

gilded pecan
#

yes, you could always override it from a "trusted" source. but IMO it's better to provide it as a separate argument or map called trusted that makes it obvious

#

bugs around this are very scary

abstract frigate
#

Fair enough

pliant stirrup
#

Nice thanks for your complete response, i check that tomorrow !

#

Ho and do you know good resources to correctly learn elixir ?

gilded pecan
#

did you check out #getting-started ? It's been about 7 years for me so my knowledge is dated ๐Ÿ™‚

abstract frigate
gilded pecan
#

i've written a few but yeah ๐Ÿ™‚

abstract frigate
#

Ah, good stuff

pliant stirrup
#

Now this is working how can i get my user id back when i get the value ?
The json that is return to me looks like that and don't have the user id. I think it's a type of cast like yesterday but i dont know where to edit the return schema.

{
    "data": {
        "end": "2022-10-26T21:14:09",
        "id": 8,
        "start": "2022-10-26T21:14:09"
    }
}
abstract frigate
#

As in are you running Repo.get!/3 on your element and wanting to get back the user_id field?

pliant stirrup
#

Yes from a db, and yes I'm using Repo.get command

abstract frigate
#

What's your code?

#

I'm assuming it's:

def get_element!(id), do: Repo.get!(Element, id)
#

If so the user_id should be in the returned values, does your Element schema have a belongs_to :user, User field?

pliant stirrup
#

This is my schema, but i dont have the belong belongs_to :user, User

defmodule Timemanager.WorkingTime.WorkingTimes do
  use Ecto.Schema
  import Ecto.Changeset

  schema "workingtimes" do
    field :end, :naive_datetime
    field :start, :naive_datetime
    field :user, :id

    timestamps()
  end

  @doc false
  def changeset(working_times, attrs) do
    working_times
    |> cast(attrs, [:start, :end, :user])
    |> validate_required([:start, :end, :user])
  end
end

I'm using the get by id and the list all

 def get_working_times!(id), do: Repo.get!(WorkingTimes, id)

 def list_workingtimes do
   Repo.all(WorkingTimes)
 end
abstract frigate
#

belongs_to will create a user_id field, which is how I assume you have it stored in the database table

#

Whenever you're working with FKs use belongs_to , has_many and has_one as they're expected by a bunch of Ecto code, e.g. Changesets, also makes it clearer that it's a FK when you look at your schema