In our Rails backend, we have a lot of Concerns
server side. For example, several models import an AppointableConcern
which allows the resources to be associated with Appointments
. Each model can import an unlimited number of Concerns
.
In our Ember Octane models, we use inheritance instead, and I'm not sure whether that's a good idea. For example, we have these two models...
// models/groupable.js
import { belongsTo } from '@ember-data/model';
import ApplicationModel from './application'
export default ApplicationModel.extend({
group: belongsTo('group', { inverse: 'groupables' }),
});
// models/appointable.js
import { hasMany } from '@ember-data/model';
import Groupable from './groupable';
export default Groupable.extend({
appointments: hasMany('appointment')
});
... as well as some models extending either Appointable
or Groupable
.
To me it seems inheritance has been abused to share logic between classes that are not closely related: An Appointable
is not a specific implementation of a Groupable
(multiple Groupables
can form a Group
) at all.
Now I wonder:
- Is this a recommended/standard way to share this logic between models?
- Is there a more flexible alternative? Considering my example above, directly using
group: belongsTo('group', { inverse: 'groupables' })
in any model that should be groupable andappointments: hasMany('appointment')
in all models that appointments should be allowed to associate with seems like a simple solution.
edit:
We encountered a problem with the solution i sketched out above. It is related to EmberCLI Mirage tests: I wanted to make one more model groupable
, but it does not fit in the inheritance chain well. We couldn't make it inherit from the Groupable
model. So we added this line directly to the new model: group: belongsTo('group', { inverse: 'groupables' })
This works in the browser, but in Mirage I got this error:
The 'article' type does not implement 'groupable' and thus cannot be assigned to the 'groupables' relationship in 'group'. Make it a descendant of 'groupable' or use a mixin of the same name.
But as there is no multiple inheritance, I can't make Article
a descendant of Groupable
and there are no mixins in Mirage at all. So I removed { inverse: 'groupables' }
from my new model, which is ok for the moment, but we shouldn't need to take away functionality from our code just to make a test work.