FiguredLimited / vue-mc

Models and Collections for Vue
https://vuemc.io
MIT License
626 stars 98 forks source link

Error: Not allowed to overwrite model identifier #167

Closed hdrodel closed 3 years ago

hdrodel commented 3 years ago

Hello I'm having a weird problem. I need to be able to have a collection of models that also have model collections. I try to break it down as simple as possible: The model is Pizza My ingredient

export class Ingredient extends Model{
defaults(){
    return{
        uid: null,
        name: "",
    }
}
}

Then a list of ingredients

 export class IngredientList extends Collection {
    model(){
        return Ingredient;
    }
}
export class Pizza extends Model{
defaults(){
    return{
        uid: null,
        name: "",
        ingredients:[]
    };
}
mutations(){
    return {
        ingredients:(ingredients)=>new IngredientsList(ingredients);
    }
}
}

Then my list of all Pizzas

 export class PizzaList extends Collection {
    model(){
        return Pizza;
    }
}

So far everything seems to work. The PizzaList is fetched and has an Ingredientslist. I can open a dialog and pass a PizaItem and edit and save things. But when i try to edit an Ingredient like so: Template:

<!- a list of  pizza ingredients for the active pizza-->
<v-data-table
:items="pizza.ingredients.models"
:headers="[
{
text: 'Name',
value: 'name'
},
{
text:'Actions', 
value:'actions'
}
>
<template v-slot:[`item.actions`]="{item}">
<v-icon
    small
    @click="editIngredient(item)">
mdi-pencil
</v-icon>
</template>
<!-- at another point in the template the input fields for editing ingredient -->
<tr>
    <td>
        <v-text-field
            v-model="editIngredient.name"
         ></v-text-field>
    </td>
</tr>
<tr>
    <td>
        <v-btn @click="saveIngredient()"><v-icon>mdi-content-save</v-icon></v-btn>
    </td>
</tr>
...

and in the script i have:

data:()=>({
editIngredient: null;
}),
methods:{
editIngredient(item){
this.editIngredient=item;
}
async saveIngredient(){
try{
await this.editIngredient.save()
}catch(err){
console.log(err)
}
}
}

So when i call saveIngredient the correct endpoint gets called and correctly a put request is made for updating the ingredients as specified in my methods. the request has the right body content but i get this error message

Error: Not allowed to overwrite model identifier at OutputTarget.update (vue-mc.es.js?a46f:11028) at OutputTarget.onSaveSuccess (vue-mc.es.js?a46f:11123) at eval (vue-mc.es.js?a46f:5767)

I also have tried not having the ingredients collection as model attribute of the pizza but instead only have an array of ingredients and then when saving:

saveIngredient(ingredient){
let toSave=new Ingredient(ingredient);
try{
await toSave.save()
}catch(err){
console.log(err)
}
}

But it seems like it gave me the same error message

I tried to allow overwriting the identifier like mentioned in the documentation but then the endpoint for creating a model and not for updating the model is being called

does anyone know where this error occurs? where is the identifier overwritten?

eduardobc88 commented 3 years ago

Hi! you should set default identifier in your model, some like this:

options () {
   return {
      identifier: '_id',
      overwriteIdentifier: true,
   }
}

and check the documentation options description: Screen Shot 2021-02-02 at 10 41 28

I hope I had help you. :)

hdrodel commented 3 years ago

Thank you @eduardobc88 I thought I tried that solution before but somehow this time it worked!