relationMappings() join doesn't handle ref correctly
import { Model } from 'objection';
class FirstClass extends Model {
static tableName = 'first-class';
id!: number;
name!: string;
}
class SecondClass extends Model {
static tableName = 'second-class';
id!: number;
name!: string;
fkFirstId!: number;
static relationMappings() {
return {
first: {
relation: Model.HasOneRelation,
modelClass: FirstClass,
join: {
from: SecondClass.ref('fkFirstId'),
to: FirstClass.ref('id'),
},
},
};
}
}
with this example, querying with .joinRelated() will throw the error
SecondClass.relationMappings.first: join.from must have format TableName.columnName. For example "SomeTable.id" or in case of composite key ["SomeTable.a", "SomeTable.b"].
After some trial and error, i think i've been missguided by the typing in https://github.com/Vincit/objection.js/tree/master/doc/api/types#type-relationjoin that said join.from can be a ReferenceBuilder since it's more a result from a it.
No I think this should work. I'll see what's going on as soon as I find the time.
I'm hitting the same problem in Objection v2.2.3.
Switching from the ref approach to camelCased pluralized strings gets past the problem but seems to introduce another problem. Got past that too but the workaround is a bit awkward and was hoping @koskimas might have advice.
I'm using a class and belongsTo relationship basically the same as Yimiprod's:
static relationMappings = () => ({
otherModel: {
relation: Model.BelongsToOneRelation,
modelClass: OtherModel,
join: {
from: 'someModels.otherModelId', // a string corresponding with knexSnakeCaseMappers in the knex config, replacing the ref
to: 'otherModels.id'
},
},
});
With the string refs in place, it gets past that join.from error, generating a query but one that postgres 12.3 complains about, throwing invalid reference to FROM-clause entry for table "other_models", seemingly due to the auto-generated alias in the join: select "some_models".* from "some_models" inner join "other_models" as "other_models"...
I didn't explicitly add the alias "other_models" anywhere--it's some automatic addition. I got past the issue by explicitly setting an alias both in joinRelated options and by chaining in aliasFor:
return SomeModel.query(tx)
.joinRelated('otherModel', { alias: 'other' })
.aliasFor(OtherModel, 'other')
.where(OtherModel.ref('whatever'), whatever)
.first();
Rather than overriding the alias in every query, is there a way to declare the alias in the class definition? Or a way to disable the auto-alias, or something better? I'd like to reuse filters/modifiers defined in different classes when composing queries but that depends on stable and consistent identifiers and aliases. Haven't seen a way to do that yet. (Am brand new to Objection.)
There's no automatic aliasing that would change the alias from otherModel to other_models. That simply isn't possible. other_models is either the real table name or the relation name. Also that's a separate issue and probably caused by invalid usage of either knexSnakeCaseMappers or snakeCaseMappers.
Bumping this with a TS playgorund example:
https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAbzgWQgEwKYBsA0cBK2AhjMBAHbJFhjDkDmAznoViWZdbQ3AL5wAzKBBBwA5BABGAKwwBjUhTEBuALAAoDTACeYDAWKLyjABbAwjOAF5EGuPbgwiTAFwG2RqjTr0APABVnAD4NXg0NOTZGS0D6OAwADxgMcjRLVEwsW3UHOHIiEAwAQjdGGCgfNXUwzXVIomi4AFVGDCh4pJS0lHRsbLsHMvY5OChDDi9uV3d2ClNzSxsEAdz7J2nlnNXtsY8ONwzsADoACQaqcm1WWfIcFe2HaQg6N02H98FhEDcxAFdWqCMI7ANBiO5bD6rGAQH7rIH-NoAfRBYnu7144Mh9hAvSwAGEoow3LE0Q4arleFUauF1A1tOQRgAKACU1iC-QhcDkc3gCPaNiIAHciMB4C02kcAI6-NraFlHATAQEwFlVe7c4zwSRENBw6xwIUi3kAopHAAkuxIGDQAEUZVA5WI4WJmWrOdrdc5GABtAAMAF0jvlCso4AB6MNwXwAWmjcAACsI9LBtOJgxgxHA0BAMJZyBB4IlgGU4BRHLp9GJDlgxEc4AB+es03Iakv0CDoPUC4WiuB800WwzWu2yqOxIKMp1el1VXLtztev2B9OhiNR2NwQXQADWjFCVSAA
In my case, relatedQuery incorrectly maps QueryBuilder to Model. In my personal project, which has a custom query builder, it maps it to any