dresende / node-orm2

Object Relational Mapping
http://github.com/dresende/node-orm2
MIT License
3.07k stars 376 forks source link

auto-fetch from child doesn't seem to work #477

Closed vendethiel closed 10 years ago

vendethiel commented 10 years ago

So, I'm trying to explain my problem.

I have 3 models :

forum {name}
topic {title, locked}
message {content}

and this node-orm code :

// :forum has_many :topics
models.topic.hasOne('forum', models.forum, {reverse: 'topics', required: true, +autoFetch: true})
// :topic has_many :messages
models.message.hasOne('topic', models.topic, {reverse: 'messages', required: true, autoFetch: true})

When I go to topic/13, I see the correct queries : queries

but the final JSON doesn't contains messages.

{
  "title": "swag",
  "locked": false,
  "id": 13,
  "forum_id": 2,
  "forum": {
    "name": "Sup bro",
    "id": 2
  }
}

Although the forum is queried correctly and pasting the messages query works in my mysql prompt.

Any idea what I'm doing wrong ?

bvallelunga commented 10 years ago

try changing auto-fetch to autoFetch

vendethiel commented 10 years ago

haha no, that's just because I'm using an altJS langs that dasherizes. auto-fetch isn't a valid unquoted key anyway.

dxg commented 10 years ago

It's because of the autoFetchLimit.

Try changing the autoFetchLimit:

Message.get(message.id, {autoFetchLimit: 2}, function (err, msg) {
  if (err) throw err;

  console.log(JSON.stringify(msg, null, 2));
});

You'll notice that it results in somewhat recursive looking datastructures if you push it much past 2. You can also set the limit globally.

vendethiel commented 10 years ago

I do get recursive structures with 3, but still not the messages

dxg commented 10 years ago

This works for me:

var orm = require("orm");
var async = require('async');

var dropSync = function (models, done) {
  if (!Array.isArray(models)) {
    models = [models];
  }
  async.eachSeries(models, function (item, cb) {
    item.drop(function (err) {
      if (err) throw err;

      item.sync(cb);
    });
  }, done);
};

orm.connect("postgres://user:pass@127.0.0.1/database", function (err, db) {
  if (err) throw err;

  var Forum = db.define("forum", {
    name : { type: 'text', size: 30 }
  });
  var Topic = db.define("topic", {
    name : { type: "text", size: 100 }
  });
  var Message = db.define("message", {
    text : { type: "text", size: 2000 }
  });

  Topic.hasOne(  'forum', Forum, {reverse: 'topics',   required: true, autoFetch: true})
  Message.hasOne('topic', Topic, {reverse: 'messages', required: true, autoFetch: true})

  dropSync([Forum, Topic, Message], function (err) {
    if (err) throw err;
    Forum.create({ name: "General" }, function (err, forum) {
      if (err) throw err;
      Topic.create({ name: "Cat videos", forum_id: forum.id }, function (err, topic) {
        if (err) throw err;
        Message.create({ text: ":D goo.gl/9IWFf", topic_id: topic.id }, function (err, message) {
          if (err) throw err;

          Topic.get(topic.id, {autoFetchLimit: 1}, function (err, topic) {
            if (err) throw err;

            console.log(JSON.stringify(topic, null, 2));

            db.close();
          });
        });
      });
    })
  });
});

Outputs:

{
  "name": "Cat videos",
  "id": 1,
  "forum_id": 1,
  "forum": {
    "name": "General",
    "id": 1
  },
  "messages": [
    {
      "text": ":D goo.gl/9IWFf",
      "id": 1,
      "topic_id": 1
    }
  ]
}

Can you tweak it and see if you can reproduce the behaviour you see?

vendethiel commented 10 years ago

will do, thanks.