0.0
No commit activity in last 3 years
No release in over 3 years
There's a lot of open issues
Provides a DSL for common validation formats like Date, Array, DateTime etc.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 1.3
>= 0
>= 0

Runtime

 Project Readme

Rails::Legit

It is quite common to perform checks like:

  • Check if an array is a subset of another array
  • A date supplied by the user does not be in the past
  • An event start date will always fall after the event end date

and so on...

This gem abstracts out this common logic and lets you do things like:

validates :start_date, verify_date: { before: Date.current }

or

validates :end_date, verify_date: { before: :current}

As of now, only Date and DateTime validators are implemented.

Installation

Add this line to your application's Gemfile:

gem 'rails_legit'

And then execute:

$ bundle

Or install it yourself as:

$ gem install rails_legit

Usage

The gem uses Rails' ActiveModel::Validator to perform these checks.

Date Validator

Say we are building an event management application where the management can create events where they can specify the start times and the end times of the event. EventForm is such a class that is a non-persistent model of the event record.

class Event < ActiveRecord::Base
  # has the following attributes:
  # name
  # description
  # to
  # from
end

The to and from are DateTime objects that get stored in the DB. And the corresponding ActiveModel form: (assuming Rails 4)

class EventForm 
  include ActiveModel::Model
  attr_accessor :name, :description, :to, :from
  attr_accessor :to_date, :to_time
  attr_accessor :from_date, :from_time
end

The :to_date, :to_time, :from_date, :from_time are the attributes for the data that is returned from the UI where there are separate inputs for start date, end date, start time and end time.

To use the DateValidator, include the RailsLegit module in the EventForm class:

class EventForm
  # unchanged from above
  include RailsLegit
end

Adding validations is as simple as:

class EventForm
  # unchanged from above
  validates :from_date, :to_date, date: true
end

Currently supported validation syntax elements are:

verify_date: true

This will check if the date returned from the input fields in the UI is valid or not.

verify_date: { before: Date.current }
# same as:
verify_date: { before: :current }

The valid options are :before, :after, :on_or_before, :on_or_after, :on.

You can pass in a method as a symbol, string or a Date object. By default, all symbols except :current, :today, :now are sent to the object under validation.

validates :from_date, date: { after: :current } # Date.current is used
validates :from_date, date: { after: :today   } # Date.current is used 
validates :from_date, date: { after: :now     } # Date.current is used

validates :from_date, date: { after: :end_date } # <EventForm Object>.end_date is used

Finally,

class EventForm
  attr_accessor :to_date, :from_date
  include ActiveModel::Model
  include RailsLegit
  validates :from_date, date: { after: :today }
  validates :to_date, date: { after: :from_date }
end

Array Validator

It is quite common to check whether an array of attributes is a subset of another array -- a list of valid IDs, for example. The VerifyArray validator handles the three cases of :in, :not_inand:eq`. The abstract functionality is as follows:

# The simplest case would be to verify if a record attribute is an
# Array
validates [1, 2], verify_array: true                    # => true

# Or, you could specify options. Supported options are :in, :not_in,
# :eq

validates [1, 2, 3], verify_array: { in: [1, 2, 3, 4] } # => true
# Note: The :in and :not_in validators are not strict. That is, the
# following will work as expected. This is similar to :eq in this
# case
validates [1, 2, 3], verify_array: { in: [1, 2, 3] }    # => true
validates [1, 2, 3], verify_array: { in: [1, 2] }       # => false

# The ordering is not a factor
validates [3, 2, 1], verify_array: { in: [1, 2, 3, 4] } # => true

validates [1, 2], verify_array: { not_in: [4, 5] }      # => true
validates [1, 2], verify_array: { not_in: [1, 5] }      # => true

# :eq is a strict validator which will result true only if the given
# array contains the exact same elements (irrespective of order)
# compared to the verification array.

validates [1, 2], verify_array: { eq: [2, 1] }          # => true
validates [1, 2], verify_array: { eq: [3, 1] }          # => false

Use this in validating your models like so:

# Specify a Symbol which is a method defined on the model
class EventInvitees < ActiveRecord::Base
  validates :invited_users, verify_array: { in: :valid_users_in_db }

  def valid_users_in_db
    User.all.pluck(:id).map(&:to_s)
  end
end

# or, specify an Array
class EventInvitees < ActiveRecord::Base
  validates :invited_users, verify_array: { in: [1, 25, 155] }
end

# or, specify a Proc that returns an array
class EventInvitees < ActiveRecord::Base
  validates :invited_users, verify_array: { in: ->{ [1, 25, 155] } }
end

The only caveat here is that the verification item (symbol/proc) should return an Array.

Hash Validator

To validate a hash, you can do like so:

# some_hash = { one: 1, two: 2, three: 3 }
validates some_hash, verify_hash: { keys: [:one, :two, :three] } # => true
validates some_hash, verify_hash: { values: [1, 2, 3] }          # => true

The valid options are :keys and :values. You can pass in an Array or a Proc that evaluates to an array or a method that is defined inside the class.

# You can use an Array as the option's value

class User < ActiveRecord::Base
  validates :settings, verify_hash: { keys: ['public_email', 'public_profile'] }
end

# You can use a Proc

class User < ActiveRecord::Base
  validates :settings, verify_hash: { keys: -> { ['public_email', 'public_profile'] } }
end

# Or, you can use a Symbol if a method with that name is defined

class User < ActiveRecord::Base
  validates :settings, verify_hash: { keys: :accepted_settings }

  # The method can be private or a visible one
  private

  def accepted_settings
    ['public_email', 'public_profile']
  end
end

The keys or values are checked for existence and not for equality. In other words even if the hash in the first example in Hash section was { one: 1, two: 2 }, it would still validate to true. To add to that, the ordering is not significant.

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