Persisting hasMany assoc in emberdata - ember.js

Any examples of persisting new model entity with hasMany associacion?

Here is an example, see http://jsfiddle.net/pangratz666/vuT2v/
App.Comment = DS.Model.extend({
text: DS.attr('string')
});
App.Post = DS.Model.extend({
title: DS.attr('string'),
comments: DS.hasMany('App.Comment')
});
var first = App.Comment.createRecord({
id: 'firstComment',
text: 'first comment'
});
var second = App.Comment.createRecord({
id: 'secondComment',
text: 'second comment'
});
var post = App.Post.createRecord({
id: 1,
title: 'post title'
});
var comments = post.get('comments');
comments.addObject(first);
comments.addObject(second);
App.store.commit();​

Related

How do you save a many-to-many relationship in Ember and Firebase

Let's say we have many medicines that can be prescribed to many patients. Our model would look like this:
App.Medicine = DS.Model.extend({
name: DS.attr(),
patients: DS.hasMany('user', { async: true }),
});
App.User = DS.Model.extend({
name: DS.attr(),
medicines: DS.hasMany('medicine', { async: true })
});
In this scenario, how do we save records to a Firebase store?
App = Ember.Application.create();
App.ApplicationAdapter = DS.FirebaseAdapter.extend({
firebase: new Firebase('https://YOUR_FIREBASE.firebaseio.com/')
});
App.Router.map(function(){ });
App.Medicine = DS.Model.extend({
name: DS.attr(),
patients: DS.hasMany('user', { async: true }),
});
App.User = DS.Model.extend({
name: DS.attr(),
medicines: DS.hasMany('medicine', { async: true })
});
App.IndexRoute = Ember.Route.extend({
model: function() {
var medicines = this.store.find('medicine');
var users = this.store.find('user');
return {
medicines: medicines,
users: users
};
},
actions: {
savePost: function(){
var store = this.store;
var medicine1 = store.createRecord('medicine', {name: 'aspirin'});
var patient1 = store.createRecord('user', {name: 'Jane'});
var patient2 = store.createRecord('user', {name: 'Peter'});
medicine1.save()
.then(function(){
return Ember.RSVP.Promise.all([
patient1.save(),
patient2.save()
])
.then(function(){
var promises = [];
var patientsOfMedicine1 = medicine1.get('patients');
var medicinesOfPatient1 = patient1.get('medicines');
var medicinesOfPatient2 = patient2.get('medicines');
promises.push(patientsOfMedicine1, medicinesOfPatient1, medicinesOfPatient2);
return Ember.RSVP.Promise.all(promises);
})
.then(function(arrayOfAttachedArrays){
var promises = [];
var patientsOfMedicine1 = arrayOfAttachedArrays[0];
var medicinesOfPatient1 = arrayOfAttachedArrays[1];
var medicinesOfPatient2 = arrayOfAttachedArrays[2];
patientsOfMedicine1.addObjects(patient1, patient2);
medicinesOfPatient1.addObject(medicine1);
medicinesOfPatient2.addObject(medicine1);
promises.addObjects(medicine1.save(),patient1.save(),patient2.save());
return Ember.RSVP.Promise.all(promises);
});
});
}
}
});
Notes:
Thanks to David Govea for showing me how this works.
If there's a better way to do this, please post below.

createRecord with ember-data + ember-data-django-rest-adapter

I'm currently working on creating an ember application using ember/ember-data/ember-data-django-rest-adapter with Django backend.
I'm having issue creating record when there's belongsTo and hasMany relationship going on.
I currently have this code:
App.Article = DS.Model.extend({
title: attr(),
description: attr(),
authors: hasMany('author'),
category: belongsTo('page'),
slug: attr(),
content: attr(),
articleContent: Ember.computed.alias("content"),
published: attr(),
publish_from: attr(),
isScheduled: function() {
return moment().isBefore(moment(this.get('publish_from')));
}.property('publish_from'),
articlePublishDate: function() {
return moment(this.get('publish_from')).format('MMMM Do YYYY');
}.property('publish_from'),
articlePublishTime: function() {
return moment(this.get('publish_from')).format('h:mm a');
}.property('publish_from'),
//content_type: belongsTo('content_type', { async: true }),
content_type: attr()
});
App.Page = DS.Model.extend({
title: attr(),
description: attr(),
pageContent: attr(null, {
key: 'content'
}),
templateFile: attr(null, {
key: 'template'
}),
slug: attr(),
tree_path: attr(),
tree_parent: belongsTo('page'),
site: attr()
});
App.Author = DS.Model.extend({
name: attr(),
slug: attr(),
description: attr(),
text: attr(),
email: attr(),
photo: attr(),
user: belongsTo('user'),
});
// create article
App.ArticleCreateController = Ember.ObjectController.extend({
editMode: false,
allAuthors: function() {
return this.store.find('author');
}.property(),
allPages: function() {
return this.store.find('page');
}.property(),
actions: {
save: function(session) {
var self = this;
var article = this.get('model');
var newArticle = this.store.createRecord('article', {
content_type: "19",
content: article.get('articleContent'),
description: article.get('description'),
publish_from: article.get('publish_from'),
published: article.get('published'),
slug: article.get('slug'),
title: article.get('title')
});
this.store.find('page', 3).then(function(page) {
newArticle.set('category', page);
});
newArticle.save();
}
}
});
All I really want to do is POST data like this to apiRoot/articles/ (along with other attributes, but those are working the way they should)
authors: [1,3,5], // hasMany
category: 3 // belongsTo
But when I make a POST request, category returns as null for some reason. All I want to extract from it is just the id itself. Also, I have no clue how to extract the array of authors. I tried posting the data, and it tells me something about it needing to be 'App.Author'.
First, at the current time you need a fork of ember-data because async create is currently broken (as it's a promise and the internal serializer won't wait for it to resolve).
Pull down this branch, do a npm install + grunt test to build the adapter. Also you need to use the forked build of ember-data in that branch'es test lib directory (until ember-data pulls in the fix for this)
https://github.com/toranb/ember-data-django-rest-adapter/tree/asyncBelongsToHasManyWIP
Then inside your controller you can do something like this to "create" the customer and appointment (notice -async belongsTo/hasMany relationship)
App.Customer = DS.Model.extend({
name: DS.attr('string'),
appointments: DS.hasMany('appointment', { async: true})
});
App.Appointment = DS.Model.extend({
details: DS.attr('string'),
customer: DS.belongsTo('customer', { async: true})
});
var customer = {
name: 'foobar'
}
this.store.createRecord('customer', customer).save().then(function(persisted) {
var appointment = {
details: 'test',
customer: persisted
}
return self.store.createRecord('appointment', appointment).save().then(function(apt) {
persisted.get('data').appointments.pushObject(apt);
router.transitionTo('index');
});
});

Find record from belongsTo association in Ember.js

How can I get the associated record from an Ember model? Or: how to get the record from the Promise Object?
Customer model
Docket.Customer = DS.Model.extend({
name: DS.attr('string'),
initial: DS.attr('string'),
description: DS.attr('string'),
number: DS.attr('string'),
archived: DS.attr('boolean'),
projects: DS.hasMany('project',{ async: true })
});
Project model
Docket.Project = DS.Model.extend({
name: DS.attr('string'),
description: DS.attr('string'),
number: DS.attr('string'),
archived: DS.attr('boolean'),
customer: DS.belongsTo('customer', { async: true })
});
Find method
var project = this.store.find('project', id).then(function(data) {
console.log(data.get('customer').toString());
});
Console output
<DS.PromiseObject:ember654>
JSON response
{"projects":[
{
"id":1,
"name":"test",
"number":"a310",
"description":null,
"archived":false,
"customer_id":22
}
]};
use another then on the get :)
var project = this.store.find('project', id).then(function(data) {
data.get('customer').then(function(c){
console.log(c);
}
});

Ember.js access model values

I'd like to be able to modify/validate data before actually saving.
Model
App.Post = DS.Model.extend({
title: DS.attr('string'),
author: DS.attr('string'),
date: DS.attr('date', { defaultValue: new Date() }),
excerpt: DS.attr('string'),
body: DS.attr('string')
});
Route
App.PostsNewRoute = Ember.Route.extend({
model: function() {
return this.get('store').createRecord('post');
},
actions: {
doneEditing: function() {
debugger;
this.modelFor('postsNew').save();
this.transitionTo('posts.index');
}
}
});
So, the questions, before the .save() I want to, let's say, validate that the title is not empty or so.
Everything I've tried gets undefined, or [Object object] has no .val() method. I don't know how to get to the values of the model. How can I do that?
And the other thing I have in mind. Is that defaultValue working as intended? I want to set Date() to every new created post. Somehow date is not being recorded since it's not showing.
Thanks.
App.PostsNewRoute = Ember.Route.extend({
model: function() {
return this.get('store').createRecord('post');
},
actions: {
doneEditing: function() {
debugger;
var model = this.modelFor('postsNew');
var title = model.get('title');
model.save();
this.transitionTo('posts.index');
}
}
});

How to dynamically load fixtures in ember.js

Hey I'm having trouble dynamically loading fixture data into my emberjs models. How should I go about doing this? The addArtist function at the bottom will add one song correctly but I'm not sure how to adapt this to loading all of the songs into the data store correctly. Is there an easier way than adding each one individually?
App.Store = DS.Store.extend({
revision: 13,
adapter: 'DS.FixtureAdapter'
});
App.Artist = DS.Model.extend({
name: DS.attr('string'),
tracks: DS.hasMany('App.Tracks')
});
App.Tracks = DS.Model.extend({
videoid: DS.attr('string'),
title: DS.attr('string'),
duration: DS.attr('number')
});
App.Artist.FIXTURES = [];
App.Tracks.FIXTURES = [];
App.loadFixtures = function(){
$.getJSON('/artists', function(data){
$.each(data.artists, function(i,v){
App.Artist.createRecord(v);
});
});
$.getJSON('/tracks', function(data){
$.each(data.tracks, function(i,v){
App.Tracks.createRecord(v);
});
});
};
App.addArtist = function(){
var artist = App.Artist.createRecord({
id: 3,
name: 'Justin Martin'
});
var track = App.Tracks.createRecord({
id: 300,
title: 'Jungle Mix',
duration: 200
});
artist.get('tracks').pushObject(track);
};
Sample JSON Responses:
{"artists":[
{"id":1,"name":"The (International) Noise Conspiracy","track_ids":[1,2,3,4]},
{"id":2,"name":"0SM","track_ids":[5]},
{"id":3,"name":"2am","track_ids":[6,7,8]}
]}
{"tracks":[
{"id":1,"videoid":"FyjmCg_VMU0","title":"Smash It Up","duration":197},
{"id":2,"videoid":"jKXWm9yi4DY","title":"Only Lovers Left Alive","duration":162},
{"id":3,"videoid":"fwbleH55CCk","title":"Up For Sale","duration":211},
{"id":4,"videoid":"50JdKhIB1EQ","title":"A New Morning, Changing Weather","duration":270},
{"id":5,"videoid":"bd6ve0ydHVo","title":"The Landing feat. Alex G - Original Mix","duration":322},
{"id":6,"videoid":"RnwVtbMW4x4","title":"Anxious","duration":238},
{"id":7,"videoid":"Yo0zsqa06ZE","title":"I Did Wrong","duration":305},
{"id":8,"videoid":"_9ydBAgg130","title":"I Love You (feat. Baekchan & Joohee)","duration":219}
]}
Should I include the track_ids in the Artists response or do they get added when I call this method?
artist.get('tracks').pushObject(track);