I have the following model
MyApp.Company = MyApp.User.extend
companyName: DS.attr('string')
companyEmail: DS.attr('string')
cvr: DS.attr('number')
services: DS.hasMany('service')
Which has many services
MyApp.Service = DS.Model.extend
name: DS.attr('string')
description: DS.attr('string')
content: DS.attr('string')
avatar: DS.attr('string')
smallAvatar: DS.attr('string')
serviceField: DS.belongsTo('serviceField')
companies: DS.hasMany('company')
Now i have a panel, where the user adds services to his company, and end up pushing the save button which triggers this action in my controller.
saveAccount: ->
#get('model').save()
Now my problem is that, with the new services added, i would expect the data in the put request to look something like this.
company: {
company_email: "fsfsdfsdf"
company_name: "Elvar's biks"
cvr: 389298498
services: [1,4,2]
}
But the "services" is missing; am i expecting a wrong json structure? If so, how should i tackle this?
Might be worth noting, that all the object are created before hand, so the client i choosing from existent services, i just need to create the relations server side.
Looks like you are trying to set up a many to many relationship, so you'll want to use a bridge table/model here.
First, create a new model called CompanyService:
MyApp.CompanyService = DS.Model.extend
company: DS.belongsTo 'company'
service: DS.belongsTo 'service'
Next, update your company model:
MyApp.Company = MyApp.User.extend
companyName: DS.attr('string')
companyEmail: DS.attr('string')
cvr: DS.attr('number')
companyServices: DS.hasMany('companyService', {async:true})
Then, update your service model:
MyApp.Service = DS.Model.extend
name: DS.attr('string')
description: DS.attr('string')
content: DS.attr('string')
avatar: DS.attr('string')
smallAvatar: DS.attr('string')
serviceField: DS.belongsTo('serviceField')
companyServices: DS.hasMany('companyService', {async:true})
From here you'll need to modify whatever backend setup (Rails?) you have going to accommodate this new model relationship.
Hope that helps!
Related
I have access to API endpoints to only get, cannot suggest or apply any modifications.
This a sample schema of each api:
var person = DS.Model.extend {
firstName: DS.attr(),
lastName: DS.attr()
}
var credit = DS.Model.extend {
name: DS.attr(),
personId: : DS.belongsTo('person')
}
var debit = DS.Model.extend {
name: DS.attr(),
personId: : DS.belongsTo('person')
}
I can get api/person, api/credit, api/debit individually. After fetching the data. I want to map relationship between person and credit/debit similar to this...
var person = DS.Model.extend {
firstName: DS.attr(),
lastName: DS.attr(),
**debits: DS.hasMany('debit'),**
**credits: DS.hasMany('credit')**
}
How can I accomplish this in ember-data?
JSbin - http://emberjs.jsbin.com/gewowucamo/8/edit?html,js,output
Everything you're doing will work. When you load the data using store.push() it builds the related relationships for you (if they exist).
This JSBin gives you an example of what you're doing that works.
I believe the problem you have is likely related to using Fixtures - and at a guess I would assume it doesn't follow the same behaviour/logic when loading data.
Fixtures are being removed from Ember (see this PR)
You have already answered your own questions, as the code you have given should already work.
I have a model called question and subject:
App.Question = DS.Model.extend({
title: DS.attr('string'),
description: DS.attr('string'),
answers: DS.hasMany('answer',{async:true }),
subjects: DS.hasMany('subject',{async:true })
});
App.Subject = DS.Model.extend({
description: DS.attr('string'),
question: DS.belongsTo('question')
});
I want to return all the questions that have a tagged with specific subject for example
findAll questions where subjects.contain(aSubject)
Do i have to implement a filter on the embedded SubjectsArray or is there a slick way to do this with Ember-data?
thanks
I'm trying to set up a hasMany relationship between two models and a hasOne (belongsTo in the current version of Ember Data) between the hasMany and hasOne.
I'm working with Ember Data and have a made a RESTful API that works according to Ember's conventions. All the classes can be queried individually.
Bookmark = hasMany -> Termbinding
Termbinding = belongsTo -> Term
Term = belongsTo -> Termbinding
So the goal is to fetch a Bookmark and get the Terms that are attached to it through the Termbinding. I would already be pretty happy to get the Bookmark to Termbinding relation working. I went through all questions posted on here, sadly enough that didn't work.
Router.js
var Router = Ember.Router.extend();
Router.map(function() {
this.resource('bookmarks', { path:'bookmarks'});
this.resource('bookmark', { path:'bookmarks/:bookmark_id' });
this.resource('termbindings', { path:'termbindings' });
this.resource('termbinding', { path:'termbindings/:termbinding_id' });
});
export default Router;
Bookmark.js
var Bookmark = DS.Model.extend({
url: DS.attr('string'),
description: DS.attr('string'),
visits: DS.attr('number'),
termbinding: DS.hasMany('termbinding')
});
export default Bookmark;
Termbinding.js
var Termbinding = DS.Model.extend({
bookmarkId: DS.attr('number'),
termId: DS.attr('number'),
termOrder: DS.attr('number'),
bookmarks: DS.belongsTo('bookmark')
});
export default Termbinding;
I hope someone can help me because this is preventing me from using Ember for my bookmark application. Thanks in advance.
It might be wise to explicitly specify your inverses, i.e.
var Termbinding = DS.Model.extend({
bookmarkId: DS.attr('number'),
termId: DS.attr('number'),
termOrder: DS.attr('number'),
bookmarks: DS.belongsTo('bookmark', { inverse: 'termbinding' })
});
export default Termbinding;
var Bookmark = DS.Model.extend({
url: DS.attr('string'),
description: DS.attr('string'),
visits: DS.attr('number'),
termbinding: DS.hasMany('termbinding', { inverse: 'bookmarks' })
});
export default Bookmark;
Ember Data will try to map inverses for you, however, it is not without faults. It could possibly be that your pluralization of 'bookmarks' on a DS.belongsTo relationship is throwing off its automatic inverse mapping. Typically for belongsTo you would use the singular, 'bookmark'. Conversely, your hasMany would be termbindings: DS.hasMany('termbinding')
Also, if you could show where you're invoking the models that would be greatly appreciated. Typically I find that creating a JSbin at emberjs.jsbin.com helps me isolate the problem and also provides a collaborative space to debug and experiment.
I have the following models:
App.Company = DS.Model.extend({
name: DS.attr('string'),
accounts: DS.hasMany('App.Account', {
inverse: 'company'
})
});
App.Account = DS.Model.extend({
login: DS.attr('string'),
first_name: DS.attr('string'),
last_name: DS.attr('string'),
email: DS.attr('string'),
password: DS.attr('string'),
password_confirmation: DS.attr('string'),
company: DS.belongsTo('App.Company')
});
The company is defined as being embedded in the account:
DS.RESTAdapter.map('App.Account', {
company: { embedded: 'always' }
});
When I create a new account, the company data is correctly embedded in the account data and I'm seeing the POST request that I expect on the server side:
Started POST "/accounts" for 127.0.0.1 at 2013-06-27 13:30:53 +0200
Processing by AdminUsersController#create as JSON
Parameters: {"account"=>{"login"=>"fsdfdf", "first_name"=>"fgdfgh", "last_name"=>"fsfdsfdsfsd#fgfdgdfgf.de", "email"=>"dsfdsgds#frgdfgfgdfg.de", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "company"=>{"name"=>"gfdhgtrhzrh"}}}
However, I'm also seeing an additional POST request for the company itself:
Started POST "/companies" for 127.0.0.1 at 2013-06-27 13:30:53 +0200
Processing by CompaniesController#create as JSON
Parameters: {"company"=>{"name"=>"gfdhgtrhzrh"}}
I'm setting up the models as follows:
this.transaction = this.get('store').transaction();
var account = this.transaction.createRecord(App.Account, {});
account.set('company', this.transaction.createRecord(App.Company, {}));
When the user clicks save, I simply commit the transaction:
this.transaction.commit();
Is that a bug or am I doing something wrong? Spent quite some time on that already...
Thanks for help!
this.transaction.createRecord(App.Company, {})
The code fragment creates the separate company entity. Is it really such a surprise there is a post action for it?
As far as I remember that was never actually supported in the (old) version of Ember Data I used back then. Newer versions handle that case differently anyway so I'd say this is outdated and close it.
I'm having to override a route to do some custom loading of models like this:
App.EventsIndexRoute = Ember.Route.extend
model: (params) ->
origin = LJ.origin().join(',')
location = [LJ.stripQuery(params.loc2), params.loc1].join(',')
h = $.param(origin: origin, location: location)
$.getJSON "#{LJ.CONFIG.api.url}/events?#{h}"
The JSON returned includes sideloaded models, but they aren't being loaded by ember. I'm guessing I need to do something to get them loaded but I don't know what. I'd appreciate any help on this.
Here's an example of the returned JSON.
Update
Here's the model definition:
App.Event = DS.Model.extend
acts: DS.hasMany('App.Act')
ageLimit: DS.attr('string')
centsAdvance: DS.attr('number')
centsDoor: DS.attr('number')
currency: DS.attr('string')
description: DS.attr('string')
endsAt: DS.attr('number')
priceAdvance: DS.attr('string')
priceDoor: DS.attr('string')
repeats: DS.attr('string')
repeatsUntil: DS.attr('string')
startsAt: DS.attr('number')
title: DS.attr('string')
url: DS.attr('string')
venue: DS.belongsTo('App.Venue')
venueSection: DS.attr('string')
IMO this has nothing to do with your route but with your model. Make sure that you declare it like that (they have to be present of course)
App.Event = DS.Model.extend({
venue: DS.belongsTo('App.Venue'),
acts: DS.hasMany('App.Act'),
// go on with the model
});
I found it helpful to include a {{ log event }} into the template to dig into the controller and the model and make sure it really does not get loaded
P.s: You do return the ajax response in the route, do you not?
The link of the example JSON you are returning doesn't work, could you please provide a working sample?
You are going around Ember-data for your ajax call, which would mean you will need to handle deserializing it in a more manual manner. If you want ember to do that for you, you need to call into the store, like:
App.EventsRoute = Ember.Route.extend({
model: function() {
// other code here if necessary
return this.store.find('event', params._id);
}
Also, whenever I am not getting my related objects (venues in your case) loaded into the store, it is because the JSON isn't in the format Ember is expecting, which would look like this:
{
Events: [{ Id: 1, Venues: [1], ... }],
Venues: [{ Id: 1, ... }]
}
NOT LIKE THIS:
{
Events: [{ Id: 1, Venue: { Id: 1, ... }, ... }],
}
Maybe this helps?