-
Notifications
You must be signed in to change notification settings - Fork 32
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
Error when updating content type with validations #49
Comments
Just for reference this is my janky workaround for the time being, pending this issue being resolved. Where def clean_validations(content_type)
return unless content_type.fields.kind_of? Array
content_type.fields.each do |field|
next unless field.validations.kind_of? Array
field.validations.each do |validation|
validation.validations = nil
end
end
end I have to run this on a content_type if I wish to update it after it has been retrieved. |
Could you post the code that you use to create the content type, field and validation? |
Sure let's see. Firstly, I'm using contentful-management (0.6.0). As far as the code goes, here is the actual code being executed that reproduces the bug: (The actual calls to the contentful management library are hidden behind helper methods) fields = [
new_asset_field(
id: 'featuredImage',
name: 'Featured Image',
validations: [
new_validation(link_mimetype_group: 'image')
]
),
]
product_content_type = contentful_space.content_types.create(
name: 'Product',
id: 'product',
fields: fields
)
product_content_type = contentful_space.content_types.find('product')
# Workaround for https://github.com/contentful/contentful-management.rb/issues/49
#clean_validations(product_content_type)
product_content_type.update(displayField: 'productName') Here is the debug level output when the code above is executed:
And here is the relevant implementation of those helper methods: def contentful_space
@contentful_space ||= begin
# Don't actually need the client, just need to intitialize it
management_client
::Contentful::Management::Space.find(Rails.configuration.contentful_space_id)
end
end
def new_asset_field(id:, name:, **kwargs)
kwargs[:type] = ::Contentful::Management::ContentType::LINK
kwargs[:link_type] = 'Asset'
new_field(id: id, name: name, **kwargs)
end
def new_field(id:, name:, type:, **kwargs)
field = ::Contentful::Management::Field.new
field.id = id
field.name = name
field.type = type
kwargs.each do |kwarg, value|
unless value.nil?
field.send("#{kwarg}=", value)
end
end
field
end
# Workaround for JSON error when coercing fields to JSON. Pending resolution
# of https://github.com/contentful/contentful-management.rb/issues/49
def clean_validations(contentful_obj)
if contentful_obj.respond_to?(:fields) && contentful_obj.fields.kind_of?(Array)
contentful_obj.fields.each do |field|
clean_validations(field)
end
elsif contentful_obj.respond_to?(:validations) && contentful_obj.validations.kind_of?(Array)
contentful_obj.validations.each do |validation|
validation.validations = nil
end
end
end
def management_client
::Contentful::Management::Client.shared_instance || ::Contentful::Management::Client.new(
Rails.application.secrets.contentful['management_api_oauth_access_token'],
:logger => Logger.new(STDOUT),
:log_level => Logger::DEBUG,
)
end I've commented out the I would also draw your attention to the last request output in the logs I posted. If you look into the :query key of the reqeust, you can see there is a Validation object that has not been converted into a hash getting passed directly to in the query. This is what the HTTP client seems to be choking on when making the request. Let me know if you have thoughts or suggestions on the above. Thanks! |
I did some more work related to this issue today, and one question that arose for me is why a It's quite possible that I'm unaware of functionality or contexts where a nested validation might actually be used, but this seems to be the core of the issue. I've found, for example, that as a workaround to the fix I posted above I can simply remove the validations property from the Validation class and thereafter I do not have this error on update requests. I hope this is helpful... |
Thank you for all the reports. I will take a look into them as soon as I am back from sick leave! |
I just tried to reproduce the issue with a bit of simpler code. Unfortunately I can not reproduce the error. require 'contentful/management'
client = Contentful::Management::Client.new(ENV['token'])
space = Contentful::Management::Space.find(ENV['space'])
validation = Contentful::Management::Validation.new
validation.link_mimetype_group = 'image'
title = Contentful::Management::Field.new
title.id = 'asset_title'
title.name = 'asset title'
title.type = 'Text'
field = Contentful::Management::Field.new
field.id = 'asset_field'
field.name = 'asset'
field.type = 'Link'
field.link_type = 'Asset'
field.validations = [validation]
space.content_types.create(name: 'ct-type', id: 'ct_type', fields: [title, field])
ct = space.content_types.find('ct_type')
ct.update(displayField: 'asset_title') # Here should be a breakage What version of the |
Thanks for looking into this! I ran your exactly code above and was pretty mystified to as to why this would not reproduce the error we saw. I ended up firing both my original code and this script in two separate debugging sessions side by side, and stepping deep within the request building process to figure out what was going wrong. I FINALLY got to the bottom of this -- and ironically it's literally the exact same root cause of a different bug that I reported in the main contentful gem here: contentful/contentful.rb#53 If you scroll up to the code I was using, specifically the helper method I have to create a client What's happening is that when the validations key is being converted to JSON, it hits that sub validation object, and looks for a In my example, @logger is the Rails logger, which throws an error when one tries to coerce it to JSON. Again, this is similar to what I experienced in the other gem. Your example doesn't have the Rails logger, so it runs cleanly. I imagine if you have a rails project lying around you could pretty easily reproduce the actual error by feeding your client a Rails logger. All this said, I'd definitely encourage you guys to consider the purpose of the ::Contentful::Management::Validation.class_eval do
# Remove unnecessary field
# Workaround for https://github.com/contentful/contentful-management.rb/issues/49
property_coercions[:validations] = nil
remove_method :validations
remove_method :validations=
end But you might want to consider whether it belong as I mentioned previously. |
Which version of rails are you using? I tried to reproduce it now with the logger from the stdlib and an old rails 3.2 that I had lying around and could not reproduce it either. |
Ok I was now able to reproduce this. |
I'm getting an IOError when attempting to update an existing content type that has fields with validation on it. The error is emanating from pretty deep within HTTP::Client, when the parameters are being coerced as json. It appears that during the process of converting properties to a hash, the :validations property of the Validation object has an extra Validation on it which is getting missed.
So let me see if I can explain. This is what
fields
looks like on an example content type I'm building at the create step:After the object is created, if I re-retrieve the content type and attempt to update it, this is what
fields
looks like:The biggest difference is the existence of the
:validations
property on theValidation
object itself, which gets left in place and cannot be coerced into json.It looks like some special handling needs to be added to account for this property, akin to the way those other properties are handled in the
parse_value
of theField
class.Let me know if the above makes sense or you have any questions. I'm going to attempt to work around this issue in the meantime.
The text was updated successfully, but these errors were encountered: