PhilWaldmann / openrecord

Make ORMs great again!
https://openrecord.js.org
MIT License
486 stars 38 forks source link

Can't find relation error #33

Closed gorcer closed 7 years ago

gorcer commented 7 years ago

I have two tables - products and prices. Prices is belong to products via product_id column.

My code:

var config = require('./config.json'); var OpenRecord = require('openrecord');

var db = new OpenRecord({ type: 'mysql', host: config.host, database: config.db, user: config.user, password: config.password, port: 3306 });

db.Model('Products', function(){ this.hasMany('Prices'); }); db.Model('Prices', function(){ this.belongsTo('Products') }); db.ready(function(){ var Prices = db.Model('Prices'); Prices.include('Products').exec(function(prices){ console.log(prices[0].products); }) });

After execute i got error: RelationNotFoundError: Can't find relation "Products" for Prices

Why?

PhilWaldmann commented 7 years ago

Hi gorcer,

models should be named in singular form. E.g.:

db.Model('Product', function(){
  this.hasMany('Prices');
});

OpenRecord uses the inflection module to singularize the relation name (e.g. this.belongsTo('Products')) and searches for the corresponding model (=>Product)

Relations are generated asynchronously. If there is no corresponding model for a relation it wont be established. That's the reason you get that RelationNotFoundError error.

Let me know if that solves your problem

gorcer commented 7 years ago

Hi Phil,

Oh)))

Thanks! This solved my problem.

PhilWaldmann commented 7 years ago

Awesome!

I'll close this issue

SampsonCrowley commented 7 years ago

I'd like clarification..

I've been using active record for a long time, so i understand inflections, when to use plural and singular.. but in your example above you are using capitalized Prices

in most ORM's that would instead be prices since it has many instances of Price not the Price model itself (and belongsTo would be singular e.g. belongsTo('price'))

is that the case with this ORM? the documentation is really lacking on relations. are there any relationship editing syntaxes like accepts nested attributes?

PhilWaldmann commented 7 years ago

OpenRecord will accept both (db.Model('Prices', ...) and db.Model('Price', ...)). it uses the lower-cased plural form of the name for the table name. So in either case it will use the prices table. However, I don't recommend to use the plural form! It could lead to strange behaviour when used with relations.

@SampsonCrowley Yes, the docs are not as complete as I would like it to be.

OpenRecord will accept all nested attributes by default (see create-test.js) Additionally, here ist the list of options for relations:

/**
   * Adds a has many relation to the current Model
   *
   * @class Definition
   * @method hasMany
   * @param {string} name - The name of the relation
   * @param {object} options - Additional options for the relation
   *
   * @options
   * @param {string} model - The related model Name
   * @param {string} store - Optional store name for cross-store relations
   * @param {string} through - The through relation name
   * @param {string} relation - The target relation name (in conjunction with through)
   * @param {string} primary_key - SQL only
   * @param {string} foreign_key - SQL only
   * @param {string} as - the name of a polymophic relation - SQL only
   * @param {object} conditions - Extra conditions for the relation - SQL only
   * @param {string} dependent - `destroy`, `delete`, `nullify` or null. Default to null - SQL only
   *
   * @return {Definition}
   */

  /**
   * Adds a belongs to relation to the current Model
   *
   * @class Definition
   * @method belongsTo
   * @param {string} name - The name of the relation
   * @param {object} options - Additional options for the relation
   *
   * @options
   * @param {string} model - The related model Name
   * @param {string} store - Optional store name for cross-store relations
   * @param {string} through - The through relation name
   * @param {string} relation - The target relation name (in conjunction with through)
   * @param {boolean} polymorph - true to define this relation as polymorph.
   * @param {string} primary_key - SQL only
   * @param {string} foreign_key - SQL only
   * @param {string} type_key - the name of the polymorphic relation. You need to have a <name>_type and <name>_<primary_key> attribute on your model. Default is the relation name - SQL only
   * @param {object} conditions - Extra conditions for the relation - SQL only
   * @param {string} dependent - `destroy`, `delete` or null. Default to null - SQL only
   *
   * @return {Definition}
   */

 /**
  * Adds a belongs to many relation to the current Model
  *
  * @class Definition
  * @method belongsToMany
  * @param {string} name - The name of the relation
  * @param {object} options - Additional options for the relation
  *
  * @options
  * @param {string} model - The related model Name
  * @param {string} store - Optional store name for cross-store relations
  * @param {string} through - The through relation name
  * @param {string} relation - The target relation name (in conjunction with through)
  *
  * @return {Definition}
  */

/**
   * Adds a has one relation to the current Model
   *
   * @class Definition
   * @method hasOne
   * @param {string} name - The name of the relation
   * @param {object} options - Additional options for the relation
   *
   * @options
   * @param {string} model - The related model Name
   * @param {string} store - Optional store name for cross-store relations
   * @param {string} through - The through relation name
   * @param {string} relation - The target relation name (in conjunction with through)
   * @param {string} primary_key - SQL only
   * @param {string} foreign_key - SQL only
   * @param {object} conditions - Extra conditions for the relation
   * @param {string} dependent - `destroy`, `delete` or null. Default to null - SQL only
   *
   * @return {Definition}
   */