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

Allow setting optional fields on input objects to explicit null #28

Merged
merged 7 commits into from
Aug 8, 2017

Conversation

wesleyjellis
Copy link
Contributor

This change allows you to manually set an optional field to null on an input object.

Change is needed to so that we can delete an a child object in an update mutation. Specifically, CollectionInput needs to support setting CollectionImage to null so that it gets deleted.

Closes #27

@eapache
Copy link
Contributor

eapache commented Aug 2, 2017

Seems straightforward enough, but there's room to make it nicer:

  • only need to do this work if the field is optional
  • we can annotate the arguments to the set methods with appropriate Nullable/NonNull (using the custom_annotations argument since not all javas have the same set of those)

@@ -266,6 +267,7 @@ public class <%= schema_name %> {
<% type.optional_input_fields.each do |field| %>
private <%= java_input_type(field.type) %> <%= escape_reserved_word(field.camelize_name) %>;
<% end %>
private HashSet<String> fieldsSeen = new HashSet<>();
Copy link
Contributor

Choose a reason for hiding this comment

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

This is kind of a weird mix of using generated instance variables and a HashSet. If we are going to generate instance variables, then we should also generate a boolean to indicate that the field has been set. If we wanted a sparse object instead, it would make more sense to just use a HashMap, which could use the key's presence to indicate whether or not the field has been set.

@wesleyjellis
Copy link
Contributor Author

  • only need to do this work if the field is optional

Already done, I add the extra code only for optional_fields

@@ -265,6 +265,7 @@ public class <%= schema_name %> {
<% end %>
<% type.optional_input_fields.each do |field| %>
private <%= java_input_type(field.type) %> <%= escape_reserved_word(field.camelize_name) %>;
private boolean <%= escape_reserved_word(field.name) %>Seen = false;
Copy link
Contributor

Choose a reason for hiding this comment

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

No java reserved words end in Seen, so you don't need escape_reserved_word.

Also, I think you should use field.camelize_name to follow the java naming convention if the schema uses underscore separated words. E.g. if the field in the schema is two_words then the variable would be two_wordsSeen.

public <%= java_input_type(field.type) %> get<%= field.classify_name %>() {
return <%= escape_reserved_word(field.camelize_name) %>;
}

public <%= type.name %> set<%= field.classify_name %>(<%= java_input_type(field.type) %> <%= escape_reserved_word(field.camelize_name) %>) {
public <%= type.name %> set<%= field.classify_name %>(<%= java_annotations(field).gsub(/(.)$/, '\1 ') %><%= java_input_type(field.type) %> <%= escape_reserved_word(field.camelize_name) %>) {
Copy link
Contributor

Choose a reason for hiding this comment

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

The .gsub(/(.)$/, '\1 ') replacement is really weird, since it just adds a trailing whitespace at the end of each line in the string.

irb(main)> "one\ntwo\n".gsub(/(.)$/, '\1 ')
=> "one \ntwo \n"

but it looks like what you actually want is to replace the newlines. You could use .tr("\n", " ") instead to do that.

However, why not just add a keyword argument tojava_annotations to control the separator so you don't need to workaround its limitation with string replacements.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I think the correct solution is to let java_annotations format differently for arguments vs methods or fields. I'm gonna add some tests for java_annotations while I'm at it

end.compact.join("\n")
end.compact
if in_argument
annotations.join(" ") + " "
Copy link
Contributor

Choose a reason for hiding this comment

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

this is generating an extra space when there are no annotations

Copy link
Contributor

Choose a reason for hiding this comment

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

The change I was thinking of was to just change

-    end.compact.join("\n")
+    end.compact.join(separator)

where separator is an argument passed into java_annotations. However, it might be even simpler to just have this method return an array and do the .join("\n") or .join(' ') on the return value in the template.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There's still the problem that we need a trailing space at the end of annotations in argument that I feel would make the templates uglier to deal with it there. I'll just add an early return if there are no annotations

this.<%= escape_reserved_word(field.camelize_name) %> = <%= escape_reserved_word(field.camelize_name) %>;
this.<%= escape_reserved_word(field.name) %>Seen = true;
Copy link
Contributor

Choose a reason for hiding this comment

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

This needs to use field.camelize_name without escape_reserved_word for consistency with the instance variable name.

@@ -306,11 +310,15 @@ public class <%= schema_name %> {
<%= generate_build_input_code(escape_reserved_word(field.camelize_name), field.type) %>
<% end %>
<% type.optional_input_fields.each do |field| %>
if (<%= escape_reserved_word(field.camelize_name) %> != null) {
if (this.<%= escape_reserved_word(field.name) %>Seen) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Again, use field.camelize_name without escape_reserved_word to avoid errors if this does get escaped

@wesleyjellis wesleyjellis merged commit 1f84b1c into master Aug 8, 2017
@wesleyjellis wesleyjellis deleted the add_optional_null_to_input branch August 8, 2017 19:54
@BenEmdon BenEmdon mentioned this pull request Sep 6, 2017
3 tasks
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.

3 participants