How to get parent id when creating a child ember js


#1

I want to set parent_id in child records.

My models are Recipe (id, title) and Ingredients(id, about, recipe_id).

I have a form where i create recipe with many ingredients. All works well but i don’t know how to set a parent_id in child records after parent record is created.

Example:

We create recipe (id = 1, title = ‘Title01’). So all our ingredients will have field recipe_id with 1 (id=2, about=‘this is ingredient’, recipe_id=1)

recipe.js.coffee


App.Recipe = DS.Model.extend
  title: DS.attr('string')
  ingredients: DS.hasMany('App.Ingredient')


ingredient.js.coffee

App.Ingredient = DS.Model.extend
  about: DS.attr('string')
  recipe: DS.belongsTo('App.Recipe')


new.emblem (here i create parent Recipe and children Ingredients)

h1 Create recipe

form
  div
    label{bindAttr for='title.elementId'} Title
    Ember.TextField valueBinding='title' name='title' viewName='title'

  div
    label{bindAttr for='about.elementId'} About
    Ember.TextArea valueBinding='about' name='about' viewName='about'

  #ingredients
    h3 Ingredients
    each ingredient in content.ingredients itemViewClass='App.ItemView'
      h3= this.view.rebasedIndex
      .control-group
        .controls
          Ember.TextField valueBinding='ingredient.about'
          a{ action removeIngredient ingredient target='controller' } href='#' Remove
    div
      a{ action addIngredient target='controller' } href='#' Add Ingredient

  button.btn.btn-success{ action save this } Create
  button.btn.btn-inverse{ action cancel this } Cancel

Here is my recipes_new_controller.js.coffee


App.RecipesNewController = Ember.ObjectController.extend
  save: ->
    @transaction.commit()
  cancel: ->
    console.log "cancel recipe"

  addIngredient: ->
    ingredients = @content.get('ingredients')
    ingredients.createRecord
      recipe: @content

  startCreating: ->
    console.log 'startCreating'
    @transaction = @get('store').transaction()
    @set 'content', @transaction.createRecord(App.Recipe, {})

#2

When you create a new ingredient, try setting the recipe relation, something like this:

App.Ingredient.createRecord({about: 'this is ingredient', recipe: yourParentRecipeObject})

where yourParentRecipeObject is your recipe.


#3

I updated my question and added new_controller code. I use


 @set 'content', @transaction.createRecord(App.Recipe, {})

and


 @transaction.commit()

to commit recipe and ingredient at once.

Can you help me to implement your code in my app?


#4

I see, they’re in the same transaction, if you try to set the recipe in the ingredient, it will be set in ember, but since the object does not exist yet, you won’t have an id, that’s why the recipe_id is not being set in your db, you know, ember does asynchronous calls.

What you can do is this:

wherever you have the setup of your store, do something like this:

App.Adapter.map App.Recipe,    
  ingredients:
    embedded: "always"

and in your ember models:

App.Recipe = DS.Model.extend
  title: DS.attr('string')
  ingredients: DS.hasMany('App.Ingredient', {embedded: 'always'})

App.Ingredient = DS.Model.extend
  about: DS.attr('string')
  recipe: DS.belongsTo('App.Recipe', {embedded: 'always'})

and then, you just have to push your ingredients to your recipe, like this:

recipe.get('ingredients').pushObject(ingredient)

and in your server, you’ll get a JSON like this:

{"recipe"=>{"about"=>"HELLO", "ingredients"=>[{"about"=>"HI"}]}}

and you can then do the magic in your server, create the recipe then create the ingredients with the right recipe_id.

otherwise, you will have to commit first the recipe and register a listener on the recipe.didCreate, after that you’ll have the recipe object with its id, that way you could then create the ingredients.

Hope this helps.


#5

Thanks a lot for help. I’ve done it but I think the right way is to create a listener and then set a recipe_id to ingredient. Mb someone has good examples of such app with listeners?