For example, I have the following models
type Company struct {
ID uint `gorm:"PRIMARY_KEY"`
Name string
Departments []*Department `gorm:"FOREIGNKEY:CompanyID"`
Managers []*Manager
}
type Department struct {
ID uint `gorm:"PRIMARY_KEY"`
Name string
Managers []*Manager `gorm:"FOREIGNKEY:DepartmentID"`
CompanyID uint
}
type Manager struct {
ID uint `gorm:"PRIMARY_KEY"`
Name string
DepartmentID uint
}
That is, company has many departments, and department has many managers. How can I create an association between company and manager such that I can say company has many managers through departments?
Is this feature even possible in Go GORM? I am used to seeing this in Rails ActiveRecord
class Company < ApplicationRecord
has_many :departments
has_many :managers, through: :departments
end
Thanks
Related
I am new to ORM (and GORM) so apologies if this is an obvious question, but it does not seem to be covered by the documentation.
I will be using the examples from the documentation as a base to my questions
Question 1: Belongs To
// `User` belongs to `Company`, `CompanyID` is the foreign key
type User struct {
gorm.Model
Name string
CompanyID int
Company Company
}
type Company struct {
ID int
Name string
}
A User belongs to one Company only → this is handled by the code
above
A Company has many User → is this implied by the code
above? Or should I add somehow a relation O2M in Company?
Question 2: Has Many
// User has many CreditCards, UserID is the foreign key
type User struct {
gorm.Model
CreditCards []CreditCard
}
type CreditCard struct {
gorm.Model
Number string
UserID uint
}
A User has 1+ CreditCard→ this is handled by the code
A CreditCard can belong to several users (say, a shared family CC) → is it implied? (if not: how to set up the O2M relationship).
Or is it, instead, a case where a CreditCard is explicitly configured to belong to only one user?
Q1: Based on how you defined your structs, you don't need an explicit O2M relationship in the Company struct, but when loading Company details, if you want to load all users that are assigned to that specific company, you need to add that field as well. It will need an additional function call like Preload or Joins, but you shouldn't need an explicit definition of this relationship.
type Company struct {
ID int
Name string
Users []User
}
Q2: The way the relationship is defined now, it is configured so that a CreditCard belongs to only one user. If you want a many2many relationship, you need to specify the relation table. There is more documentation on it here, but it should look something like this:
type User struct {
gorm.Model
CreditCards []CreditCard `gorm:"many2many:users_creditcards"`
}
type CreditCard struct {
gorm.Model
Number string
}
I use the gorm with the has many。
This is my model
type Pro struct {
Model
TaxRate []TaxRate `json:"taxRate" gorm:"constraint:OnUpdate:CASCADE;"`
}
type TaxRate struct {
ID uint
Tax float64
ProjectID uint
}
but when I update the project, I found that the TaxRate just insert the record not update.
This is my update operation
result:=pRepo.db.Session(&gorm.Session{FullSaveAssociations: true}).Updates(p)
According to the gorm documentation on has-many relationships (https://gorm.io/docs/has_many.html) the automatic relation needs to be structnameID, so in your case ProID (the owner struct is called Pro and not Project). Either rename the struct or the reference or add gorm:"foreignKey:ProjectID" as tag:
type Pro struct {
Model
TaxRate []TaxRate `json:"taxRate" gorm:"foreignKey:ProjectID;constraint:OnUpdate:CASCADE;"`
}
There are two model use gorm in my project as following:
type User struct {
gorm.Model
Name string `gorm:"type:varchar(128)" json:"name"`
}
type Service struct {
gorm.Model
Name string `gorm:"type:varchar(128)" json:"name"`
Members []*User `gorm:"many2many:user_to_service;" json:"members"`
}
Now, I need to add a field role in the user_to_service, represent the user role in the service such as admin, member, guest and so on.
How do I add the role field in user_to_service? And How to update or query with this field use gorm?
Given the following one-to-many relationship (One Receipt has many LineItem's), I would like to map the Price field from the Receipt table into the Price field of LineItem table (for each LineItem in Product).
Receipt Schema
type Product struct {
ID uint `json:"id"`
TotalPrice float64 `json:"total"`
LineItems []LineItem `json:"lineItems"`
}
LineItem Schema
type LineItem struct {
ID uint `json:"id"`
ProductID uint `json:"productID"`
Price float64 `json:"price"`
}
I'm currently using gorm, an ORM for Go, but I can't find the functionality to support what I'm looking for.
Assuming that you have 3 tables/models, Receipt, Product, and LineItem, you can add field that reference Product in LineItem model like so :
type Receipt struct {
ID uint `json:"id"`
TotalPrice float64 `json:"total"`
LineItems []LineItem `json:"lineItems"`
}
type Product struct {
ID uint `json:"id"`
Price float64 `json:"price"`
}
type LineItem struct {
ID uint `json:"id"`
ProductID uint `json:"productID"`
Product *Product `json:"product"`
}
Then you can query Receipt while populating LineItems field as well as Product field in each LineItem by using gorm's Preload feature:
db.Preload("LineItems").Preload("LineItems.Product").Find(&receipt)
This way you will have the price info in each LineItem accessible through Product field:
for _, li in receipt.LineItems {
fmt.Println(li.Product.Price)
}
Can I make associations in gorm go both ways?
i.e.
type Store struct {
ID int
Products []Product
}
type Product struct {
ID int
StoreID int
Store Store
}
So a Store has many Products, and a Product belongs to a Store.
Is this correct?