I have the following code:
Pult.Zone = DS.Model.extend({
name: DS.attr('string'),
authoritative: DS.attr('boolean'),
user_id: DS.attr('number'),
rulesets: DS.hasMany('Pult.Ruleset')
});
Pult.RESTAdapter.map('Pult.Zone', {
primaryKey: 'name',
rulesets: { key: 'rulesetIds' }
});
However, it doesn't seem like is picking up on the primary key correctly. I have rendered a list of all zones.
Here's a test case:
zones = Pult.store.findAll(Pult.Zone);
zones.get('length'); // Returns 10
zones = Pult.store.findAll(Pult.Zone);
zones.get('length'); // Returns 20
So every time I load zones from the server, it adds them to the local list, since it does not recognize them as already existing. Any way to fix this, or will I have to try to mock up some surrogate keys?
After upgrading to Ember Data 1.0.0 Beta 2, I found a solution that works:
App.Zone = DS.Model.extend({
name: DS.attr('string'),
user_id: DS.attr('number'),
});
App.ZoneSerializer = DS.RESTSerializer.extend({
normalize: function(type, hash, property) {
// Ember Data use the zone name as the ID.
hash.id = hash.name;
// Delegate to any type-specific normalizations.
return this._super(type, hash, property);
}
});
Related
I have got this route retrieving 2 models:
App.PanelRoute = Ember.Route.extend({
model: function(){
var topologymin = this.store.find('topologymin');
var metricmap = this.store.find('metricmap', { param1: 'something'})
return Ember.RSVP.hash({
topologymin: topologymin,
metricmap: metricmap
});
});
This makes 2 calls:
http://localhost/topologymins
http://localhost/metricmaps?param1=something
If I go to another route and again to this one, it makes again the call with the params, not the other one:
http://localhost/metricmaps?param1=something
But, as its the same call to retrieve the same records I would like them to be cached like in the other call.
How does it know when to call the server and when its not necessary? Is it possible to do that?
My models:
App.Topologymin = DS.Model.extend({
siteGroup: DS.attr('string'),
sites: DS.hasMany('site')
});
App.Metricmap = DS.Model.extend({
profile: DS.attr('string'),
link: DS.attr('string'),
services: DS.attr()
});
When you fire a request based on params Ember Data doesn't know how those params necessarily translate into the models (aka it doesn't know that you have all of the records that have some sort of relationship param1). You can cache it yourself, but then you'd still need some sort of way of knowing those records from other records in your store.
App.PanelRoute = Ember.Route.extend({
model: function(){
var met = this.get('fetchedBeforePromise'),
topologymin = this.store.find('topologymin'),
metricmap = met || this.store.find('metricmap', { param1: 'something'});
this.set('fetchedBeforePromise', metricmap);
return Ember.RSVP.hash({
topologymin: topologymin,
metricmap: metricmap
});
});
I have a model that has a one to many relationship with multiple translations:
App.Category = DS.Model.extend({
translation_ids: DS.hasMany('translation', { embedded: 'always' }),
});
App.Translation = DS.Model.extend({
name: DS.attr(),
locale: DS.attr()
});
I want to fetch the name of the category according to the selected language :
App.CategoryController = Ember.ObjectController.extend({
needs: ['settings'],
currentLocale: Ember.computed.alias('controllers.settings.currentLocale'),
name: function() {
var translations = this.get('translation_ids').filterBy('locale', this.get('currentLocale'));
Ember.assert("Only one translation is expected", translations.length === 1);
return translations[0].get('name');
}.property('translation_ids')
});
Everything works out great. But when I edit my category, the "name" property doesn't update :
I have tried a million different things, but nothing work so far. Could someone point out my mistake?
translation_ids is an array, so you want to observe the elements in the array, not just the array itself. Use .property('translation_ids.#each').
I'm writing a custom data adapter (doesn't talk to webserver) and I need to know whether hasMany relationship was changed or not to persist relationship data.
App.Note = DS.Model.extend({
content: attr('string'),
createdAt: attr('date'),
tags: DS.hasMany('tag', { async: true })
});
App.Tag = DS.Model.extend({
name: DS.attr('string'),
notes: DS.hasMany('note')
});
I need to implement adapter's updateRecord:
updateRecord: function(store, type, record) {
// record.changedAttributes() returns changed attributes but not relationships
}
In my case list of tags attached to note may change (via note.get('tags').addObject(..) / removeObject(..)) so I need to get a diff. What's the best way to do that? I can remove all tags in a database and insert new tags but that's not efficient at all
My model is defined as follow:
App.User = DS.Model.extend({
primaryKey: 'username',
username: DS.attr('string'),
name: DS.attr('string')
});
My custom Adapter map:
DS.SocketAdapter.map('App.User', {
primaryKey: 'username',
username: DS.attr('string'),
});
I am testing this model out by typing on console:
App.User.createRecord({username:"user_1"});
var r = App.User.find("user_1");
console.log( r.serialize() );
>> Object {username: null, name: null ..... all null}
But it retuns a "null" Object. Also tested:
App.User.find({username:"user_1"});
But this is doing a remote request. I read that Ember Data does allow you to find records via attributes other than the ID.
So what I am doing wrong in telling Ember data my custom primaryKey?
I think your problem lies in the fact that you are defining username twice. if you map username from your json to your model's primaryKey trough your Adapter, then you should avoid to do the same on the model I guess. There are different approaches where to define the mapping, but the Adapter is the most appropriate place In your case, see here for more details: https://github.com/emberjs/data/blob/master/BREAKING_CHANGES.md#mapping
change your code like so and it should work:
// Model
App.User = DS.Model.extend({
name: DS.attr('string')
});
// Adapter
DS.SocketAdapter.map('App.User', {
primaryKey: 'username'
});
now try to create a new record
App.User.createRecord({username:"user_1", name:"foo"});
and then find the record by it's id as you already did:
var r = App.User.find("user_1");
this
console.log( r.serialize() );
should then give you at least:
>> Object {name: "foo" ...}
hope it helps
I would get the records of my field children. Here the code:
App.User = DS.Model.extend({
name: DS.attr('string'),
online: DS.attr('boolean')
});
App.List = DS.Model.extend({
name: DS.attr('string'),
children: DS.hasMany('App.User'),
online: function() {
var users = this.get("children");
return users.reduce(0, function(previousValue, user){ // no record founds
return previousValue + user.get("online");
});
}.property("children.#each.online")
});
But App.List.find(1).get('online') returns no record. (For some reason I cannot specify that App.List.children contains many records, of type App.Users, as embedded records).
Here is the fiddle: JSBIN and it's output
How I can solve my issue?
Define the embedded Model on your Adapter map:
App.List = DS.Model.extend({
name: DS.attr('string'),
users: DS.hasMany('App.User'), //use "users" as the property name to mantain ember's naming conventions
...
});
App.Adapter = DS.RESTAdapter.extend();
App.Adapter.map('App.List', {
users: {embedded: 'always'} //you can use `always` or `load` which is lazy loading.
});
App.Store = DS.Store.extend({
revision: 12,
adapter: App.Adapter.create()
});
Hope it helps