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

No validation error if invalid JSON string is passed and schema allows empty object (no presence validation) #43

Open
alexander-e1off opened this issue Sep 10, 2020 · 1 comment

Comments

@alexander-e1off
Copy link

Env: ruby 2.7.1, Rails 6.0.3.2
Modified given example as follows:
Schema (added empty object):

{
  "$schema": "http://json-schema.org/draft-04/schema",
  "oneOf": [
    { "$ref": "#/definitions/profile" },
    { "$ref": "#/definitions/empty" }
  ],
  "definitions": {
  "profile": {
    "type": "object",
    "properties": {
      "city": { "type": "string" },
      "country": { "type": "string" }
    },
    "required": ["country"]
  },
  "empty": {
    "type": "object",
    "properties": {},
    "additionalProperties": false
  }
}

Model (removed 'profile' presence validation):

create_table "users" do |t|
  t.string "name"
  t.json "profile" # First-class JSON with PostgreSQL, yo.
end

class User < ActiveRecord::Base
  # Constants
  PROFILE_JSON_SCHEMA = Rails.root.join('config', 'schemas', 'profile.json_schema').to_s

  # Validations
  validates :name, presence: true
  validates :profile, json: { schema: PROFILE_JSON_SCHEMA }
end

Expected result:

user = User.new(name: 'Samuel Garneau', profile: '{invalid JSON":}')
user.valid? # => false
user.profile_invalid_json # => '{invalid JSON":}'

Observed result:

user = User.new(name: 'Samuel Garneau', profile: '{invalid JSON":}')
user.valid? # => true
user.profile_invalid_json # => '{invalid JSON":}'

Since attribute setter got JSON parsing error, it replaces it with empty object {} which is passed then to validate_each, and if schema supports empty object, validation is passed and no error is added even if "#{attribute}_invalid_json" is not empty.

It seems it is needed to add in the beginning of validate_each method something like:

return record.errors.add(attribute, 'JSON parse error') if record.send(:"#{attribute}_invalid_json").present?
@remi
Copy link
Member

remi commented Jul 7, 2021

Hi Alexander,

Very sorry about the delayed response. Can you tell me if the issue is still present in 2.0+, now that the json_schemer gem is used?

And if so, would you mind sending a pull request with your proposed changes?

Thank you! ✌️

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

No branches or pull requests

2 participants