Matthew Clark
Matthew Clark

Reputation: 571

Ember recursive parent-child relationship errors

I have a rails backend for which I'm trying to make an Ember.js admin panel. Basically there are categories that can be parents to other categories and categories can have many "stickers" but "stickers" can also have many categories. Please consider the backend structure immutable in this(I can fiddle with the serializer, but that's it). Here are my serializers:

Category Model:

class Category < ActiveRecord::Base
  has_many :parent_cats, class_name: "CatToCat",foreign_key: "child_id"
  has_many :children_cats, class_name: "CatToCat",foreign_key: "parent_id"

  has_many :parents, through: :parent_cats
  has_many :children, through: :children_cats
end

Category to Category Model:

class CatToCat < ActiveRecord::Base
  belongs_to :parent, class_name: "Category"
  belongs_to :child, class_name: "Category"
end

Sticker:

class StickerSerializer < ActiveModel::Serializer
  embed :ids, include: true
  attributes :id, :text, :audio, :created_at, :image, :smallImage, :updated_at, :stickerServerID
    has_many :categories
end

Category:

class CategorySerializer < ActiveModel::Serializer
  embed :ids, include: true
  attributes :id, :name, :catImage, :created_at, :catOrder, :catServerID, :updated_at
  has_many :stickers
  has_many :children
  has_many :parents
end

Here are the Ember Models:

Sticker:

App.Sticker = DS.Model.extend({
    audio: DS.attr("string"),
    image: DS.attr("string"),
    smallImage: DS.attr("string"),
    stickerServerID: DS.attr("string"),
    text: DS.attr("string"),
    updated_at: DS.attr("date"),
    created_at: DS.attr("date"),

    categories: DS.hasMany("category")
});

Category:

App.Category = DS.Model.extend({
    name: DS.attr("string"),
    catImage: DS.attr("string"),
    catOrder: DS.attr("string"),
    catServerID: DS.attr("string"),
    updated_at: DS.attr("date"),
    created_at: DS.attr("date"),

    stickers: DS.hasMany("sticker"),

    children: DS.hasMany("category",{inverse:'parents'}),
    parents: DS.hasMany("category",{inverse:'children'})
});

Store:

App.ApplicationSerializer = DS.ActiveModelSerializer.extend({
  keyForAttribute: function(attr){
    console.log("keyForAttribute:"+attr+"->"+this._super(attr));
  if (attr == "smallImage" || attr == "stickerServerID" || attr == "catOrder" || attr == "catImage" || attr == "catServerID"){
    console.log("try:"+attr);
    return attr;
  }else{
    return this._super(attr);
  }
});

App.ApplicationStore = DS.Store.extend({
  adapter: '-active-model'
});

The error that Chrome reports:

Error while loading route: Error: No model was found for 'child'

The error that Firefox reports is useless :-/

Happy to add any other info that is helpful! Thanks in advance!

Upvotes: 0

Views: 300

Answers (1)

Tim Baas
Tim Baas

Reputation: 6185

There is a way to do this, but it's not perfect.

  • Add child_ids to the attributes in your serializer.
  • Set children to a DS.hasMany in your model in Ember.

Rails:

# app/serializers/category_serializer.rb    
class CategorySerializer < ActiveModel::Serializer
  embed :ids, :include => true
  attributes :id, :name, :child_ids
end

Ember (EmberCLI):

// app/models/category.js
import DS from 'ember-data';

export default DS.Model.extend({
  children: DS.hasMany('category'),
  name: DS.attr('string'),
});

The problem is the serializer doesn't load the children automatically, so you need to always load all categories at once.

Upvotes: 1

Related Questions