Skip to content

Create associate items #216

Closed
Closed

Description

@MrSwitch

With the autoFetch attribute, nested items are retrieved from associated tables.

Is it possible to have the same work for post, e.g if i were to post

  Person.create([{
     name:"John", 
     pets:[
        {name:"Fido"},
        {name:"Tigger"}
     ]
  }], function(){... respond when done...});

It would write items to the model which was associated with 'pets'

I found a work around using afterCreate hook e.g.

  afterCreate : function(){
      // Loop through and insert any children
      for(var x in this){
        if( this.hasOwnProperty(x) && this[x] instanceof Array && x in models){

          for(var i=0;i<this[x].length;i++){
            this[x][i]['owner_id'] = this.id;
          }

          models[x].create(this[x], function(err){
            if(err){
              console.log(err);
            }
            else{
              console.log("Added "+i +" pets");
            }
          });
        }
      }
 }

However i'd like it to be a little more abstract and have it know the reference to the child in question, e.g. not have to explicitily define it like i do with... this[x][i]['owner_id'] = this.id;

Also i'd only like it to trigger the callback if this has been completed successfully. But there is no "next" parameter passed to this particular hook.

Thanks in advance, great project.

Activity

  1. dresende commented on Jul 2, 2013

    @dresende
    Owner

    Does your Person.create work? Does it create the 2 pets and then the person before calling your callback?

  2. MrSwitch commented on Jul 2, 2013

    @MrSwitch
    Author

    No it doesn't. Thats why I've written the hook. Should it? I cant see it in
    the docs.
    On 2 Jul 2013 19:00, "Diogo Resende" notifications@github.com wrote:

    Does your Person.create work? Does it create the 2 pets and then the
    person before calling your callback?

    —
    Reply to this email directly or view it on GitHubhttps://github.com//issues/216#issuecomment-20334357
    .

  3. MrSwitch commented on Jul 2, 2013

    @MrSwitch
    Author

    ... also the two pets are created after the person because they reference
    the owner. Dont know if you meant to say that or not.
    On 2 Jul 2013 21:08, "Andrew Dodson" andrew.j.dodson@gmail.com wrote:

    No it doesn't. Thats why I've written the hook. Should it? I cant see it
    in the docs.
    On 2 Jul 2013 19:00, "Diogo Resende" notifications@github.com wrote:

    Does your Person.create work? Does it create the 2 pets and then the
    person before calling your callback?

    —
    Reply to this email directly or view it on GitHubhttps://github.com//issues/216#issuecomment-20334357
    .

  4. dresende commented on Jul 2, 2013

    @dresende
    Owner

    They might be created after the owner to be able to have the owner id set. But what I meant was if the callback is called after the owner is created or after everything is created?

  5. MrSwitch commented on Jul 2, 2013

    @MrSwitch
    Author

    The callback e.g. the one on Person.create ([...], callback) does not wait
    for the afterCreate hook.
    On 2 Jul 2013 23:14, "Diogo Resende" notifications@github.com wrote:

    They might be created after the owner to be able to have the owner id set.
    But what I meant was if the callback is called after the owner is created
    or after everything is created?

    —
    Reply to this email directly or view it on GitHubhttps://github.com//issues/216#issuecomment-20344652
    .

  6. dresende commented on Jul 2, 2013

    @dresende
    Owner

    Yes, after* hooks don't wait, they are triggered after the action. What I mean is if when the callback is called, the person and pets are already saved or it's just the person.

  7. MrSwitch commented on Jul 2, 2013

    @MrSwitch
    Author

    Its just the Person, with no pets. I'll add a new test case if this isn't the expected behavior.

  8. dresende commented on Jul 2, 2013

    @dresende
    Owner

    Can you try using the new operator?

    var John = new Person({
        name: "John",
        pets: [ /* ... */ ]
    });
    John.save(/* ... */);

    I think this works as expected. Maybe the only thing that is not is the different behaviour of Model.create.

  9. MrSwitch commented on Jul 3, 2013

    @MrSwitch
    Author

    Its not working for me. here's my test case. John is inserted into the 'person' table but his pet Fido is not inserted into the 'animal' table.

    console.log("TEST ASSOCIATE INSERT");
    
    
    var orm = require('orm');
    
    orm.connect("mysql://root:root@127.0.0.1/test?debug=true", function (err, db){
    
        console.log("CONNECTED TO DATABASE");
    
        ///////////////////////
        // CREATE THE PARENT
        ///////////////////////
    
        var Person = db.define('person', {
            name : String
        });
    
        ///////////////////////
        // CREATE THE CHILD
        ///////////////////////
    
        var Animal = db.define('animal', {
            name : String
        });
    
    
        ///////////////////////
        // LINK THEM UP
        ///////////////////////
    
        Animal.hasOne("owner", Person, {
            reverse: "pets"
        });
    
    
        ///////////////////////
        // Sync
        ///////////////////////
    
        db.sync(function(){
    
            console.log("SYNC'D DB `test`");
    
            ///////////////////////
            // Test insert
            ///////////////////////
    
            var John = new Person();
            John.name = "John";
    
            // Define associate
            John.pets = [
                {
                    name : "Fido"
                }
            ];
    
            John.save(function(err,obj){
                console.log(arguments);
            });
    
        });
    
    });
    
  10. dresende commented on Jul 3, 2013

    @dresende
    Owner

    Try changing { name: "Fido" } to new Animal({ name: "Fido" }).

  11. MrSwitch commented on Jul 3, 2013

    @MrSwitch
    Author

    Ah ok, so it can dish it* out but it can't take it* (*json).... pardon the joke.

    That's what i thought. Any chance this could be a future feature?

  12. dresende commented on Jul 3, 2013

    @dresende
    Owner

    Yes, I'll update this. I was just trying to understand if the problem was that or not.

  13. dresende commented on Jul 4, 2013

    @dresende
    Owner

    Please try and tell if it's working now with the latest commit.

  14. MrSwitch commented on Jul 4, 2013

    @MrSwitch
    Author

    I get these two inserts

     (orm/mysql) INSERT INTO `person` (`name`) VALUES ('John')
     (orm/mysql) INSERT INTO `animal` (`name`, `owner_id`) VALUES (NULL, 4)
    

    The second one is missing the name.

  15. dresende commented on Jul 4, 2013

    @dresende
    Owner

    I didn't realize you made a hasOne association on animal with reverse and saving it using person. I'm debugging right now.

  16. dresende commented on Jul 4, 2013

    @dresende
    Owner

    If you change your code to this, it works:

            // Define associate
            John.pets = {
                name : "Fido"
            };

    A reverse association of hasOne is creating another hasOne so you can't use an Array.

  17. dresende commented on Jul 4, 2013

    @dresende
    Owner

    What you want makes sense but the reverse option does not do what you want, the syntax is missleading. Perhaps I can make this possible, let me think about it.

  18. dresende commented on Jul 4, 2013

    @dresende
    Owner

    I think I got it, I'm posting a fix in a moment. Nevermind about my previous comment, it should behave as you're thinking about it.

  19. MrSwitch commented on Jul 5, 2013

    @MrSwitch
    Author

    Hey that's great

    (orm/mysql) INSERT INTO person (name) VALUES ('John')
    (orm/mysql) INSERT INTO animal (name, owner_id) VALUES ('Fido', 5)

    fyi: cloning on windows and running "npm install" breaks on sqlite, somehow 'npm update' works though. I'm not too familiar with npm.

    How long until these fixes are available in npm?

  20. dresende commented on Jul 5, 2013

    @dresende
    Owner

    sqlite3 has been a recurrent problem, it seems its support on latest node versions is not that great.
    I'll post a new version during next week.

  21. dresende commented on Jul 5, 2013

    @dresende
    Owner

    If you're using sqlite3 > 2.1.7, downgrade it to this version. Later ones have some problems on some obscure queries.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions