Waterline associations, change foreign key? - foreign-keys

The latest waterline now supports associations. Here is an example of a one-to-many
// A user may have many pets
var User = Waterline.Collection.extend({
identity: 'user',
connection: 'local-postgresql',
attributes: {
firstName: 'string',
lastName: 'string',
// Add a reference to Pets
pets: {
collection: 'pet',
via: 'owner'
}
}
});
var Pet = Waterline.Collection.extend({
identity: 'pet',
connection: 'local-postgresql',
attributes: {
breed: 'string',
type: 'string',
name: 'string',
// Add a reference to User
owner: {
model: 'user'
}
}
});
This creates a field called owner on the pet collection. This would be fine except for working with an existing DB. which calls it's foreign key owner_id.
Is there anyway to override the field name used in the database?

You can change the column name used for any model attribute by setting the columnName property:
attributes: {
breed: 'string',
type: 'string',
name: 'string',
// Add a reference to User
owner: {
columnName: 'owner_id',
model: 'user'
}
}
Note also that when defining a model in Sails, you shouldn't extend from Waterline directly, but simply save the model file in /api/models with the appropriate name, e.g. User.js:
module.exports = {
attributes: {
breed: 'string',
type: 'string',
name: 'string',
// Add a reference to User
owner: {
model: 'user',
columnName: 'owner_id'
}
}
}
and let Sails / Waterline handle the identity and connection for you unless you really want to override the defaults.

Related

Deep nested validation in loopback models

The loopback docs indicate how to validate models in the REST layer. But, is there a way you can validate deep/nested models inside your model?
If a User has both a name and a Contact, I want both to be validated, including all properties defined in Contact.
This comment from 2015 mentions deep validation is not supported. Is this still the case?
In this more recent answer it is suggested to set type: Contact directly, but I'm getting this error:
Property User.contact does not have "type" in its definition
import {Entity, model, property} from '#loopback/repository';
// User
#model()
export class User extends Entity {
#property({
type: 'string',
required: true,
})
name: string;
#property({
type: Contact,
required: true,
})
contact: Contact;
}
// Contact
#model()
export class Contact extends Model {
#property({
type: 'string',
required: true,
default: 'phone',
})
type: string;
}

How to implement `loopback-ds-timestamp-mixin` in loopback 4?

I found a problem when implementing it in loopback 4, because the structure of version 4 changed completely. there is no model-config.json file.
How do I add mixins property to server?
I want to add createdAt and updatedAt to each model on loopback 4
you can write a BaseClass Model and then inherit it in your models.
base-entity.model.ts
export abstract class BaseEntity extends Entity {
#property({
type: 'date',
default: () => new Date(),
name: 'created_on',
})
createdOn?: Date;
#property({
type: 'date',
default: () => new Date(),
name: 'modified_on',
})
modifiedOn?: Date;
}
yourmodel.model.ts
export class Yourmodel extends BaseEntity {
}

Emberjs (link-to HasMany) Error while loading route: TypeError: Cannot call method 'resolve' of undefined

I am trying to set model of a route(not nested) but with relationship belong to with setupController
Here is my JSBIN
i.e company hasMany Contacts
from companies list page I have directly linked to contacts page (want flow that ways)
I want to use the company model to get its contacts list but I am getting error
Error while loading route: TypeError: Cannot call method 'resolve' of undefined
Heres my Router
App.Router.map(function() {
this.resource('companies',{path:'/'});
this.resource('company',{path:'/company/:company_id'});
this.resource('contacts',{path:'/company/:id/contacts'});
});
This is what I am doing
App.ContactsRoute = Em.Route.extend({
setupController: function(controller, model) {
console.log(model.get('contacts')); //This line gives error
//controller.set('model',model.get('contacts'));
}
});
The MODEL
App.Company = DS.Model.extend({
name: DS.attr('string'),
contacts: DS.hasMany('Contact')
});
App.Company.FIXTURES = [{
id: 1,
name: 'company 1',
contacts: ['1']
}, {
id: 2,
name: 'company 2',
contacts: ['1', '2']
}];
App.Contact = DS.Model.extend({
name: DS.attr('string'),
company: DS.belongsTo('Company')
});
App.Contact.FIXTURES = [{
id: 1,
name: 'employee 1',
company: 1
}, {
id: 2,
name: 'employee 2',
company: 2
}];
Updated Fiddle
I updated the fiddle for you and changed a few things. To me, it seemed more logical to add contacts as a route of the resource company instead of a separate resource.
I also made the company model async, so it waits for all models to be loaded before actually rendering everything
Take a look and feel free to ask questions if you don't fully understand the solution.

Pushing an Object to EmberData hasMany relationship disappears

Id like to oush object to a hasMany property of my object. When add it with an action, it shows up, and disappears when the bucket object is saved.
here is some code:
App.Item = DS.Model.extend({
name: DS.attr('string'),
bucket: DS.belongsTo('bucket',{
async: true,
inverse: "items"
}),
});
App.Bucket = DS.Model.extend({
name: DS.attr('string'),
items: DS.hasMany('item',{
async: true,
inverse: "bucket"
}),
});
And this is how I try to push an item to the bucket, in the controller action:
//add new item to the bucket
var bucket = this.get('model');
////////////////
var item = this.store.createRecord('item');
item.set('name', name);
item.save().then(function(resolvedItem){
bucket.get('items').pushObject(item);
bucket.save();
});
Im using ember 1.2.0, and EmberData v1.0.0-beta.3
UPDATE: I'm using Fixture Data.

Ember-data mapping embedded object from JSON

I am struggling with a strange problem. I have a model called Activity with a property defined like this:
owner: DS.belongsTo('App.User', embedded: true)
The User is also a defined model when I'm getting the JSON response like this:
some single properties and
user: { id: etc. }
My all properties map well but the user embedded object from JSON doesn't map to the owner property. However, when I change
owner
to
user
It maps well. But I want to leave the owner because it's a better representation of what I mean. I tried this action:
owner: DS.belongsTo('App.User', key: 'user', embedded: true)
but it didn't help.
First, I recommend using the latest Ember / EmberData, but you will need to handle embedded records manually by enhancing extractSingle in a custom serializer (see example below). Also, you should define relationships like this:
App.Activity = DS.Model.extend({
name: DS.attr('string'),
owner: DS.belongsTo('user')
});
App.User = DS.Model.extend({
name: DS.attr('string'),
activities: DS.hasMany('activity')
});
Next, I recommend using the ActiveModelAdapter if you are using underscores when communicating with the server (i.e. like in EmberData 0.13):
App.ApplicationAdapter = DS.ActiveModelAdapter;
Finally, to use owner for a User, override typeForRoot in a custom serializer.
For example:
App.ApplicationSerializer = DS.ActiveModelSerializer.extend({
typeForRoot: function(root) {
if (root == 'owner' || root == 'owners') { root = 'user'; }
return this._super(root);
},
// based on: https://github.com/emberjs/data/blob/master/TRANSITION.md#embedded-records
extractSingle: function(store, type, payload, id, requestType) {
var owner = payload.activity.owner,
ownerId = owner.id;
payload.owners = [owner];
payload.activity.owner_id = ownerId;
return this._super.apply(this, arguments);
}
});
Example JSBin