Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create associate items #216

Closed
MrSwitch opened this issue Jul 2, 2013 · 21 comments
Closed

Create associate items #216

MrSwitch opened this issue Jul 2, 2013 · 21 comments

Comments

@MrSwitch
Copy link

MrSwitch commented Jul 2, 2013

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.

@dresende
Copy link
Owner

dresende commented Jul 2, 2013

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

@MrSwitch
Copy link
Author

MrSwitch commented Jul 2, 2013

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" [email protected] 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
.

@MrSwitch
Copy link
Author

MrSwitch commented Jul 2, 2013

... 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" [email protected] 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" [email protected] 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
.

@dresende
Copy link
Owner

dresende commented Jul 2, 2013

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?

@MrSwitch
Copy link
Author

MrSwitch commented Jul 2, 2013

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" [email protected] 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
.

@dresende
Copy link
Owner

dresende commented Jul 2, 2013

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.

@MrSwitch
Copy link
Author

MrSwitch commented Jul 2, 2013

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

@dresende
Copy link
Owner

dresende commented Jul 2, 2013

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.

@MrSwitch
Copy link
Author

MrSwitch commented Jul 3, 2013

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:[email protected]/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);
        });

    });

});

@dresende
Copy link
Owner

dresende commented Jul 3, 2013

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

@MrSwitch
Copy link
Author

MrSwitch commented Jul 3, 2013

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?

@dresende
Copy link
Owner

dresende commented Jul 3, 2013

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

dresende added a commit that referenced this issue Jul 4, 2013
…ciations (#216)

Adds initial tests for Model.create(), deprecates old one
@dresende
Copy link
Owner

dresende commented Jul 4, 2013

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

@MrSwitch
Copy link
Author

MrSwitch commented Jul 4, 2013

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.

@dresende
Copy link
Owner

dresende commented Jul 4, 2013

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

@dresende
Copy link
Owner

dresende commented Jul 4, 2013

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.

@dresende
Copy link
Owner

dresende commented Jul 4, 2013

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.

@dresende
Copy link
Owner

dresende commented Jul 4, 2013

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.

@MrSwitch
Copy link
Author

MrSwitch commented Jul 5, 2013

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?

@dresende
Copy link
Owner

dresende commented Jul 5, 2013

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.

@dresende dresende closed this as completed Jul 5, 2013
@dresende
Copy link
Owner

dresende commented Jul 5, 2013

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
Projects
None yet
Development

No branches or pull requests

2 participants