0
votes

I have two models that are related to each other, a RequestMatcher and Response. A RequestMatcher has many Responses but only oneactiveResponse. How do i observe the activeResponse on the RequestMatcher model so i can use that in templates? Here's what i have.

// request-matcher.js
import DS from 'ember-data';

export default DS.Model.extend({
    path: DS.attr('string'),
    project: DS.belongsTo('project', {async: true}),
    responses: DS.hasMany('response', {inverse: 'requestMatcher', async: true}),
    activeResponse: DS.attr('number'),
    matches_get_request: DS.attr(),
    matches_post_request: DS.attr(),
    matches_put_request: DS.attr(),
    matches_delete_request: DS.attr()
});

and

//response.js
import DS from 'ember-data';

export default DS.Model.extend({
    title: DS.attr('string'),
    body: DS.attr('string'),
    status_code: DS.attr('number'),
    requestMatcher: DS.belongsTo('requestMatcher', {async: true}),
    isActiveResponse: function() {

        if (this.get('isNew')) {
            return false;
        }

        var id = parseInt(this.get('id'));

        return this.get('requestMatcher').then(function (requestMatcher) {

            if (!requestMatcher) {
                return false;
            }

            var activeResponseId = requestMatcher.get('activeResponse');

            return activeResponseId === id;
        });
    }.property('requestMatcher.activeResponse')
});

I'm using a number as activeResponse because ember has trouble referencing the same model type twice on the same model. I can't get the .property() to work correctly on my Response model. It always renders as true. I've also tried this approach but the observer never gets triggered.

//request-matcher.js 
import DS from 'ember-data';
import Ember from 'ember';

export default DS.Model.extend({
    path: DS.attr('string'),
    project: DS.belongsTo('project', {async: true}),
    responses: DS.hasMany('response', {inverse: 'requestMatcher', async: true}),
    activeResponse: DS.attr('number'),
    matches_get_request: DS.attr(),
    matches_post_request: DS.attr(),
    matches_put_request: DS.attr(),
    matches_delete_request: DS.attr(), 
    onActiveResponseChange: function() {
        Ember.run.once(this, 'setActiveResponse');
    }.observes('activeResponse', 'isLoaded'),

    setActiveResponse: function() {

        var activeResponseId = parseInt(this.get('activeResponse'));

        this.get('responses').then(function (responses) {
            responses.forEach(function (response) {
                var isActive = activeResponseId === parseInt(response.get('id'));
                response.set('isActiveResponse', isActive);
            });
        });   
    }
});
1

1 Answers

0
votes

I'm using a number as activeResponse because ember has trouble referencing the same model type twice on the same model.

Therein lies your problem. That should definitely be a relationship and not a number. I've achieved something very similar to this in Ember-Data before, so unless they've made breaking changes in the new betas, you should be able to accomplish it. Here is how I personally would declare those relationships:

export default DS.Model.extend({
    responses: DS.hasMany('response', { inverse: 'requestMatcher', async: true }),
    activeResponse: DS.belongsTo('response', { inverse: null, async: true })
});

Setting the inverse to null will ensure that your Response class doesn't have to know about the relationship (it doesn't seem like it needs to anyway). Now you can use Ember-Data like you would with any other relationship, only you don't have to change anything in the Response model. This should allow you to observe your activeResponse properties as you normally would.