EmberData belongsTo not working with just ID - ember.js

I am trying to create a belongsTo relation, but i am always getting the following error:
Error while loading route: Error: Assertion Failed: You must include
an id in a hash passed to push
My model definition looks like this:
GambifyApp.Bet = DS.Model.extend({
scoreT1: DS.attr('string'),
scoreT2: DS.attr('string'),
user: DS.belongsTo('user')
});
Within my Json return I have simply
{
id:128433,
user:8926,
points:0,
game:94,
scoreT1:2,
scoreT2:2
}
The user value under user is my user id. Regarding Documentation(http://emberjs.com/guides/models/the-rest-adapter/#toc_relationships) it should look exactly like this. But its causing me this error. If I change my "user" property to an attribute everything is working fine.
Update:
Found the problem in my serializer that is extracting all relations and adds them as sideloaded models. Of course it was not handling the case where this relation is only an id instread of the whole object.

If you aren't including the data associated with user the relationship should be async.
GambifyApp.Bet = DS.Model.extend({
scoreT1: DS.attr('string'),
scoreT2: DS.attr('string'),
user: DS.belongsTo('user', {async:true})
});

Related

Ember data embedded has one relationship for ember-data.1.0.0

I am trying to serialize a user object and pass it to an ember client. My app uses the RESTserializer.
A user object has_one address object. There is no separate endpoint for just the address so I can't just provide a foreign key id and sideload it.
The JSON received just includes address as an object and looks something like this:
{"user":
{
"id":"5",
"name":"Andrew",
"address":
{
"id":"3",
"addressable_id":"5",
"street":"1",
"country_code":"US"
}
}
On the ember side I have a user model
App.User = DS.Model.extend({
name: DS.attr('string'),
address: DS.belongsTo('address'),
//hasOne via belongsTo as suggested by another SO post:
//http://stackoverflow.com/questions/14686253/how-to-have-hasone-relation-with-embedded-always-relation
});
and an address model
App.Address = DS.Model.extend({
addressable_id: DS.attr('string'),
street: DS.attr('string'),
country_code: DS.attr('string'),
user: DS.belongsTo('user')
});
Currently running this code throw an error in the console:
TypeError: Cannot read property 'typeKey' of undefined
which can be fixed by removing the
address: DS.belongsTo('address'),
line in the user model but then the relationship doesn't load properly.
So what am I doing wrong configuring this? I am having a hell of a time finding up to date documentation on this.
You need to use the DS.EmbeddedRecordsMixin on a per-type serializer.
In your case, you would need to do the following :
App.UserSerializer = DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
attrs: {
address: {embedded: 'always'}
}
});
as explained in this excellent answer.

Ember Data Endpoint Issue

I am experiencing a weird issue while using ember data. With the following user model everything works great.
App.User= DS.Model.extend({
firstName: attr(),
lastName: attr()
});
I call user.save() and is posts to /users with the correct data. However when i try and use a user model that has relationships on it
App.User= DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string'),
friends: DS.hasMany('user'),
followers: DS.hasMany('user'),
});
For some reason with that model when i call user.save() it posts to /Users (note the capitalization. Also, in the response it expects it formatted {"User": {...}} instead of {"user": {...}}
Anyone run into this before? I could always add the additional endpoints to my api however I would like it to work uniform if possible.
I did a little more digging and it seems when you add a relationship to the model there is a computed property called relationshipsByName. This property, in my example, will set the meta.type property to 'User'. It works without relationships because I called the createRecord method with 'user' so i assume it uses this as the type. When the relationship is added it uses 'User'
I found that modelFor calls the resolvers normalize on the keys. So the solution is to add a custom resolver like below.
App = Ember.Application.create({
Resolver: Ember.DefaultResolver.extend({
normalize: function(fullName) {
var n = this._super(fullName);
if(fullName.startsWith('model')){
n = n.replaceAt(6, n[6].toLowerCase());
}
return n;
}
})
});
*note i have string extensions for startsWith and replaceAt

ember computed property based on model properties

I'm quite new to ember and trying to write a computed property that checks whether or not a user is online based on their 'state' property, defined in the user model, and then returns a count of the number of users online. This is what I have been attempting, which is not working-
onlineUsers: function() {
return this.get("model").filterBy("state", "online").get("model.length");
}.property("'model.[]'"),
And this is my user model-
App.User = DS.Model.extend({
name : DS.attr('string'),
email : DS.attr('string'),
state : DS.attr('string'),
subjects : DS.hasMany('subject')
});
Can anyone point out what I'm doing wrong?
You need to use model.#each.state
onlineUsers: function() {
return this.get("model").filterBy("state", "online").get("length");
}.property("model.#each.state"),
Also model.length in the end not work, because the result of the filterBy is a new array, and you want the length of that array.

Looking up values on a belongsTo relationship

I have a system where I want users to add flags (hashtags) to items. Here's my models:
Social.Item = DS.Model.extend({
source: DS.belongsTo ('source'),
url: DS.attr (),
post_timestamp: DS.attr(),
summary: DS.attr(),
item_flags: DS.hasMany('item_flag', {async: true})
});
Social.Flag = DS.Model.extend({
kind: DS.attr(),
name: DS.attr(),
item_flags: DS.hasMany('item_flag', {async: true})
});
Social.ItemFlag = DS.Model.extend({
item: DS.belongsTo('item', {async: true}),
user: DS.belongsTo('user', {async: true}),
flag: DS.belongsTo('flag', {async: true}),
});
Here's the relevant handlebars code:
{{#each item in site.sorted_items itemController="item"}}
{{{item.summary}}}
{{#each item_flag in item.item_flags}}{{item_flag.flag}}*FF*{{/each}}
{{/each}}
The system outputs a few FF tags for each item - there's definitely item_flag elements in the database, and I can see the calls on my REST endpoint - the system is requesting the item_flags from the database. It just seems like the object on the other side of the belongsTo relationship isn't available here. I tried extending the ItemFlag model to contain this code:
flag_string: function() {
return this.get('flag').then(function (data) {return data.get('name')});
}.property('flag')
But that just throws a NPE - this.get('flag') on the ItemFlag model returns null. There seems to be some mention of an "embed: always" defined on the adapter, but (a) that's from pre- ember-data-beta days, and (b) it didn't help (also, my records aren't embedded).
What I want to do in the general case here is figure out how to look at a model's parent model, as defined by the relationships in the database.
Turns out, I fell afoul of the new ember-data serializer expectations. My item_flag serializer was responding with json that looked like {id: 1, flag_id:1, user_id:1} when what it should have looked like was {id: 1, flag:1, user:1}. This caused (apparently), the item_flag to get created without the proper parameters.

Ember data override foreign key convention

I am trying to load json data into the following model using findAll:
App.Territory = DS.Model.extend({
name: DS.attr('string'),
code: DS.attr('string'),
regionId: DS.attr('string')
});
When the model is actually created, converting back to JSON shows that it has a reference for region_id, which is null, but nothing for regionId. Does anyone know of a way to override this default convention?
Determined that it was the keyForAttribute method on the RESTSerializer that was calling Ember.String.decamelize(name) which formated the key. I was able to work around this by adding the line:
App.store.adapter.serializer.keyForAttributeName = function (type, name) {
return name;
}