Consider the following 2 models: car and owner
I have a car record with the current owner (bob jones) and I have a owner record (bob jones) with details... address, phone etc.
In my car form (car model), I have this:
export default Model.extend({
"owner_id": DS.belongsTo('owner'),
"year": attr(''),
"model": attr(''),
"make": attr('')
})
Stored on the DB end, is the ID '12345', corresponding to the Bob Jones owner record.
When I load up the car record (2015 Jaguar), it will also connect to the Bob Jones record which tells me his phone, address etc. For example, if I print out
{{owner_id.id}} - {{owner_id.name}}
I will show:
12345 - Bob Jones
My question is, what happens if I change owners of the car. If I select the dropdown list
{{my-select
name="owner_id"
content=ownerList
selection=owner_id.id
prompt="select an owner"
required=true
}}
From this component:
import Ember from 'ember';
export default Ember.Component.extend({
content: [],
prompt: null,
optionValuePath: 'value',
optionLabelPath: 'label',
init: function () {
this._super(...arguments);
if (!this.get('content')) {
this.set('content', []);
}
},
actions: {
change: function () {
let selectedIndex = this.$('select')[0].selectedIndex;
let content = this.get('content');
// decrement index by 1 if we have a prompt
let hasPrompt = !!this.get('prompt');
let contentIndex = hasPrompt ? selectedIndex - 1 : selectedIndex;
let _selection = content[contentIndex];
this.sendAction('willChangeAction', _selection);
if (this.get('optionValuePath')) {
this.set('selection', _selection[this.get('optionValuePath')]);
} else {
this.set('selection', _selection);
}
this.sendAction('didChangeAction', _selection);
}
}
});
and change the value... I get this error:
A record's id cannot be changed once it is in the loaded state
How do you go about updating the 2015 Jaguar car record to change the owner, and load in the details of the new owner?
You're changing the id of the owner instead of changing the owner_id
prop on the jaguar. I changed the owner_id
prop to owner
to help clarify what the belongsTo holds.
The general strategy I'm taking is to select the owner of the car, then pass that back up to the controller to save the car.
models/car.js
export default Model.extend({
"owner": DS.belongsTo('owner'),
// ...
})
routes/cars/car.js
import Ember from 'ember';
export default Ember.Route.extend({
model(params) {
return Ember.RSVP.hash({
car: this.store.find('car', params.id),
ownerList: // however you get the owner list
})
}
})
controllers/cars/car.js
import Ember from 'ember';
export default Ember.Controller.extend({
actions{
ownerChanged(newOwner) {
// If the select is setup properly, newOwner should be an instance of owner.
const car = this.get('model.car');
car.set('owner', newOwner);
car.save
}
}
})
templates/cars/car.hbs.
{{my-select
name="owner"
content=model.ownerList
selection=model.car.owner.id
prompt="select an owner"
required=true
didChangeAction='ownerChanged'
}}
The code in the route's model hook is mostly there for clarity, if you're taking a different approach, adjust the names accordingly