adonisjs / lucid

AdonisJS SQL ORM. Supports PostgreSQL, MySQL, MSSQL, Redshift, SQLite and many more
https://lucid.adonisjs.com/
MIT License
1.03k stars 189 forks source link

@belongsTo cannot find foreignKey automatically if contains multiple words #911

Closed guoyunhe closed 1 year ago

guoyunhe commented 1 year ago

Package version

Node.js and npm version

Sample Code (to reproduce the issue)

I have two models:

import { BelongsTo, belongsTo, column } from '@ioc:Adonis/Lucid/Orm';
import Image from './Image';
import Model from './Model';

export default class Game extends Model {
  @column()
  public boxartImageId: number | null;

  @belongsTo(() => Image, { foreignKey: 'boxartImageId' })
  public boxartImage: BelongsTo<typeof Image>;
}
import { column, computed } from '@ioc:Adonis/Lucid/Orm';
import Model from './Model';

export default class Image extends Model {
   // ...
}

Game model has boxartImageId, which loads an Image as boxartImage. However, if I write @belongsTo(() => Image), loading relation will fail:

Exception: E_MISSING_MODEL_ATTRIBUTE: "Game.boxartImage" expects "imageId" to exist on "Game" model, but is missing
    at /Users/guoyunhe/Git/rgi-api/node_modules/@adonisjs/lucid/build/src/Orm/Relations/KeysExtractor.js:47:23
    at Array.reduce (<anonymous>)
    at KeysExtractor.extract (/Users/guoyunhe/Git/rgi-api/node_modules/@adonisjs/lucid/build/src/Orm/Relations/KeysExtractor.js:43:39)
    at BelongsTo.boot (/Users/guoyunhe/Git/rgi-api/node_modules/@adonisjs/lucid/build/src/Orm/Relations/BelongsTo/index.js:151:12)
    at Preloader.load (/Users/guoyunhe/Git/rgi-api/node_modules/@adonisjs/lucid/build/src/Orm/Preloader/index.js:106:18)
    at ModelQueryBuilder.preload (/Users/guoyunhe/Git/rgi-api/node_modules/@adonisjs/lucid/build/src/Orm/QueryBuilder/index.js:567:24)
    at GamesController.index (/Users/guoyunhe/Git/rgi-api/app/Controllers/Http/GamesController.ts:8:19)
    at Injector.callAsync (/Users/guoyunhe/Git/rgi-api/node_modules/@adonisjs/fold/build/src/Ioc/Injector.js:124:30)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

So I have to use @belongsTo(() => Image, { foreignKey: 'boxartImageId' }). It works. But not as straight-forward as Laravel.

BONUS (a sample repo to reproduce the issue)

https://github.com/guoyunhe/rgi-api

RomainLanz commented 1 year ago

Hey! 👋🏻

Adonis uses convention over configuration, which relies on predefined conventions for naming and structuring code. In your example, the foreign key is not automatically detected because it does not adhere to these conventions. So, you'll need to specify the foreign key's name manually.

📚 https://docs.adonisjs.com/guides/models/relationships#custom-relationship-keys