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

Support updateOnly feature #92

Merged
merged 5 commits into from
Aug 23, 2017
Merged

Support updateOnly feature #92

merged 5 commits into from
Aug 23, 2017

Conversation

rashmihunt
Copy link
Contributor

@rashmihunt rashmihunt commented Aug 5, 2017

This is part of solution forhttps://github.com/strongloop/loopback/issues/2924

Other PRs involved in the solution of issue strongloop/loopback#2924

@bajtos Please take a initial look.

This PR changes include

  • check for createOnlyInstance in schema-builder.js to use a new model for create only
  • defining and setting separate model for create operation based on updateOnly props - changes in model-helper.js
  • tests cases

Copy link
Member

@bajtos bajtos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the pull request! The changes looks mostly good, I would like you to clean the code a bit.

More importantly, please add a test (or more) to cover this new feature.


// check if ModelClass has getUpdateOnlyProperties() function defined to avoid version issues
if (lbdef.modelBuilder && lbdef.modelBuilder.defaultModelBaseClass &&
lbdef.modelBuilder.defaultModelBaseClass.getUpdateOnlyProperties) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is getting update-only properties from the default base model, which usually don't contain any, if my understanding is correct. I think you should be calling modelCtor.getUpdateOnlyProperties() instead. Thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm I added getUpdateOnlyProperties() at the end of last checkins and tested using local mocha test and above code does work in mocha test.. I re-tried it with end to end test creating app using lb app and using api -explorer and I do see that, I need to use modelCtor.getUpdateOnlyProperties() instead.

var updateOnlyProps =
lbdef.modelBuilder.defaultModelBaseClass.getUpdateOnlyProperties();
// if at least one updateOnly property is found, we need to create another model $new_xyz to be used only for
// create operation and this model will not have the updateOnly property included in the model. For e.g generated "id" field
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please wrap the lines at 80 chars

@@ -50,7 +65,7 @@ var modelHelper = module.exports = {
},
};

var definitionFunction = function(modelCtor, typeRegistry) {
var definitionFunction = function(modelCtor, typeRegistry, name, updateOnlyProps) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am proposing to add a single argument options to keep the number of arguments under control. This new argument can expect two properties for the starter - options.name and options.updateOnlyProps.

// if model has updateOnly properties, check if current property we are trying to add is updateOnly.
// If yes, skip adding to the model since this model is used for create operation where generated/update
// only property should not exist
if (updateOnlyProps) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the definition function should not need to know that the skipped properties are updateOnly. In the future, we may want to skip other kinds of properties, e.g. createOnly. Let's rename updateOnlyProps to a more generic excludeProps.

I also think this newly added block can be simplified a bit:

if (excludeProps && excludeProps.includes(key)) {
  return;
}

swaggerDef.properties[key] = schema;

@rashmihunt
Copy link
Contributor Author

@bajtos PTAL

  • Incorporated code review comments
  • Added new tests

Copy link
Member

@bajtos bajtos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks mostly good, let's clean up the code a bit more please.

// check if ModelClass has defined getUpdateOnlyProperties() function to
// avoid version issues
if (modelCtor.getUpdateOnlyProperties) {
var excludeProps = modelCtor.getUpdateOnlyProperties();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const excludeProps = ...

if (excludeProps && excludeProps.length > 0) {
const modelName = '$new_' + name;
typeRegistry.registerModel(modelName, function() {
var options = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. use const
  2. we don't quote property keys unless they contain characters like space or a dot
  3. In ES6+, a property name can be excluded when the value is set to a variable with the same name.
const options = {excludeProps};
return definitionFunction(modelCtor, typeRegistry, options);

// or even
return definitionFunction(modelCtor, typeRegistry, {excludeProps});

});
});

function createLoopbackAppWithModelWithForceId(forceId) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of copy-pasting most of createLoopbackAppWithModel, I think it will be better to add a parameter to createLoopbackAppWithModel.

This is how I envision the new usage:

// replacement for createLoopbackAppWithModel('/custom-api-root');
createLoopbackAppWithModel({apiRoot: '/custom-api-root'});

// in your new tests
createLoopbackAppWithModel({modelOptions.forceId: true});

@bajtos
Copy link
Member

bajtos commented Aug 16, 2017

Also please check why the CI builds are failing.

@rashmihunt
Copy link
Contributor Author

rashmihunt commented Aug 19, 2017

@bajtos PTAL.

CI will fail until upstream changes in juggler and loopback are merged. 3 failing tests require these changes since these tests check if there is a new model created or not for create operation.

@rashmihunt rashmihunt closed this Aug 19, 2017
@rashmihunt rashmihunt reopened this Aug 19, 2017
Copy link
Member

@bajtos bajtos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with two more suggestions. No further review is necessary, at least as far as I am concerned.

.to.include.members(['Product']);
});

it('should use $new_Product definition for post/create operation', function() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add "when forceId is in effect" and "when forceId is false" to the names of this and the next test. I found it confusing why we say "should use $new_Product" and then "should use Product" without explaining the difference in the tested scenario.

if (options === undefined || options.forceId === undefined) {
modelSettings = {description: ['a-description', 'line2']};
} else {
modelSettings = {description: ['a-description', 'line2'], forceId: options.forceId};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DRY

const modelSettings = {description: ['a-description', 'line2']};
if (options && options.forceId !== undefined) {
  modelSettings.forceId = options.forceId;
}

Copy link
Member

@bajtos bajtos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, I wanted to approve in my comment above.

@rashmihunt
Copy link
Contributor Author

@slnode test please

@rashmihunt rashmihunt merged commit ae196d6 into master Aug 23, 2017
@rashmihunt rashmihunt deleted the updateonly_feature branch August 23, 2017 04:49
rashmihunt added a commit that referenced this pull request Aug 23, 2017
 * Support updateOnly feature (#92) (Rashmi Hunt)
 * Add stalebot configuration (Kevin Delisle)
 * Update Issue and PR Templates (#95) (Sakib Hasan)
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

Successfully merging this pull request may close these issues.

2 participants