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