No commit activity in last 3 years
No release in over 3 years
There's a lot of open issues
Validation for serialized model objects
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 1.5
~> 10.1
~> 2.6
~> 1.3

Runtime

< 5.0, >= 3.0
 Project Readme

Validates Serialized

ActiveModel provides ways to validate attributes, and to serialize objects. This gem provides some ActiveModel extensions and syntactic sugar to simplify the process of validating those serialized objects.

This gem provides:

  • A generic validation method that supports any serializable object
  • A validation method for serialized hashes, to validate specific key values
  • A validation method for serialized hashes, to support validating all hash values
  • A validation method for serialized arrays, to support validating all array values

Installation

Add this line to your application's Gemfile:

gem 'validates_serialized', '~> 0.0.1'

And then execute:

$ bundle

Or install it yourself as:

$ gem install validates_serialized

Validating a generic object

Here we have an example, serializable class called 'Person' with a name and age attribute.

class Person
  def initialize(h={})
    h.each {|k,v| send("#{k}=",v)}
  end

  def name
    @name ||= nil
  end

  def name=(val)
    @name = val
  end

  def age
    @age ||= nil
  end

  def age=(val)
    @age = val
  end
end

Now we can serialize this object and validate its properties in another class

class Family < ActiveRecord::Base
  include ActiveModel
  ...

  serialize :father, Person
  validates_serialized :father do
    validates :name, presence: true
    validates :age, numericality: { greater_than: 21 }
  end
end

The validations will be run against the serialized object whenever validation hooks are fired. E.g.

# With valid serialized object
valid_father = Person.new(name: "Bob", age: 31)
family = Family.new(father: valid_father)
family.valid? #=> true

# With invalid serialized object
valid_father = Person.new(name: "Bob", age: 13)
family = Family.new(father: valid_father)
family.valid? #=> false
family.errors[:father] #=> ["age must be greater than 13"]

Validating a serialized hash by keys

class Comment < ActiveRecord::Base
  include ActiveModel
  ...

  serialize :metadata, Hash
  validates_hash_keys :metadata do
    validates :timestamp, presence: true
    validates :locale, presence: true
  end
end

# With valid hash
comment = Comment.new(metadata: { timestamp: Time.new(2014, 1, 1), locale: "Ohio" })
comment.valid? #=> true

# With invalid hash
comment = Comment.new(metadata: { timestamp: Time.new(2014, 1, 1), locale: nil })
comment.valid? #=> false
comment.errors[:metadata] #=> ["locale can't be blank"]

Validating serialized hash values

class Comment < ActiveRecord::Base
  include ActiveModel
  ...

  serialize :ratings, Hash
  validates_hash_values :ratings, numericality: { greater_than: 0 }
end

# With valid hash
comment = Comment.new(ratings: { tom: 4, jim: 2 })
comment.valid? #=> true

# With invalid hash
comment = Comment.new(ratings: { tom: 4, jim: -1 })
comment.valid? #=> false
comment.errors[:ratings] #=> ["ratings must be greater than 0"]

Validating a serialized array (syntax #1)

class Comment < ActiveRecord::Base
  include ActiveModel
  ...

  serialize :tags, Array
  validates_array_values_with :tags, length: { minimum: 4 }
end

# With valid hash
comment = Comment.new(tags: ["ruby" "rails"])
comment.valid? #=> true

# With invalid hash
comment = Comment.new(tags: ["ruby" "rails", "ror"])
comment.valid? #=> false
comment.errors[:tags] #=> ["tags is too short (minimum is 4 characters)"]

Validating a serialized array (syntax #2)

class Comment < ActiveRecord::Base
  include ActiveModel
  ...

  serialize :tags, Array
  validates_each_in_array :tags do
    validates :value, length: { minimum: 4 } #the attribute 'value' with access each value
  end
end

# With valid hash
comment = Comment.new(tags: ["ruby" "rails"])
comment.valid? #=> true

# With invalid hash
comment = Comment.new(tags: ["ruby" "rails", "ror"])
comment.valid? #=> false
comment.errors[:tags] #=> ["tags is too short (minimum is 4 characters)"]

Customizing error message for Array validation

There is activerecord.errors.messages.array_has_invalid_value translation key available for Array validation errors.

The two options are available in translation: attribute and text

Default error message is: "#{attribute} has a value that #{text}"

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request