I have the following scenario:
type Band struct {
Name string
LocationId *datastore.Key
Albums []Album
}
type Album struct {
Name string
GenreId *datastore.Key
Year int
}
What I want to do is query a Bands Albums key for an album with a specific GenreId key.
I found the answer. It turned out to be simple. Instead of
Filter("GenreId =", genreId)
I used
Filter("Albums.GenreId =", genreId)
That gave me valid query results.
Related
im a beginner in golang. when im using gorm:"primaryKey"
i dont see any field that use primary key
this is my model
type Orders struct {
OrderID uint64 `gorm:"primaryKey" json:"orderId"`
CustomerName string `json:"customerName"`
OrderedAt time.Time `json:"orderedAt" example:"2020-01-09T21:21:46+00:00"`
Items []Items `json:"items"`
}
type Items struct {
ItemID uint64 `gorm:"primaryKey" json:"lineItemId"`
Item_code string `json:"itemCode"`
Description string `json:"description"`
Quantity int `json:"quantity"`
}
which part do i wrong?
and do i need relational database for items field?
Lets be clear over here,
At first you need to declare a struct as a Model i.e by
type Anything struct {
gorm.Model
... (other fields)
}
And then in order to use Has Many relation you need to use the ID of the parent on the child i.e
type User struct {
gorm.Model
CreditCards []CreditCard
}
type CreditCard struct {
gorm.Model
Number string
UserID uint (like this over here.)
}
Please do kindly follow the docs GORM Docs
In the model Orders model has a hasMany relation to Items, but Items is missing the Key of Orders.
The db.AutoMigrate(&models.Orders{}, &models.Items{}) should be failing to create in this case for Order.Items, but the error is ignored.
Include OrdersID in Items struct to complete referential integrity because gorm expects default primary key/ foreign key as <StructName>ID so for Orders it will search OrdersID in Items
type Orders struct {
OrdersID uint64 `gorm:"primaryKey" json:"orderId"`
...
}
type Items struct {
OrdersID uint64
...
}
Suggestion, structs should be called Order and Item rather than Orders and Items thus the model becomes
type Order struct {
OrderID uint64 `gorm:"primaryKey" json:"orderId"`
CustomerName string `json:"customerName"`
OrderedAt time.Time `json:"orderedAt" example:"2020-01-09T21:21:46+00:00"`
Items []Item `json:"items"`
}
type Item struct {
ItemID uint64 `gorm:"primaryKey" json:"lineItemId"`
Item_code string `json:"itemCode"`
Description string `json:"description"`
Quantity int `json:"quantity"`
OrderID uint64
}
I'm working on a Gin app using Gorm ORM (I'm new to both of them). I've got the following model:
type Record struct {
Barcode string `json:"barcode" gorm:"size:48;unique;not null" sql:"index"`
Name string `json:"name" gorm:"size:160;unique;not null"`
Artist Artist `gorm:"foreignKey:ArtistID""`
ArtistId uint
Category Category `gorm:"foreignKey:CategoryID"`
CategoryId uint
NumOfRecords int `json:"num_of_records" gorm:"not null"`
OriginalReleaseDate time.Time `json:"original_release_date" gorm:"default:null"`
ReissueReleaseDate time.Time `json:"reissue_release_date" gorm:"default:null"`
SideColor string `json:"side_color" gorm:"default:null"`
BarcodeInRecord bool `json:"barcode_in_record" gorm:"default=true"`
gorm.Model
}
As you can see there are two fields with two foreign keys: Artist and Category.
Here's those models:
type Category struct {
Name string `json:"name" gorm:"size:60;unique;not null"`
Description string `json:"description" gorm:"size:120"`
Parent uint `json:"parent" gorm:"default:null"`
Active bool `json:"active" gorm:"default:true"`
gorm.Model
}
type Artist struct {
Name string `json:"name" gorm:"size:120;unique;not null"`
Type string `json:"type" gorm:"default:null"`
CountryOfOrigin string `json:"countryOfOrigin" gorm:"default:null"`
gorm.Model
}
category_id and artist_id columns are being created but they are not referencing the other tables two tables:
I've tried to define those fields using AssociationForeignKey:Refer. I also tried to change the foreign key name to simply ID since that's the name that GORM assigns to primary keys but none of those thinks have worked.
What am I missing?
IMO Gorm docs are pretty lousy. From another SO question (Gorm Golang orm associations) it is said that:
it doesn't (create FKs when migrations run). If you want Foreign Key in DB, you need explicitly write something like db.Model(&Place{}).AddForeignKey("town_id", "towns(id)", "RESTRICT", "RESTRICT") during your migrations.
I have a TODO list application which is based on items and users. When I get a user from the users collection in mongo, I also want to get the items with the field "userId" which are in another collection. But all this should happen in one query. I want to know how should I emulate the joins from SQL or some method which can return all that I requiring in one query. I only get the id of the user in repository.
Here is the code:
Item
type Item struct{
ItemId primitive.ObjectID `bson:"_id,omitempty" json:"_id"`
Title string `bson:"title,omitempty" json:"title"`
Description string `bson:"description,omitempty" json:"description"`
UserId primitive.ObjectID `bson:"userId" json:"userId"`
}
func NewItem(title string,description string) Item {
return Item{
Title: title,
Description: description,
}
}
User
type User struct{
UserId primitive.ObjectID `bson:"_id,omitempty" json:"user_id"`
UserName string `bson:"name,omitempty" json:"user_name"`
Status bool `bson:"status" json:"status"`
Items []Item `bson:"items" json:"items"`
}
func NewUser(userId primitive.ObjectID,userName string,status bool,items []Item) User{
return User{
userId,
userName,
status,
items,
}
}
I have the following table schema:
user
-----
id uuid
name string
user_model
------
id uuid
user_id uuid
model_id uuid
role int
model
_____
id uuid
name string
model_no string
I have the following code which fetches the data from the "model" table.
underlyingModel = &model{}
var model IModel
model = underlyingModel
role := 0
db.Table("model").Joins('INNER JOIN user_model ON user.id = user_model.uuid')
.Joins('INNER JOIN model ON user.id = model_id').Find(&model);
In my actual code, the model can be many different struct types with different fields, they're all behind the IModel interface.
What I want to do is to fetch that extra role field from the user_model in one query. Something like .Find(&model, &role).
Is it possible using Gorm?
One possible solution is to create an anonymous struct to put the results in, with a combination of the Select() method.
var selectModel struct {
ID string //I'm assuming uuid matches the string
Name string
ModelNo string
Role int
}
db.Table("model").
Joins("INNER JOIN user_model ON user.id = user_model.uuid").
Joins("INNER JOIN model ON user.id = model_id").
Select("model.id, model.name, model.model_no, user_model.role").
Find(&selectModel);
Basically, you create an anonymous struct with selectModel variable, containing all the fields you want to return. Then, you need to do a select statement because you need some fields that are not part of the model table.
Here you can find more info on Smart Select Fields in form.
EDIT:
Based on additional info from the comments, there is a solution that might work.
Your IModel interface could have two methods in its signature, one to extract a string for the SELECT part of the SQL query, and the other one to get a pointer of the selectModel that you would use in the Find method.
type IModel interface {
SelectFields() string
GetSelectModel() interface{}
}
The implementation would go something like this:
func (m *model) SelectFields() string {
return "model.id, model.name, model.model_no, user_model.role"
}
func (m *model) GetSelectModel() interface{} {
return &m.selectModel
}
type model struct {
selectModel
ID uint64
Age int
}
type selectModel struct {
Name string
Email string
}
Then, your query could look something like this:
var m IModel
m = model{}
db.Table("model").
Joins("INNER JOIN user_model ON user.id = user_model.uuid").
Joins("INNER JOIN model ON user.id = model_id").
Select(m.GetSelectFields()).
Find(m.GetSelectModel());
Consider the following;
class Person {
int id
String name
static hasMany = [cars : Car]
}
class Car {
int id
String brand
static belongsTo = Person
static hasMany = [owners: Person]
}
The above will result in a person_cars join table. All I'm trying to find out is if there are any entries in that table, in words;
Do any Persons currently exist who own a car.
Happy to use any mechanism available (finders/criteria/HQL etc)
My opinion is better to add PersonCar entity.
For your question:
Car.count() > 0
As car belongTo Person, so that can't be any copy of car without been added to the person.
If person is nullable you can use:
Car.countByPersonIsNotNull()
Think that if car has person, so that there will be a value in that table.
Got it! A lot simpler than I thought.
Person.createCriteria().count {
owners {
count
}
}
This effectively gives me the number of person_cars records.