in the following model:
package models
import "github.com/astaxie/beego/orm"
type Movie struct {
Id int `orm:"pk; auto; column(id)"; form: "-"`
Title string `orm:"unique; column(title)"; form: "title, text, title:`
Plot string `orm:"column(plot)"; form: "plot, text, plot:"`
ImdbID string `orm:"column(imdb_id)"; form: "imdb_id, text, imdb_id:"`
Actors string `orm:"column(actors)"; form: "actors, text, actors:"`
Runtime string `orm:"column(runtime)"; form: "runtime, text, runtime:"`
Year string `orm:"column(year)"; form: "year, text, year:"`
Genre *Genre `orm:"rel(fk); on_delete(do_nothing)"`
Cover string `orm:"column(cover)"; form: "cover, text, cover:"`
Status int `orm:"column(status)"; form: "status, int, status:"`
}
func (a *Movie) TableName() string {
return "app_movie"
}
func init() {
orm.RegisterModel(new(Movie))
}
I would like to refer to: the genre model, which looks like:
package models
import "github.com/astaxie/beego/orm"
type Genre struct {
Id int `orm:"pk; auto; column(id)"; form: "-"`
Title string `orm:"unique; column(title)"; form: "title, text, title:`
Status int `orm:"column(status)"; form: "status, int, status:"`
}
func (a *Genre) TableName() string {
return "app_genre"
}
func init() {
orm.RegisterModel(new(Genre))
}
For information it goes to an sqlite db with data (DB first).
In the controller i iterate over a list of movies and print out: movie.Genre.Title but its empty. If I watch on movie.Genre I get: {3 0}
What to do to get to the title and the ID? Or. what am I doing wrong?
Thanks for your help!
num, err := qs
.Limit(4)
.Filter("status", true)
.RelatedSel()
.Exclude("useritem__userid", 1)
.OrderBy("-id")
.All(&movies)
all works fine. :) .RelatedSel()
Related
Let's say I have two different structs:
type One struct {
Id string
// Other fields
}
type Two struct {
Id string
// Other fields
}
Is it possible to define a function that accepts both One and Two without explicitly listing them as options?
E.g. I am looking for something like this:
type ModelWithId struct {
Id string
}
func Test[M ModelWithId](m M) {
fmt.PrintLn(m.Id)
}
one := One { Id: "1" }
Test(one) // Prints 1
I don't want to use funcTest[M One | Two](m M), because I'll likely have 10+ structs and I don't want to come back to the function every time I add a new struct to the codebase.
Generics constraints the type parameter behaviours using methods, so you need to rewrite your code as:
type One struct {
id string
}
func (o *One) Id() string {
return o.id
}
then your use site would become:
type ModelWithId interface {
Id() string
}
func Test[M ModelWithId](m M) {
fmt.Println(m.Id())
}
type Old struct {
UserID int `json:"user_ID"`
Data struct {
Address string `json:"address"`
} `json:"old_data"`
}
type New struct {
UserID int `json:"userId"`
Data struct {
Address string `json:"address"`
} `json:"new_data"`
}
func (old Old) ToNew() New {
return New{
UserID: old.UserID,
Data: { // from here it says missing expression
Address: old.Data.Address,
},
}
}
What is "missing expression" error when using structs?
I am transforming old object to a new one. I minified them just to get straight to the point but the transformation is much more complex. The UserID field for example works great. But when I use struct (which intended to be a JSON object in the end) the Goland IDE screams "missing expression" and the compiler says "missing type in composite literal" on this line. What I am doing wrong? Maybe should I use something else instead of struct? Please help.
Data is an anonymous struct, so you need to write it like this:
type New struct {
UserID int `json:"userId"`
Data struct {
Address string `json:"address"`
} `json:"new_data"`
}
func (old Old) ToNew() New {
return New{
UserID: old.UserID,
Data: struct {
Address string `json:"address"`
}{
Address: old.Data.Address,
},
}
}
(playground link)
I think it'd be cleanest to create a named Address struct.
You're defining Data as an inline struct. When assigning values to it, you must first put the inline declaration:
func (old Old) ToNew() New {
return New{
UserID: old.UserID,
Data: struct {
Address string `json:"address"`
}{
Address: old.Data.Address,
},
}
}
Hence it is generally better to define a separate type for Data, just like User.
I created a struct in a file called availability.go
package restconsume
import (
)
// Availabilityrequest for sabre
type Availabilityrequest struct {
OTAAirLowFareSearchRQ struct {
OriginDestinationInformation []struct {
DepartureDateTime string `json:"DepartureDateTime"`
DestinationLocation struct {
LocationCode string `json:"LocationCode"`
} `json:"DestinationLocation"`
OriginLocation struct {
LocationCode string `json:"LocationCode"`
} `json:"OriginLocation"`
RPH string `json:"RPH"`
} `json:"OriginDestinationInformation"`
POS struct {
Source []struct {
PseudoCityCode string `json:"PseudoCityCode" default:"F9CE"`
RequestorID struct {
CompanyName struct {
Code string `json:"Code" default:"TN"`
} `json:"CompanyName"`
ID string `json:"ID" default:"1"`
Type string `json:"Type" default:"1"`
} `json:"RequestorID"`
} `json:"Source"`
} `json:"POS"`
TPAExtensions struct {
IntelliSellTransaction struct {
RequestType struct {
Name string `json:"Name" default:"200ITINS"`
} `json:"RequestType"`
} `json:"IntelliSellTransaction"`
} `json:"TPA_Extensions"`
TravelPreferences struct {
TPAExtensions struct {
DataSources struct {
ATPCO string `json:"ATPCO" default:"Enable"`
LCC string `json:"LCC" default:"Disable"`
NDC string `json:"NDC" default:"Disable"`
} `json:"DataSources"`
NumTrips struct {
} `json:"NumTrips"`
} `json:"TPA_Extensions"`
} `json:"TravelPreferences"`
TravelerInfoSummary struct {
AirTravelerAvail []struct {
PassengerTypeQuantity []struct {
Code string `json:"Code"`
Quantity int `json:"Quantity"`
} `json:"PassengerTypeQuantity"`
} `json:"AirTravelerAvail"`
SeatsRequested []int `json:"SeatsRequested" default:"1"`
} `json:"TravelerInfoSummary"`
Version string `json:"Version" default:"1"`
} `json:"OTA_AirLowFareSearchRQ"`
}
// AddADepartureDate to set the date you leave
func (a *Availabilityrequest) AddADepartureDate() Availabilityrequest {
a.OTAAirLowFareSearchRQ.OriginDestinationInformation[0].DepartureDateTime = "2020-03-21"
return *a
}
//AddOriginDestination to set the ori and dest
func (a *Availabilityrequest) AddOriginDestination(Origin ,Destination string) {
a.OTAAirLowFareSearchRQ.OriginDestinationInformation[0].DestinationLocation.LocationCode = Destination
a.OTAAirLowFareSearchRQ.OriginDestinationInformation[0].OriginLocation.LocationCode = Origin
}
Now I've imported this package into my main one and having issue instatntiating with only one substruct(TPAExtensions)
main.go
package main
import (
"restconsume"
"fmt"
)
func main() {
var a= new(restconsume.Availabilityrequest)
a = Availabilityrequest{
"OTA_AirLowFareSearchRQ":OTAAirLowFareSearchRQ{
"IntelliSellTransaction": IntelliSellTransaction{
"RequestType": RequestType{
"Name": "200ITINS"},
},
},
}
}
error message
undefined: Availabilityrequest
My question is how could I instantiate this kind of complex struct?
The simplest answer is to not try to use struct literal but rather have a variable of the top-level type to be initialized to an appropriate zero value for its type and then explicitly set only those fields which are needed, like this:
var a Availabilityrequest
a.OTAAirLowFareSearchRQ.TPAExtensions.IntelliSellTransaction.RequestType.Name = "200ITINS"
But honestly, judging from your question, it looks like you're JavaScript programmer trying to attack Go without much prior knowledge about that language. This is a path to suffering.
Please be advised to at least start with the Tour of Go and then read any introductory-level book on Go (I would recommend this one).
"Effective Go" is also a must.
In Golang ozzo-validation, how can I validate a field which is dependent on another field ?
For example, if I have the following:
return validation.ValidateStruct(&c,
validation.Field(&c.Name, validation.Required, validation.Length(5, 20)),
validation.Field(&c.Gender, validation.In("Female", "Male")),
validation.Field(&c.Email, is.Email),
validation.Field(&c.Address),
How can I add a validation that the Address is required only if email is not empty?
You can achieve it in two ways-
Adding your own custom rules
Conditionally add FieldRules based on precondition-value i.e check Email while creating field rules then supply it to validation.ValidateStruct
For e.g.:
type Sample struct {
Name string
Gender string
Email string
Address Address
}
type Address struct {
// ... fields
}
func (s Sample) Validate() error {
var fieldRules []*validation.FieldRules
fieldRules = append(fieldRules, validation.Field(&s.Name, validation.Required, validation.Length(5, 20)))
fieldRules = append(fieldRules, validation.Field(&s.Gender, validation.In("Female", "Male")))
fieldRules = append(fieldRules, validation.Field(&s.Email, is.Email))
if len(strings.TrimSpace(s.Email)) > 0 {
fieldRules = append(fieldRules, validation.Field(&s.Address, validation.Required))
fieldRules = append(fieldRules, validation.Field(&s.Address))
}
return validation.ValidateStruct(&s, fieldRules...)
}
The library now supports conditional validation by the validation.When function.
Here is a code snipped which fits the validation you described.
package main
import (
"fmt"
validation "github.com/go-ozzo/ozzo-validation" // or "github.com/go-ozzo/ozzo-validation/v4" if "When" not found
)
type Entry struct {
Name string
Gender string
Email string
Address string
}
func main() {
v := func(e Entry) {
fmt.Println(validation.ValidateStruct(&e,
validation.Field(&e.Name, validation.Required, validation.Length(5, 20)),
// Note that if gender is "" and not required, validation returns no error.
validation.Field(&e.Gender, validation.Required, validation.In("Female", "Male")),
validation.Field(&e.Address, validation.When(e.Email != "", validation.Required.Error("Address is required if Email is set"))),
))
}
// All is fine for no Email.
e := Entry{
Name: "My name is!",
Gender: "Male",
}
v(e)
// Validation fails for Email and no Address.
e = Entry{
Name: "My name is!",
Gender: "Male",
Email: "a#org.com",
}
v(e)
}
It outputs.
<nil>
Address: Address is required if Email is set.
The library documentation describes it as well: https://github.com/go-ozzo/ozzo-validation#conditional-validation
I'd like to know how to retrieve the parent struct of an instance.
I have no idea how to implement this.
For instance:
type Hood struct {
name string
houses []House
}
type House struct {
name string
people int16
}
func (h *Hood) addHouse(house House) []House {
h.houses = append(h.houses, house)
return h.houses
}
func (house *House) GetHood() Hood {
//Get hood where the house is situated
return ...?
}
Cheers
You should retain a pointer to the hood.
type House struct {
hood *Hood
name string
people int16
}
and when you append the house
func (h *Hood) addHouse(house House) []House {
house.hood = h
h.houses = append(h.houses, house)
return h.houses
}
then you can easily change the GetHood, although a getter may not be required at that point.
func (house *House) GetHood() Hood {
return *house.hood
}