@@ -153,6 +153,59 @@ func (p *Package) FindModel(name string) *Model {
153153 return p .indexedModels [name ]
154154}
155155
156+ func (p * Package ) addMissingRelationships () error {
157+ for _ , m := range p .Models {
158+ for _ , f := range m .Fields {
159+ if f .Kind == Relationship && ! f .IsInverse () {
160+ if err := p .trySetFK (f .TypeSchemaName (), f ); err != nil {
161+ return err
162+ }
163+ }
164+ }
165+ }
166+
167+ return nil
168+ }
169+
170+ func (p * Package ) trySetFK (model string , fk * Field ) error {
171+ m := p .FindModel (model )
172+ if m == nil {
173+ return fmt .Errorf ("kallax: cannot assign implicit foreign key to non-existent model %s" , model )
174+ }
175+
176+ var found bool
177+ for _ , f := range m .Fields {
178+ if f .Kind == Relationship {
179+ if f .ForeignKey () == fk .ForeignKey () {
180+ found = true
181+ break
182+ }
183+ } else {
184+ if f .ColumnName () == fk .ForeignKey () {
185+ found = true
186+ break
187+ }
188+ }
189+ }
190+
191+ if ! found {
192+ for _ , ifk := range m .ImplicitFKs {
193+ if ifk .Name == fk .ForeignKey () {
194+ found = true
195+ break
196+ }
197+ }
198+ }
199+
200+ if ! found {
201+ m .ImplicitFKs = append (m .ImplicitFKs , ImplicitFK {
202+ Name : fk .ForeignKey (),
203+ Type : identifierType (fk .Model .ID ),
204+ })
205+ }
206+ return nil
207+ }
208+
156209const (
157210 // StoreNamePattern is the pattern used to name stores.
158211 StoreNamePattern = "%sStore"
@@ -182,6 +235,10 @@ type Model struct {
182235 Type string
183236 // Fields contains the list of fields in the model.
184237 Fields []* Field
238+ // ImplicitFKs contains the list of fks that are implicit based on
239+ // other models' definitions, such as foreign keys with no explicit inverse
240+ // on the related model.
241+ ImplicitFKs []ImplicitFK
185242 // ID contains the identifier field of the model.
186243 ID * Field
187244 // Events contains the list of events implemented by the model.
@@ -499,6 +556,11 @@ func relationshipsOnFields(fields []*Field) []*Field {
499556 return result
500557}
501558
559+ type ImplicitFK struct {
560+ Name string
561+ Type string
562+ }
563+
502564// Field is the representation of a model field.
503565type Field struct {
504566 // Name is the field name.
0 commit comments