Skip to content

Unable to define properties without persistence #92

Open
mhuggins opened this Issue Jun 10, 2012 · 12 comments

5 participants

@mhuggins

I'm trying to use JugglingDB, but there doesn't appear to be a way to include properties in my model that are NOT persisted into the database.

My specific use case involves a User model with an encrypted_password property, which is persisted when the user is saved. However, the encrypted_password is never provided by the interacting user, and is intended to be generated from another property named password (as well as password_confirmation). Ideally, I'd like to:

  1. validate that password == password_confirmation
  2. generate encrypted_password in the beforeValidation callback handler

In other words:

var User = schema.define("users", {
    email                 : { type: String, length: 254 },
    username              : { type: String, length: 20 },
    encrypted_password    : { type: String, length: 40 },
    salt                  : { type: String, length: 16 },
    created_at            : { type: Date, default: Date.now },
    updated_at            : { type: Date, default: Date.now }
});

User.beforeValidation = function (next) {
    this._generateSalt();     // assigns a value to this.salt
    this._encryptPassword();  // assigns a value to this.encrypted_password
    next();
};

User.validate('password_confirmation', function (err) {
    if (this.password != this.password_confirmation) {
        this.errors.add('password_confirmation', 'must match password');
        err();
    }
});

I'm currently providing a form (via Express) that allows the user to fill out password and password_confirmation when registering. The problem is that calling User.create(params) does not assign these two properties since they're not defined in my users schema.

@1602
Owner
1602 commented Jun 13, 2012
@mhuggins

That is good to know, thanks for the extra info. Good insight into how some of jugglingdb works. :)

Unfortunately, it looks like the example you provide doesn't demonstrate a good way of requiring a password confirmation input value (where the user is required to repeat their password a second time during registration).

Ideally, this logic should not be included elsewhere (such as a controller), as it would be needed to be repeated if I wanted multiple registration points in my app. I would expect it should be something that can occur within the model since it should always be required logic for creating a user. But the call to User.create() doesn't accept/set values on the object unless they are defined as properties via property(). But calling property() means that jugglingdb will attempt to save that column value, meaning that is not a viable option.

Any thoughts? Thanks again!

@mhuggins

The more I test this, the more it seems like it's becoming a new feature request. My suggestion would be that when creating a new setter (without calling the property() method) should allow _initProperties() of AbstractClass to assign all setters, regardless of whether or not they're defined in the schema.

This could even be a new option when creating a property such that it would be defined as a virtual property:

define('User', function() {
  property('password', String, { virtual: true });
  // virtual('password', String);        # alternate format
});

I would be happy to work on such a feature, but I want to: 1) make sure I'm not missing something that is already doable in jugglingdb, and 2) make sure it's something that sounds like it makes sense to have in jugglingdb.

@1602 1602 closed this Jan 22, 2013
@bioform
bioform commented Apr 13, 2013

It seems to me that this issue should be reopened since last version of jugglingdb checks type of variable which is assigned to model field. So virtual field should be declared in a scheme.

@bioform
bioform commented Apr 13, 2013

Each time when we need validate "password" field we should make "crutches" instead of simple "property('password', String, { virtual: true });"

@anatoliychakkaev
Collaborator
@bioform
@1602
Owner
1602 commented Apr 15, 2013

It's not magic. It's just how setter works.

@1602 1602 reopened this Apr 15, 2013
@zxqfox
zxqfox commented Jul 5, 2014

@1602 reopened?

@anatoliychakkaev
Collaborator
@zxqfox
zxqfox commented Jul 5, 2014

Is there something to work on?

@zxqfox
zxqfox commented Jul 5, 2014

alternate format:
property('password', String, { dataType: 'virtual' }); ?

But I'm confused a little. dataType used for low-level schema configuration. Is this right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.