### Setup ActiveRecord Table and Model for JSON Validation Source: https://github.com/mirego/activerecord_json_validator/blob/master/README.md This Ruby code demonstrates how to set up an ActiveRecord model for JSON validation. It includes creating a database table with a JSON column and defining a model with a JSON validator that references a schema file. It also shows examples of valid and invalid user profiles. ```ruby 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') # Validations validates :name, presence: true validates :profile, presence: true, json: { schema: PROFILE_JSON_SCHEMA } end user = User.new(name: 'Samuel Garneau', profile: { city: 'Quebec City' }) user.valid? # => false user = User.new(name: 'Samuel Garneau', profile: { city: 'Quebec City', country: 'Canada' }) user.valid? # => true user = User.new(name: 'Samuel Garneau', profile: '{invalid JSON":}') user.valid? # => false user.profile_invalid_json # => '{invalid JSON":}' ``` -------------------------------- ### Add gem to Gemfile Source: https://github.com/mirego/activerecord_json_validator/blob/master/README.md To install the activerecord_json_validator gem, add the specified line to your application's Gemfile. This makes the validator available for use in your Rails project. ```ruby gem 'activerecord_json_validator', '~> 3.1.0' ``` -------------------------------- ### Passing Options to JSONSchemer Source: https://context7.com/mirego/activerecord_json_validator/llms.txt Enables passing configuration options directly to the underlying `json_schemer` library via the `:options` argument. This allows for advanced features like format validation and custom reference resolvers. Dependencies include `json_schemer` and potentially network libraries if custom resolvers are used. ```ruby class User < ActiveRecord::Base PROFILE_SCHEMA = { 'type' => 'object', 'properties' => { 'email' => { 'type' => 'string', 'format' => 'email' }, 'website' => { 'type' => 'string', 'format' => 'uri' } } } validates :profile, json: { schema: PROFILE_SCHEMA, options: { formats: true, # Enable format validation ref_resolver: 'net/http' # Custom reference resolver } } end ``` ```ruby class Document < ActiveRecord::Base validates :content, json: { schema: DOCUMENT_SCHEMA, options: { insert_property_defaults: true, # Insert default values property_name_resolver: ->(name) { name.underscore } # Transform property names } } end ``` -------------------------------- ### Dynamic JSON Schema Definition using Lambda Source: https://github.com/mirego/activerecord_json_validator/blob/master/README.md This Ruby code shows how to dynamically set the JSON schema based on model logic. It uses a lambda (or a symbol referencing a method) to determine which schema file to use for validation, allowing for context-dependent validation rules. ```ruby class User < ActiveRecord::Base # Constants PROFILE_REGULAR_JSON_SCHEMA = Rails.root.join('config', 'schemas', 'profile.json_schema') PROFILE_ADMIN_JSON_SCHEMA = Rails.root.join('config', 'schemas', 'profile_admin.json_schema') # Validations validates :profile, presence: true, json: { schema: lambda { dynamic_profile_schema } } # `schema: :dynamic_profile_schema` would also work def dynamic_profile_schema admin? ? PROFILE_ADMIN_JSON_SCHEMA : PROFILE_REGULAR_JSON_SCHEMA end end ``` -------------------------------- ### JSON Schema as Hash or String Source: https://github.com/mirego/activerecord_json_validator/blob/master/README.md This Ruby code demonstrates that the JSON schema can be provided not only as a file path but also directly as a Ruby Hash or a JSON string. This offers flexibility in how schemas are defined and managed within the application. ```ruby class User < ActiveRecord::Base # Constants JSON_SCHEMA = Rails.root.join('config', 'schemas', 'profile.json_schema') # JSON_SCHEMA = { 'type' => 'object', 'properties' => { 'foo' => { 'type' => 'integer', 'minimum' => 3 } } } # Schema as Hash # JSON_SCHEMA = '{"type":"object","properties":{"foo":{"type":"integer","minimum":3}}}' # Schema as JSON string # Validations validates :profile, presence: true, json: { schema: JSON_SCHEMA } end ``` -------------------------------- ### Configure JSON Validator Options Source: https://github.com/mirego/activerecord_json_validator/blob/master/README.md This section details the options available for the `json` validator in ActiveRecord. Options include specifying the `:schema` to validate against, a `:value` to use for validation, a custom error `:message`, and additional `:options` to pass to the underlying `json_schemer` gem. ```ruby # Available options for the json validator: # :schema - The JSON schema to validate against. # :value - The actual value to use for validation. # :message - The ActiveRecord error message. # :options - Additional options for json_schemer. ``` -------------------------------- ### Dynamic JSON Schema Validation using Proc in Ruby Source: https://context7.com/mirego/activerecord_json_validator/llms.txt Enables validation of JSON attributes against different schemas based on runtime conditions, using a Proc or a Symbol pointing to a method. This allows for flexible validation rules that adapt to the state of the model. The `json` validator checks the attribute against the schema returned by the dynamic method. ```ruby class User < ActiveRecord::Base PROFILE_REGULAR_SCHEMA = { 'type' => 'object', 'properties' => { 'city' => { 'type' => 'string' }, 'country' => { 'type' => 'string' } }, 'required' => ['country'] } PROFILE_ADMIN_SCHEMA = { 'type' => 'object', 'properties' => { 'city' => { 'type' => 'string' }, 'country' => { 'type' => 'string' }, 'admin_level' => { 'type' => 'integer', 'minimum' => 1, 'maximum' => 5 }, 'department' => { 'type' => 'string' } }, 'required' => ['country', 'admin_level', 'department'] } validates :profile, json: { schema: lambda { dynamic_profile_schema } } # Alternatively: validates :profile, json: { schema: :dynamic_profile_schema } def dynamic_profile_schema admin? ? PROFILE_ADMIN_SCHEMA : PROFILE_REGULAR_SCHEMA end def admin? role == 'admin' end end # Regular user validation user = User.new(role: 'user', profile: { country: 'Canada', city: 'Toronto' }) user.valid? # => true # Admin requires additional fields admin = User.new(role: 'admin', profile: { country: 'Canada', city: 'Toronto' }) admin.valid? # => false admin = User.new( role: 'admin', profile: { country: 'Canada', city: 'Toronto', admin_level: 3, department: 'IT' } ) admin.valid? # => true ``` -------------------------------- ### Basic JSON Validation with Schema Source: https://context7.com/mirego/activerecord_json_validator/llms.txt Validates a JSON attribute against a predefined schema. It uses a raw getter for validation and an OpenStruct getter for convenient access to the JSON data. Dependencies include ActiveRecord and a JSON schema definition. ```ruby class User < ActiveRecord::Base validates :raw_profile, json: { schema: PROFILE_SCHEMA } def raw_profile self[:profile] end def profile OpenStruct.new(self[:profile] || {}) end end ``` -------------------------------- ### Customizing the Value to Validate Source: https://github.com/mirego/activerecord_json_validator/blob/master/README.md This Ruby code illustrates how to specify a custom value for JSON validation when the default attribute getter is not suitable. It uses a lambda to define a 'raw getter' that accesses the attribute's underlying storage, ensuring validation is performed on the correct data. ```ruby # Will validate `self.foo` by default validates :foo, json: { schema: SCHEMA } # Will validate `self[:foo]` using a lambda validates :foo, json: { schema: SCHEMA, value: ->(record, _, _) { record[:foo] } } # Alternatively, implement a raw getter method validates :raw_foo, json: { schema: SCHEMA } def raw_foo self[:foo] end ``` -------------------------------- ### Validate JSON Attribute with Schema File in Ruby Source: https://context7.com/mirego/activerecord_json_validator/llms.txt Validates a JSON attribute against a JSON schema file located on the filesystem. It requires the `json_schemer` gem and integrates with Rails' ActiveModel validation. The input is a Ruby hash or a JSON string, and the output is a boolean indicating validity, with errors accessible via `user.errors.full_messages`. ```ruby class User < ActiveRecord::Base PROFILE_JSON_SCHEMA = Rails.root.join('config', 'schemas', 'profile.json') validates :profile, presence: true, json: { schema: PROFILE_JSON_SCHEMA } end # Valid usage user = User.new(profile: { city: 'Quebec City', country: 'Canada' }) user.valid? # => true # Invalid - missing required field user = User.new(profile: { city: 'Quebec City' }) user.valid? # => false user.errors.full_messages # => ["Profile object at root is missing required properties: country"] # Invalid - malformed JSON string user = User.new(profile: '{invalid JSON":}') user.valid? # => false user.profile_invalid_json # => '{invalid JSON":}' user.profile # => {} ``` -------------------------------- ### Customize JSON Validation Message with Proc Source: https://github.com/mirego/activerecord_json_validator/blob/master/README.md Demonstrates how to use a Proc for the ':message' option in ActiveRecord's JSON validation. The Proc receives an array of errors from the JSON schema validator and can be used to format or augment these errors as first-level errors for the model. This allows for dynamic and detailed error reporting. ```ruby class User < ActiveRecord::Base # Validations validates :profile, presence: true, json: { message: ->(errors) { errors }, schema: 'foo.json_schema' } end user = User.new.tap(&:valid?) user.errors.full_messages # => [ # 'The property \'#/email\' of type Fixnum did not match the following type: string in schema 2d44293f-cd9d-5dca-8a6a-fb9db1de722b#', # 'The property \'#/full_name\' of type Fixnum did not match the following type: string in schema 2d44293f-cd9d-5dca-8a6a-fb9db1de722b#', # ] ``` -------------------------------- ### Custom Error Messages for JSON Validation Source: https://context7.com/mirego/activerecord_json_validator/llms.txt Allows customization of validation error messages using the `:message` option. This can be a Symbol pointing to a locale key, a String, or a Proc for dynamic message generation. It enhances user feedback by providing specific error explanations. ```ruby class User < ActiveRecord::Base validates :profile, json: { schema: 'config/schemas/profile.json', message: :profile_schema_invalid } end ``` ```ruby class User < ActiveRecord::Base validates :profile, json: { schema: 'config/schemas/profile.json', message: ->(errors) { errors } } end ``` ```ruby class Product < ActiveRecord::Base validates :metadata, json: { schema: PRODUCT_SCHEMA, message: ->(errors) { errors.map do |error| details = error['details'].to_a.flatten.join(' ') "Metadata validation failed: #{details}" end } } end ``` -------------------------------- ### Invalid JSON String Detection in ActiveRecord Source: https://context7.com/mirego/activerecord_json_validator/llms.txt Automatically detects and flags malformed JSON strings in an attribute by creating an `_invalid_json` reader. If JSON parsing fails, the attribute is set to an empty hash to prevent application crashes. This is useful for handling user input that may not be valid JSON. ```ruby class User < ActiveRecord::Base validates :profile, json: { schema: PROFILE_SCHEMA } end ``` -------------------------------- ### Define JSON Schema for Validation Source: https://github.com/mirego/activerecord_json_validator/blob/master/README.md This JSON schema defines the expected structure for a user's profile. It specifies that 'city' and 'country' should be strings, and 'country' is a required field. This schema is used by the validator to check incoming JSON data. ```json { "type": "object", "$schema": "http://json-schema.org/draft-04/schema#", "properties": { "city": { "type": "string" }, "country": { "type": "string" } }, "required": ["country"] } ``` -------------------------------- ### Validating Serialized JSON Attributes Source: https://context7.com/mirego/activerecord_json_validator/llms.txt Validates JSON data stored in serialized attributes, which is essential for databases lacking native JSON support (e.g., SQLite). It uses the `serialize` method with `coder: JSON` and applies JSON schema validation. Dependencies include ActiveRecord and Ruby's built-in JSON module. ```ruby class User < ActiveRecord::Base serialize :data, coder: JSON serialize :preferences, coder: JSON PREFERENCES_SCHEMA = { 'type' => 'object', 'properties' => { 'theme' => { 'type' => 'string', 'enum' => ['light', 'dark'] }, 'notifications' => { 'type' => 'boolean' }, 'language' => { 'type' => 'string', 'pattern' => '^[a-z]{2}$' } }, 'required' => ['theme'] } validates :preferences, json: { schema: PREFERENCES_SCHEMA } end ``` -------------------------------- ### Custom JSON Value Extraction with :value Option in Ruby Source: https://context7.com/mirego/activerecord_json_validator/llms.txt Allows the JSON validator to use a custom method for retrieving the attribute's value, bypassing the default getter. This is particularly useful when the attribute has a custom accessor that returns a transformed object, ensuring validation operates on the raw database value. The `value` option accepts a Proc or lambda. ```ruby class User < ActiveRecord::Base PROFILE_SCHEMA = Rails.root.join('config', 'schemas', 'profile.json') # Validate the raw JSON from database, not the transformed object validates :profile, json: { schema: PROFILE_SCHEMA, value: ->(record, attribute, _value) { record[attribute] } } # Custom getter that returns an OpenStruct def profile OpenStruct.new(self[:profile] || {}) end end # The validator accesses self[:profile] directly user = User.new(profile: { country: 'Canada', city: 'Montreal' }) user.valid? # => true ``` -------------------------------- ### Validate JSON Attribute with Inline Schema Definition in Ruby Source: https://context7.com/mirego/activerecord_json_validator/llms.txt Validates a JSON attribute using an inline schema defined as a Ruby Hash or String. This method is useful for simpler schemas or when external files are not desired. The validation leverages ActiveModel and `json_schemer`, returning a boolean result and populating `errors` on failure. ```ruby class Product < ActiveRecord::Base PRODUCT_SCHEMA = { 'type' => 'object', 'properties' => { 'name' => { 'type' => 'string' }, 'price' => { 'type' => 'number', 'minimum' => 0 }, 'in_stock' => { 'type' => 'boolean' } }, 'required' => ['name', 'price'] } validates :metadata, json: { schema: PRODUCT_SCHEMA } end # Valid product product = Product.new(metadata: { name: 'Widget', price: 19.99, in_stock: true }) product.valid? # => true # Invalid - wrong type product = Product.new(metadata: { name: 'Widget', price: 'free' }) product.valid? # => false # Invalid - missing required field product = Product.new(metadata: { name: 'Widget' }) product.valid? # => false ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.