My Setup:
Rails 4.1 with active-model-serializer gem
Ember 1.9.0
Ember-Data 1.0.0 beta with ActiveModelAdapter used as ApplicationAdapter
I have an STI table called Jobs that has many subtypes. Each Job hasMany LineItems. I am using ActiveModelSerializers in Rails to serialize my JSON data in a way that Ember-Data understands. My Models are set up this way in Rails:
class Job < ActiveRecord::Base
has_many :line_items
...
end
class DisposalJob < Job
...
end
class SupplyJob < Job
...
end
class LineItem < ActiveRecord::Base
belongs_to :job, polymorphic: true
...
end
And this way in Ember:
App.Job = DS.Model.extend
line_items: DS.hasMany "line_item"
...
App.DisposalJob = App.Job.extend
...
App.SupplyJob = App.Job.extend
...
App.LineItem = DS.Model.extend
job: DS.belongsTo "job",
polymorphic: true
My serializers in Rails are set up like so:
class BaseSerializer < ActiveModel::Serializer
ActiveModel::Serializer.setup do |config|
config.embed = :ids
config.embed_in_root = true
end
end
class JobSerializer < BaseSerializer
...
has_many :line_items
end
class DisposalJobSerializer < JobSerializer
...
end
class SupplyJobSerializer < JobSerializer
...
end
class LineItemSerializer < BaseSerializer
belongs_to :job, polymorphic: true
end
My problem is when I try to save a line_item to a job subclass (I don't use the Job class directly), Ember refuses to see that a DisposalJob is a type of job and throws an error that it expects a "Job" record to be saved to that relation, rather than a "DisposalJob" or "SupplyJob", despite that these are both subclasses of Job. I'm an Ember newbie, so any help would be greatly appreciated.
EDIT: Here is the error I get when trying to save a DisposalJob to the Job relation on LineItem in Ember:
Uncaught Error: Assertion Failed: You can only add a 'job' record to this relationship
EDIT: I've tried refactoring this so that line_item accepts both job_id and job_type instead of just job_id. Ember still tells me it's expecting a "job" record in this relation. I've tried skirting the issue by eliminating the "belongsTo on the ember side and just have line_item include job_id: DS.attr "number" and job_type: DS.attr "string". This allows me to save the record, but without the belongsTo association, the line-items won't be found when Ember displays the job they are attached to.
If you have MODEL_FACTORY_INJECTIONS enabled you will not be able to use subclasses as the prototype based inheritance checks fail Issue #5573 and Issue #2342 and Issue #2316.
I found doing STI at the model layer with Ember.Data and indeed Ember.Model is not really workable for the following reasons:
So what you're left with is to treat things kind of like you do in the DB on your server, that is support all possibilities in your data model. This means just define all possible relationships and attributes.
When it comes to validation and other business rules, controllers can provide the façade you need. The Ember way is for controllers to decorate models and you can certainly create different classes of controller to decorate models how you please.