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

Add option to ignore property if instance is nil. #76

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

pivotal-casebook
Copy link

This is helpful when the property is a nested one and the associated representer expects a real instance, not a fragment.

We have a scenario where we use the 'instance' option with a Proc that might return nil based on the original data being deserialized. In this case, we would like Representable to ignore the property, and not pass down the fragment to the associated representer.

property :foo, extend: FooRepresenter, instance: lambda { |*| nil }, ignore_nil_instance: true

With that property, we don't want FooRepresenter to call its setters with a fragment (we use XML and receive a Nokogiri::Node). The instance Proc already reviewed the fragment and decided that nothing had to be done.

We are happy to hear thoughts or suggestions.

Cheers!

This is helpful when the property is a nested one
and the associated representer expects a real 
instance, not a fragment.
@apotonick
Copy link
Member

I was thinking about that and had the idea that nil for class: and instance: could instruct representable to ignore this property while the new parse_strategy could take care of the former scenario where you don't want representable to create an object but use the object from the getter. This way, we could save us from creating another option?!

@pivotal-casebook
Copy link
Author

Thanks for the quick feedback. That sounds fine to us -- by introducing the new option we just tried to make the feature be backwards compatible, as we were not sure how people were using the fragment when there was no class or instance. Are you suggesting that Binding#create_object returns nil instead of the fragment and ObjectDeserializer#call returns nil when the object is nil? That would work for us.

We are not quite sure what you mean by the new parse_strategy. We don't really use this feature yet, so not sure if we can help much.

Thanks,

Jacobo & Chris

@apotonick
Copy link
Member

Have you tried using :if to decide whether or not to serialize?

@apotonick
Copy link
Member

Please, give me an example what you guys do in instance: to find out whether or not to proceed.

I have an idea for an upcoming feature in representable. Since we're pretty close in 1.8 to have a well-defined workflow for parsing and rendering, we could introduce a Flow object that can be instructed to stop the flow at a certain point.

Here's an example, I just came up with this 15 minutes ago.

instance: lambda { |fragment, args|
  # find out what to do
  args.flow.skip!(:serialize)
}

That'll make it way more intuitive to control the flow. I see about 10 potential steps involved that could be managed with Flow.

@pivotal-casebook
Copy link
Author

Hello!

To your first question: we cannot use if: because it occurs before the instance: evaluation. We basically want to only abort that property when the evaluation of our instance Proc returns nil.

Which leads to the second question. In our XML we have a couple of fields that describe the subject that should be hydrated. One is an 'action' field, that will say something like 'add', 'update' or 'delete', and the other is an 'id' field, a regular database ID representing the record to be updated/deleted (does not apply to add)).

instance: then needs to read those properties (unfortunately here we need to deal with the Nokogiri::Node objects, we haven't come up with anything nicer) and then create the right instance, either by using .new or by retrieving it from the database. The case for nil is when the 'action' flag says 'none', which means that the record should not be modified and we would not want to call the parsing methods.

XML Examples:

<action>add</action> 
# we want instance to just create a new object of a specific class

<action>update</action>
<id>3</action>
# we want instance: to use ID3 to find a record in the database and instantiate an object for that data

<action>none</action>
<id>3</id>
# we want to leave the parsing flow

Today we actually thought about this and felt that maybe we could achieve the same goal if if: happened after the instantiation, but we have no idea what side effects that could have.

I hope that was clear. Please let me know what your thoughts are! And thanks for your help.

Cheers,

Jacobo

@apotonick
Copy link
Member

How do you access the action field at the moment? Is th e fragment sufficient or do you need the entire document? The new pass_options option allows that, we could add access to the entire document here.

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