How to validate if a string is json in a Rails model
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 endend
Then you could use this string extension in a custom validator.
validate :json_formatprotected 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) endend
The best way is to add a method to the JSON module !
Put this in your config/application.rb :
module JSON def self.is_json?(foo) begin return false unless foo.is_a?(String) JSON.parse(foo).all? rescue JSON::ParserError false end endend
Now you'll be enable to use it anywhere ('controller, model, view,...'), just like this :
puts 'it is json' if JSON.is_json?(something)