This issue duplicates another issue.
  1. #1
    Sencha User tradingpursuits's Avatar
    Join Date
    Sep 2011
    Posts
    6
    Vote Rating
    0
    tradingpursuits is on a distinguished road

      0  

    Exclamation Sync new record in association store duplicate the newly created record.

    Sync new record in association store duplicate the newly created record.


    REQUIRED INFORMATION

    Ext version tested:
    • Sencha Touch 2.2.1
    Browser versions tested against:
    • Chrome 28.0.1500.52 Ubuntu 12.04
    DOCTYPE tested against:
    • html
    Description:
    • Sync new record in association store duplicate the newly created record.
    Steps to reproduce the problem:
    • Add new record to a model association
    • Sync the association store.
    The result that was expected:
    • 1 copy of the newly created record in the association store.
    The result that occurs instead:
    • 2 copies of the new record in the association store.
    Test Case:

    File index.html
    Code:
    <!DOCTYPE html>
    <html>
    <head>
        <script type="text/javascript" src="lib/sencha-touch-all-debug.js"></script>
    </head>
    <body>
    <script type="text/javascript">
        Ext.define("Test.TestBundle.Entity.Car", {
            extend: "Ext.data.Model",
            uses: [
                'Test.TestBundle.Entity.CarOwner'
            ],
            config: {
                idProperty: "id",
                fields: [
                    {
                        name: "id",
                        type: "int",
                        useNull: true,
                        persist: false
                    },
                    {
                        name: "name",
                        type: "string"
                    },
                    {
                        name: "plateNumber",
                        type: "string"
                    },
                    {
                        name: "password",
                        type: "string"
                    },
                    {
                        name: "car_owner_id",
                        type: "int",
                        useNull: true
                    }
                ],
                validations: [
                    {
                        type: "presence",
                        field: "name"
                    },
                    {
                        type: "presence",
                        field: "plateNumber"
                    },
                    {
                        type: "presence",
                        field: "password"
                    }
                ],
                associations: [
                    {
                        type: 'belongsTo',
                        model: 'Test.TestBundle.Entity.CarOwner',
                        getterName: 'getCarOwner',
                        setterName: 'setCarOwner',
                        foreignKey: 'car_owner_id'
                    }
                ],
                proxy: {"type":"rest","url":"\/mycars","format":"json","writer":{"type":"json"}}    }
        });
        Ext.define("Test.TestBundle.Entity.CarOwner", {
            extend: "Ext.data.Model",
            uses: [
                'Test.TestBundle.Entity.Car'
            ],
            config: {
                idProperty: "id",
                fields: [
                    {
                        name: "id",
                        type: "int",
                        useNull: true,
                        persist: false
                    },
                    {
                        name: "name",
                        type: "string"
                    }
                ],
                validations: [
                    {
                        type: "presence",
                        field: "name"
                    }
                ],
                associations: [
                    {
                        type: 'hasMany',
                        model: 'Test.TestBundle.Entity.Car',
                        name: 'cars',
                        foreignKey: 'car_owner_id'
                    }
                ],
                proxy: {"type":"rest","url":"\/mycarowners","format":"json","writer":{"type":"json"}}    }
        });
        var owner = Ext.create('Test.TestBundle.Entity.CarOwner', {name: 'Ed'});
        owner.save({
            callback: function() {
                var cars = owner.cars();
                cars.add({
                    name: 'Ford',
                    plateNumber: 'AA1234',
                    password: 'xx'
                });
                cars.sync();
                console.log(cars);
            }
        });
    </script>
    </body>
    </html>
    Resource return from /mycarowners.json
    Code:
    {"id":83,"name":"Ed"}
    Resource return from /mycar.json
    Code:
    {"id":123,"name":"Ford","plateNumber":"AA1234","carOwner":{"id":83,"name":"Ed","cars":[]}}
    HELPFUL INFORMATION

    This problem does not happen on Ext JS 4.2.1.

    Debugging already done:
    • Function afterCommit in Ext.data.Store, call replace on the _data of Ext.util.Collection
    • The replace function, successfully add the new record and remove the old record, but then it check for filter status on the store and reinsert the old record. That is why there is 2 record in the store.
    Operating System:
    • Ubuntu 12.04

  2. #2
    Sencha - Senior Software Engineer mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    38,042
    Vote Rating
    992
    mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute

      0  
    Mitchell Simoens @SenchaMitch
    Sencha Inc, Senior Software Engineer
    ________________
    Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
    https://github.com/mitchellsimoens

    Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/

    Need more help with your app? Hire Sencha Services services@sencha.com

    Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is in print!

    When posting code, please use BBCode's CODE tags.

  3. #3
    Sencha User tradingpursuits's Avatar
    Join Date
    Sep 2011
    Posts
    6
    Vote Rating
    0
    tradingpursuits is on a distinguished road

      0  

    Default


    Are you sure it is a duplicate?

    TOUCH-3969
    is about unable to save record. This bug is about SAVING an associated record SUCCESSFUL in the backend but it is DUPLICATED in the store.

  4. #4
    Sencha User
    Join Date
    Aug 2013
    Posts
    1
    Vote Rating
    0
    dimdar74 is on a distinguished road

      0  

    Default


    The problem is also present on the store that contains the master record if this is new and the store has already been synchronized when you call the load method of the hasMany store.
    example:

    Code:
    Ext.define('MyApp.model.Test', {
        extend: 'Ext.data.Model',
        uses: [
            'MyApp.model.Frutto'
        ], 
        config: {
            fields: [
                {
                    name: 'id',
                    type: 'int'
                },
                {
                    name: 'Testo',
                    type: 'string'
                },
                {
                    name: 'Valore',
                    type: 'int'
                }
            ], 
            hasMany: {
                associationKey: 'Frutti',
                model: 'MyApp.model.Frutto',
                foreignKey: 'idTest',
                name: 'Frutti',
                store: {
                    proxy: {
                        type: 'rest',
                        url: 'http://localhost:8090/api/Frutti'
                    }
                }
            }
        }
    });
    
    Ext.define('MyApp.model.Frutto', {
        extend: 'Ext.data.Model',
        config: {
            fields: [
                {
                    name: 'id',
                    type: 'int'
                },
                {
                    name: 'idTest',
                    type: 'int'
                },
                {
                    name: 'Descrizione',
                    type: 'string'
                }
            ]
        }
    });
    
    Ext.define('MyApp.store.TestStore', {
        extend: 'Ext.data.Store',
        requires: [
            'MyApp.model.Test'
        ],
        config: {
            model: 'MyApp.model.Test',
            storeId: 'teststore',
            proxy: {
                type: 'rest',
                url: 'http://localhost:8090/api/Test'
            }
        }
    });
    
    AddMaster: function() {
        var store = Ext.data.StoreManager.lookup('teststore');
        var c = Ext.create('MyApp.model.Test', {
            id: undefined,
            Testo : "due",
            Valore : 2
        }); 
        
        store.add(c);
        store.sync();
        this.setMasterRecord(c);
    },
            
    LoadDetail: function() {
        var c = this.getMasterRecord();
        this.getListFrutti().setStore(c.Frutti());
        c.Frutti().setAutoLoad(true);
    },
            
    AddDetail: function() {
        var c = this.getMasterRecord();
        var frutto = Ext.create('MyApp.model.Frutto', { 
            id : undefined, 
            Descrizione : "Lime"
        });
        c.Frutti().add(frutto);
        c.Frutti().sync();
    }
    First call AddMaster: listMaster was updated with new record;
    Second call LoadDetail: listMaster was updated with another row of the same record and listFrutti was populated with records received from server;
    Third call AddDetail: listFrutti was updated with two rows of the same record;

  5. #5
    Sencha User
    Join Date
    Jul 2014
    Posts
    4
    Vote Rating
    0
    tedwardsknowlysis is on a distinguished road

      0  

    Default


    I just came across this same bug. The issue lies in ../src/util/Collection.js, specifically the replace function.I run into this issue when I add a newly created record to a store and then save it. The save updates the id field to the id that is created by our DB (MongoDB). After the replace function runs, the store that the record was originally now has two records with the same IDs assigned to both records (as returned by the DB call).