I'm building a simple app and want to be able to store json strings in a db. I have a table Interface with a column json, and I want my rails model to validate the value of the string. So something like:
class Interface < ActiveRecord::Base attr_accessible :name, :json validates :name, :presence => true, :length => { :minimum => 3, :maximum => 40 }, :uniqueness => true validates :json, :presence => true, :type => json #SOMETHING LIKE THIS :contains => json #OR THIS end
How do I do that?
To check if a string is JSON in JavaScript, we can use the JSON. parse method within a try-catch block. to check if jsonStr is a valid JSON string. Since we created the JSON string by calling JSON.
The best way to find and correct errors while simultaneously saving time is to use an online tool such as JSONLint. JSONLint will check the validity of your JSON code, detect and point out line numbers of the code containing errors.
jq – a lightweight and flexible CLI processor – can be used as a standalone tool to parse and validate JSON data.
I suppose you could parse the field in question and see if it throws an error. Here's a simplified example (you might want to drop the double bang for something a bit clearer):
require 'json' class String def is_json? begin !!JSON.parse(self) rescue false end end end
Then you could use this string extension in a custom validator.
validate :json_format protected def json_format errors[:base] << "not in json format" unless json.is_json? end
Currently (Rails 3/Rails 4) I would prefer a custom validator. Also see https://gist.github.com/joost/7ee5fbcc40e377369351.
# Put this code in lib/validators/json_validator.rb # Usage in your model: # validates :json_attribute, presence: true, json: true # # To have a detailed error use something like: # validates :json_attribute, presence: true, json: {message: :some_i18n_key} # In your yaml use: # some_i18n_key: "detailed exception message: %{exception_message}" class JsonValidator < ActiveModel::EachValidator def initialize(options) options.reverse_merge!(:message => :invalid) super(options) end def validate_each(record, attribute, value) value = value.strip if value.is_a?(String) ActiveSupport::JSON.decode(value) rescue MultiJson::LoadError, TypeError => exception record.errors.add(attribute, options[:message], exception_message: exception.message) end end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With