geddy / model

Datastore-agnostic ORM in JavaScript
265 stars 55 forks source link

Complex query with Obj.Obj.key doesn't work #101

Open sbmaxx opened 11 years ago

sbmaxx commented 11 years ago

There is an error in query.js, _createComparison:

    if (keyName.indexOf('.') > -1) {
      keyNameArr = keyName.split('.');
      modelName = keyNameArr[1];
      keyName = keyNameArr[0];
    }

But should be

    if (keyName.indexOf('.') > -1) {
      keyNameArr = keyName.split('.');
      modelName = keyNameArr[0];
      keyName = keyNameArr[1];
    }

In the first case the result of parsing Obj.id will be modelName = 'id' and keyName = 'Obj'. That's wrong.

Also, why we're trying to find properties of model ?props = model.descriptionRegistry[modelName].properties

What if we're searching just for plain object without model, for example:

{  key: 'value', innerObj: { anotherKey: 'anotherValue' } }

But i don't want to make model for innerObj. Without model it will fail for now.

mde commented 11 years ago

Any way you can send a PR to fix this?

sbmaxx commented 11 years ago

Yes for the first issue. I'll prepare it tomorrow. And will think about second a bit more.

mde commented 11 years ago

Model does have a datatype of "object" that you can use for properties. Does that fix the second issue for you? I'm not sure exactly what problem you're describing.

sbmaxx commented 11 years ago

I have model with that datatype. For example:

var SampleModel = function () {
    this.defineProperties({
        key: {
            type: 'string',
            required: true
        },
        obj: {
            type: 'object'
        }
    });
}

So instances of this models looks like:

SampleModel.create({
    key: 'hello',
    obj: {
        anotherKey: 'world'
    }
});
SampleModel.create({
    key: 'hi',
    obj: {
        anotherKey: 'planet'
    }
})

And if i'll try to searh { 'obj.anotherKey': { ne: 'planet' } } the modelName == 'obj' and we're looking into model.descriptionRegistry for it. And we will fail, because we don't have model with name obj. It's just plain object.

Do you understand me?

mde commented 11 years ago

Ah, you're wanting to query on properties of that object? Right, that is not supported. It's fairly trivial to create a model and use associations, so that use-case (and the object datatype in general) has not been a high priority so far.

sbmaxx commented 11 years ago

I'll see at code ;) Maybe it can be done easily. At least mongo has built in support for it :)

Btw, can i ask why to use associations i have to call save method twice?

var user = User.create({
  login: 'asdf'
, password: 'zerb'
, confirmPassword: 'zerb'
});
user.save(function (err, data) {
  var profile;
  if (err) {
    throw err;
  }
  profile = Profile.create({});
  user.setProfile(profile);
  user.save();
});

Why not just:

var user = User.create({
  login: 'asdf'
, password: 'zerb'
, confirmPassword: 'zerb'
});
user.setProfile(Profile.create({}));
user.save();

?

It store internally like reference by id profileId or it's copying all profile object into user.profile?

mde commented 11 years ago

Yes, it creates a reference on the owned object by the id of the owner object. If the owner object hasn't been saved, it doesn't yet have an id.

lesterzone commented 10 years ago

My object looks like:

    //...
    contact: {
        type: 'object'
    }

@sbmaxx @mde So I'm able to query(MongoDB) with something like this?:

{ 'contact.socialNetwork1': { like: 'foobar' } }

Or What I'm doing wrong?

I'm using geddy v13.0.3

An the error:

Error: The association "contact" is not a valid property on the Service model.
mde commented 10 years ago

@lesterzone We still haven't implemented sub-object property filtering. Now that there is a JSON datatype available for Postgres, it's a much more compelling feature to implement for multiple adapters. I think this feature will be worked on for our next release.