Here's my situation, simplified:
// model/price-source.js
export default DS.Model.extend({
price: DS.attr('number'),
product: DS.belongsTo('product')
)};
// model/product.js
export default DS.Model.extend({
priceSources: DS.hasMany('price-source')
)};
In my products template, I want to be able to simply refer to the source with the lowest price, like so:
// templates/products.hbs
{{#each model as |product|}}
<span>{{product.cheapestSource.price}} €</span>
{{/each}}
How would I go about setting up the cheapestSource computed property? I imagine I'd have to do something like this:
// model/product.js
cheapestSource: Ember.computed('priceSources', function() {
let sources = this.get('priceSources');
let cheapest = sources.get('firstObject');
// iterate over sources and set cheapest to whichever has the lowest price
return cheapest;
})
The problem is, I have little idea how to loop through the hasMany relationship (apart from using the handlebars {{#each}} helper), and whether a computed property can even consist of a single Ember Data record from another model. Does sources.@each somehow play into this, if so, how?
Any help and ideas are appreciated, thanks.
I got it working by sorting the priceSources into a computed property sortedPrices, then calling the firstObject of the sortedPrices in the template. Will edit this post with the actual solution soon.
It took ages to test because I didn't realize that commenting out handlebars blocks will break the rendering of html inside them. Note to self...
EDIT: This did it:
export default DS.Model.extend({
priceSources: DS.hasMany('price-source'),
sortProperties: ['price:asc'],
sortedSources: Ember.computed.sort('priceSources', 'sortProperties')
});
Then in the template:
<span>{{product.sortedSources.firstObject.price}} €</span>
Works ok, without a ton of code.