ActiveLayer provides validations and attribute filtering in a layer sitting on top of any model.
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


ActiveLayer provides a simple way to apply a set of validations, attribute filtering to your models.

ActiveRecord and other ORM validations are great for simple/ and relatively complex scenarios but they can very quickly become overloaded. ActiveLayer takes the approach that you might not want to have 'all' your validations in the model all the time. You might want to have a different set of accessible attributes for different classes of users.

Quick Example

	class User < ActiveRecord::Base; end
	# Every user field you want.. 
	# This layer uses the ActiveRecord adapter which pulls in several other pieces
	class UserLayer
		include ActiveLayer::ActiveRecord
		attr_accessible :name, :email, :address
		validates :name, :email, :presence => true
		validates :address_validation
		before_validate :normalize_address
		def normalize_address; end
		def address_validation
			errors.add(:address, :invalid) if address.blank?
	# Now how to use it:
	user = User.find(1)
	layer =
	layer.update_attributes( {:name => '', :admin => true, :address => 'on a busy road'} )   # => false
	layer.errors[:name].present # => true
	user.errors[:name].present => true
	user.admin  # => false   - was filtered out

Some of the players

  • ActiveLayer::Proxy
  • ActiveLayer::Validations
  • ActiveLayer::Attributes
  • ActiveLayer::Persistence


This module provides the ability to delegate method calls down to the object and typically you would not use this element directly. However, it does provide one key method active__layer__object which provides access to the underlying object/model. This may be necessary in certain cases.

This module also brings in the layers method which provides a friendly accessor for the active_layer_object


Currently the majority of the functionality resides in this module and provides the ability for composable validation classes to be layered together. This module is completely compatible with the wonderful ActiveModel::Validation module and in fact just wraps it and provides extra functionality.

Currently the following is supported:

  • Standard ActiveModel::Validators support (Each, With, Custom, etc.)
  • Custom validation methods
  • before_validation and after_validation hooks (Just like ActiveRecord)
  • Nested ActiveLayer validations (This is neat!)
  • All existing custom validators should 'just work'


	class AddressValidator
		include ActiveLayer::Validations

		before_validation :normalize_address
		validates :address, :presence => true
		validate :custom_method

		def normalize_address; end
		def custom_method; end
	class EmailValidator
		include ActiveLayer::Validations
		validates :email, :presence => true

	class UserValidator
		include ActiveLayer::Validations
		validates :name, :presence => true
		validates_with EmailValidator 
		validates_with AddressValidator, :attributes => [:addresses]
	# the EmailValidator will get passed the user object
	# the AddressValidator will get passed each address of the user and merge the errors back up
	user = User.find(1)
	validator =
	validator.valid?   # => true/false


This module provides the ability to bulk assign attributes with attribute protection via att_accessible. By default all attributes are not assignable and you must declare which attributes are accessible. Note, each attribute is available for individual assigning or reading.


	class FlawedUserFilter
		# All attributes are now assignable
	class UserFilter
		attr_accessible :name, :address
	user = User.find(1)
	filter =
	filter.attributes = {:name => 'Bob', 'admin' => true}
	user.admin  #  => false


This layer is responsible for providing the save and update_attributes methods that function very similar to ActiveRecord. Both layers invoke the validations in the layer, if currently mixed in and ultimately delegate to the proxy object for saving. If the Attributes module is mixed in then the guards will be used however, if it is not mixed then active_layer_object.attributes=(hash) will be invoked.

Note: If you plan to use Persistence with Attributes then you must mix-in the Attributes module after the Persistence module


	class UserPersistor
		include ActiveLayer::Persistence

	user = User.find(1)
	persistor =!  # will raise an ActiveLayer::RecordInvalidError with a #record method
	persistor.update_attributes(:name => 'new')
	persistor.update_attributes!(:name => 'new')

TODO / Plans

  • Ensure that the valid? method calls the underlying proxy object.valid?
  • Nested attribute support - similar to Rails - but in an adaptable manner for use in other ORMs
  • Add support for additional ORMs
  • Ideas?


ActiveLayer is available under the terms of the MIT license (see LICENSE.txt for details).