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

No associations defined error #398

Closed
figalex opened this issue Nov 24, 2013 · 18 comments
Closed

No associations defined error #398

figalex opened this issue Nov 24, 2013 · 18 comments
Milestone

Comments

@figalex
Copy link

figalex commented Nov 24, 2013

I have a users model with hasMany('addresses', {description:String}, db.model.addresses) when I try to use user.setAddresses() or user.addAddresses()it throws an error saying "No associations defined".

I checked out the code line that threw the error (line 398, Many.js file) and it is an if statement checking if Associations.length === 0, but as it seems, Associations never gets an object pushed, it seems like it would always have length = 0.

What could I be doing wrong ?

@spacegangster
Copy link

I confirm the same error.
I investigated the calls for association.setAccessor with node debugger. It is called twice actually. Associations are present in the first call, I can see them in arguments. Then comes the second call with an empty array, no associations.
I have a tags model with has hasMany('notes', models.Note, {}, { reverse: 'tags' }), and I get the No associations defined error when I try to use note.setTags([ tag1, tag2], fn).

@Tape
Copy link
Contributor

Tape commented Nov 27, 2013

You both have the params in the wrong order, see the README on the repo

// Association name, Model, Extra params, Options
Patient.hasMany('doctors', Doctor, { why: String }, { reverse: 'patients' });

@spacegangster
Copy link

I've rechecked my code, and my parameters are specified as you quote them, I will correct my comment.
If you look into the source of associations/HasMany.js, there is no difference, actually. The only important thing, is that options should pass after properties.
Still has the error.

@ctaepper
Copy link

ctaepper commented Dec 1, 2013

simmelar approach, same error:

Events.hasMany('imageresources', Imageresource.model(), {}, {
    autoFetch: true
});

i create an event having no image associations defined, that works...
when i update the event:

    update: function (id, data, cb) {
        Events.get(id, function (err, obj) {
            if (err) return cb(err);
            console.log(obj, '-->', data);
            obj.save(data, cb);
        });
    }

the log looks like the following, obj.save throws error...

{ title: [Getter/Setter],
  seo: [Getter/Setter],
  text: [Getter/Setter],
  date_from: [Getter/Setter],
  date_till: [Getter/Setter],
  id: [Getter/Setter],
  imageresources: [] } '-->' { date_from: '2013-12-01 21:12',
  date_till: '2013-12-01 21:12',
  title: 'sadasd',
  text: 'asdAsdasd',
  seo: '17-sadasd' }

error trace:
Error: No associations defined
at Object.defineProperty.value (/Users/ct/Projekte/drv/node_modules/orm/lib/ErrorCodes.js:20:13)
at Object.defineProperty.value (/Users/ct/Projekte/drv/node_modules/orm/lib/Associations/Many.js:398:25)

@ctaepper
Copy link

any news on that? or do i have to search older versions of this until i find a working one?

@dxg
Copy link
Collaborator

dxg commented Jan 2, 2014

I was trying to recreate this bug, but haven't managed to so far.
On a side note, I cleaned up some code in hasMany setAccessor so that you can now pass in empty arrays (rather than manually calling the delAccessor).
It might have resolved the issue, but that would be a workaround, not a solution.

Below is my full test code.
Please amend it to make it crash or demonstrate the double saving behaviour. Once we have the test case cornered, we can fix it.

// node-orm2/test.js
var async = require('async');
var orm   = require('./lib/ORM');

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:[email protected]/database?debug=true', function (err, db) {
  if (err) throw err;

  var Address = db.define('address', { country : String, state: String });
  var User    = db.define('user',    { name    : String });

  User.hasMany('addresses', Address, {});

  var done = function () {
    console.log("done");
    db.close();
  }

  dropSync([Address, User], function (err) {
    if (err) throw err;

    var user = User.create({ name: "John" }, function (err, user) {
      if (err) throw err;

      var address = Address.create({ country: 'Atlantis' }, function (err, address) {
        if (err) throw err;

        address.state = 'NTT'

        address.save(function (err) {
          if (err) throw err;

          user.setAddresses(address, function (err) {
            if (err) throw err;

            user.name = "John Smith";
            user.save(function (err) {
              if (err) throw err;

              done();
            });
          });
        });
      });
    });
  });
});

@lstkz
Copy link

lstkz commented Jan 8, 2014

I had same error.

My model was

DomainAccount.hasMany 'roles', Role, {}, { autoFetch: true }
AccessReservation.hasMany 'invitees', DomainAccount, {}

it was crushing on

accessReservation.addInvitees(domainAccount, ...)

but only when domainAccount.roles was empty array
To fix that I had to remove roles property

if (domainAccount.roles && domainAccount.roles.length === 0) {
    delete domainAccount.roles
}
accessReservation.addInvitees(domainAccount, ...)

@jakate
Copy link

jakate commented Jan 10, 2014

I have the same problem.

var Person = db.define('personnel', {
    firstname  : String,
    lastname   : String,
    company_id : Number,
    createdAt  : String
});

Person.hasOne('company', db.models.companies, { required: true, reverse: 'personnel', autoFetch: true });
Person.hasMany('roles', db.models.roles, {}, {autoFetch: true});
Person.hasMany('groups', db.models.groups, {}, {autoFetch: true});

When I try to update the name, it fails because roles and groups have not been added yet. So when I delete those it allowes me to save.

req.models.personnel.get(req.params.id, function (err, person) {
  if(err) return res.send(400, err);

  person.firstname = req.body.firstname;
  person.lastname = req.body.lastname;

  if(!person.roles[0]) delete person.roles;
  if(!person.groups[0]) delete person.groups;
  if(!person.shifts[0]) delete person.shifts;

  person.save(function (err) {
    if(err) res.send(400, err);
    return res.send(200, 'ok');
  });
});

@dxg
Copy link
Collaborator

dxg commented Jan 13, 2014

I've got a failing test case.
It's fixed by the commit I mentioned earlier.
To test the fix, change your package.json to:

"orm": "git://github.com/dresende/node-orm2.git#bdf531aaff1481bbc47971752eba306c36827c26",

Something still isn't right though;
Upon calling save it tries to delete all associations if autoFetch didn't return any (because there are none).
I don't think this is expected behaviour. Once this is resolved, we should release a new version.

dxg added a commit that referenced this issue Jan 13, 2014
@gileze33
Copy link

This seems to get one step further, but as you mentioned, I'm having issues when it then tries to add an association:

item.setWorkers(worker_ids, function(err) {

Causes

TypeError: Object 1 has no method 'save'
     at saveAssociation (/Users/gileze33/Dropbox/mcapi/node_modules/orm/lib/Associations/Many.js:323:19)
     at Object.exports.wait (/Users/gileze33/Dropbox/mcapi/node_modules/orm/lib/Hook.js:26:10)
     at saveNextAssociation (/Users/gileze33/Dropbox/mcapi/node_modules/orm/lib/Associations/Many.js:364:12)
     at run (/Users/gileze33/Dropbox/mcapi/node_modules/orm/lib/Associations/Many.js:368:12)
     at Object.defineProperty.value (/Users/gileze33/Dropbox/mcapi/node_modules/orm/lib/Associations/Many.js:393:5)
     at Query._callback (/Users/gileze33/Dropbox/mcapi/node_modules/orm/lib/Associations/Many.js:242:39)
     at Query.Sequence.end (/Users/gileze33/Dropbox/mcapi/node_modules/mysql/lib/protocol/sequences/Sequence.js:75:24)
     at Query._handleFinalResultPacket (/Users/gileze33/Dropbox/mcapi/node_modules/mysql/lib/protocol/sequences/Query.js:143:8)
     at Query.OkPacket (/Users/gileze33/Dropbox/mcapi/node_modules/mysql/lib/protocol/sequences/Query.js:77:10)
     at Protocol._parsePacket (/Users/gileze33/Dropbox/mcapi/node_modules/mysql/lib/protocol/Protocol.js:192:24)

@gileze33
Copy link

Apologies- it obviously didn't like me passing an array of IDs as the first parameter. Setting it to an array of Models fixed that.

I can't seem to replicate the clearing of associations that weren't initially fetched FWIW

@dxg
Copy link
Collaborator

dxg commented Jan 16, 2014

You may be able to see it executing a DELETE FROM if you set debug=true in the database connection settings.
It's not really breaking anything, but just extra unnecessary DB calls.

It would be nice if it accepted an array of ids too..

@gileze33
Copy link

@dxg Wow - now I see what you mean.

If I create multiple items (booking in the below code), it's now deleting all relationships with the workers...

(orm/mysql) INSERT INTO booking ..........
(orm/mysql) DELETE FROM worker_bookings WHERE bookings_id = 421
(orm/mysql) DELETE FROM worker_bookings WHERE worker_id = 21
(orm/mysql) INSERT INTO worker_bookings (bookings_id, worker_id) VALUES (421, 21)

I can kind of get why it's doing the first DELETE, but by it doing the second one (bear in mind I'm creating the booking object, not the worker one at this point), it clears any previous associations.

@dxg dxg added this to the v2.1.4 milestone Feb 5, 2014
@dxg
Copy link
Collaborator

dxg commented Feb 24, 2014

We'll need to fix this for the next release. I'm not sure how yet, as auto saving associations is currently the default behaviour, but will need to think about it.

@bvallelunga
Copy link

Has there been any progress on this issue? I am having the same problems as many of the developers above.

@dxg
Copy link
Collaborator

dxg commented Mar 11, 2014

The underlying issue has been fixed on master, however the issue discussed with gileze33 above remains. I need to think of a good solution - and might need to make some breaking changes to achieve this - not sure yet.

@dxg
Copy link
Collaborator

dxg commented Mar 11, 2014

@gileze33 what sort of association do you have that it deletes twice? For me it only deletes once.
I tried with/without a reverse associtation and I can't replicate the SQL statements you have.

The single delete isn't really a problem - it's expected given the current behaviour of auto-saving associations. It can be redundant when associations are not changed though..

@dxg dxg closed this as completed in 3d1d026 Mar 12, 2014
@dxg
Copy link
Collaborator

dxg commented Mar 12, 2014

Issue should be completely resolved now - including the unnecessary deletes discussed above.
There are a few outstanding issues to fix, and then I plan to publish a new version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants