go-gorm / gorm

The fantastic ORM library for Golang, aims to be developer friendly
https://gorm.io
MIT License
37.02k stars 3.94k forks source link

Defing models with foreign entities #7239

Open Pismice opened 1 month ago

Pismice commented 1 month ago

Your Question

type RealWorkout struct {
    gorm.Model
    TemplateID int
    Template   Workout
    WorkoutID  int
}

I have an entity RealWorkout which possesses 1 Workout which is supposed to act as a Template. In order to have my code working I have to have 3 fields:

  1. The "real" Workout
  2. The ID of this workout but named WorkoutID
  3. The ID of this workout but named TemplateID

2 is needed because even with a model without WorkoutID I get workout_id field in my DB and I sometimes have to set it using WorkoutID

3 is needed because otherwise at compilation I get the following error: [error] invalid field found for struct gin-app/misc.RealWorkout's field Template: define a valid foreign key for relations or implement the Valuer/Scanner interface

The document you expected this should be explained

I am not a native english speaker but I did not understand what you excepted from me in this chapter :(

Expected answer

Having all those 3 fields seem very repetitive and error prone, ideally it should be possible to only have Template Workout ? I do not get why I also need an ID field and even more why it has to have specific names, I searched through this and did not find an answer: https://gorm.io/docs/belongs_to.html Am I doing my model wrong ? What is really needed ? What do I need that ID field even though it is a repetition of my Workout.ID

omidfth commented 1 month ago

Hi, you must use Pointer for Template instead of using a value object. for example, use Template *Workout.

Pismice commented 1 month ago

Why isnt it that way in the doc ?? https://gorm.io/docs/has_one.html

type User struct {
  gorm.Model
  CreditCard CreditCard
}

type CreditCard struct {
  gorm.Model
  Number string
  UserID uint
}
Pismice commented 1 month ago

Hi, you must use Pointer for Template instead of using a value object. for example, use Template *Workout.

And I still have errors when doing this:

type Child struct {
    gorm.Model
    Name string
}

type Parent struct {
    gorm.Model
    Name   string
    Enfant *Child
}
omidfth commented 1 month ago

You still have errors because: You don't have any foreign key in the child structure. Add ParantID unit to the child structure.

Pismice commented 1 month ago

You still have errors because:

You don't have any foreign key in the child structure. Add ParantID unit to the child structure.

Why not in the parent structure ?

omidfth commented 1 month ago

Imagine the raw query in SQL:

question:
select parent and parent's child name where ID is one.

answer:
SELECT (p.id, p.name, c.name) from parents p WHERE p.id = 1 INNER JOIN child  c ON c.parent_id = p.id;

the child linked to parent => child has parent_id

Now, if any parent has too many children, you have to use an array of children in the parent structure.

Pismice commented 1 month ago

well its the parent that should hold the child_id and not the child that should hold the parent_id. So I dont get your example