lib/lotus/validations/attribute_definer.rb in lotus-validations-0.2.2 vs lib/lotus/validations/attribute_definer.rb in lotus-validations-0.2.3
- old
+ new
@@ -6,22 +6,43 @@
# Define attributes and their validations together
#
# @since 0.2.2
# @api private
module AttributeDefiner
+ # @since 0.2.3
+ # @api private
+ LOTUS_ENTITY_CLASS_NAME = 'Lotus::Entity'.freeze
+
+ # @since 0.2.3
+ # @api private
+ LOTUS_ENTITY_ID = 'id'.freeze
+
# Override Ruby's hook for modules.
#
# @param base [Class] the target class
#
# @since 0.2.2
# @api private
#
# @see http://www.ruby-doc.org/core/Module.html#method-i-included
def self.included(base)
base.extend ClassMethods
+ base.extend EntityAttributeDefiner if lotus_entity?(base)
end
+ # Decide if enable the support for `Lotus::Entity`.
+ #
+ # @param base [Class]
+ #
+ # @since 0.2.3
+ # @api private
+ def self.lotus_entity?(base)
+ base.included_modules.any? do |m|
+ m.to_s == LOTUS_ENTITY_CLASS_NAME
+ end
+ end
+
# @since 0.2.2
# @api private
module ClassMethods
# Override Ruby's hook for modules.
#
@@ -235,20 +256,27 @@
def attribute(name, options = {})
define_attribute(name, options)
validates(name, options)
end
+ # Set of user defined attributes
+ #
+ # @return [Array<String>]
+ #
+ # @since 0.2.2
+ # @api private
def defined_attributes
- @defined_attributes ||= Set.new
+ @defined_attributes ||= Set.new(super)
end
private
# @since 0.2.2
# @api private
def define_attribute(name, options)
- type = options.delete(:type)
+ type = options.fetch(:type) { nil }
+
define_accessor(name, type)
defined_attributes.add(name.to_s)
if options[:confirmation]
confirmation_accessor = "#{ name }_confirmation"
@@ -292,10 +320,77 @@
@attributes.get(name)
end
end
end
+ # Support for `Lotus::Entity`
+ #
+ # @since 0.2.3
+ # @api private
+ #
+ # @example
+ # require 'lotus/model'
+ # require 'lotus/validations'
+ #
+ # class Product
+ # include Lotus::Entity
+ # include Lotus::Validations
+ #
+ # attribute :name, type: String, presence: true
+ # attribute :price, type: Integer, presence: true
+ # end
+ #
+ # product = Product.new(name: 'Computer', price: '100')
+ #
+ # product.name # => "Computer"
+ # product.price # => 100
+ # product.valid? # => true
+ module EntityAttributeDefiner
+ # Override for Module#extend
+ #
+ # @since 0.2.3
+ # @api private
+ #
+ # @see http://ruby-doc.org/Module.html#method-i-extended
+ def self.extended(base)
+ base.class_eval do
+ include EntityAttributeDefiner::InstanceMethods
+ end
+ end
+
+ # @since 0.2.3
+ # @api private
+ #
+ # @see Lotus::Validations::AttributeDefiner#attribute
+ def attribute(name, options = {})
+ super
+ attributes name
+ end
+
+ # @since 0.2.3
+ # @api private
+ #
+ # @see Lotus::Validations::ClassMethods#validates
+ def validates(name, options = {})
+ super
+ define_attribute(name, options)
+ end
+
+ # @since 0.2.3
+ # @api private
+ module InstanceMethods
+ private
+ # @since 0.2.3
+ # @api private
+ #
+ # @see Lotus::Validations::AttributeDefiner#assign_attribute?
+ def assign_attribute?(attr)
+ super || attr.to_s == LOTUS_ENTITY_ID
+ end
+ end
+ end
+
# Create a new instance with the given attributes
#
# @param attributes [#to_h] an Hash like object which contains the
# attributes
#
@@ -333,10 +428,10 @@
#
# params = Params.new([:name, 'Luca'])
# signup = Signup.new(params)
#
# signup.name # => "Luca"
- def initialize(attributes)
+ def initialize(attributes = {})
@attributes ||= Utils::Attributes.new
attributes.to_h.each do |key, value|
public_send("#{ key }=", value) if assign_attribute?(key)
end