# # Copyright (c) 2006-2012 Hal Brodigan (postmodern.mod3 at gmail.com) # # This file is part of Ronin. # # Ronin is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Ronin is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ronin. If not, see . # require 'ronin/model/types' require 'ronin/support/inflector' require 'dm-core' require 'dm-types' require 'dm-migrations' require 'dm-validations' require 'dm-aggregates' require 'dm-serializer' require 'dm-timestamps' module Ronin # # Modifies a class so that it can represent a DataMapper model in the # {Database}. # module Model include Model::Types # # Sets up a class as a DataMapper model that can be used with the # {Database}. Also adds {ClassMethods} to the new model. # # @param [Class] base # The class that will be setup as a DataMapper model. # def self.included(base) unless base < DataMapper::Resource base.send :include, DataMapper::Resource end # include DataMapper plugins base.send :include, DataMapper::Migrations, DataMapper::Serialize, DataMapper::Timestamps # include Model types / methods base.send :include, Model::Types base.send :include, InstanceMethods base.send :extend, ClassMethods end # # Class methods that are added when {Model} is included into a class. # module ClassMethods # # The default name to use when defining relationships with the # model. # # @return [Symbol] # The name to use in relationships. # # @since 1.0.0 # # @api semipublic # def relationship_name name = Support::Inflector.underscore(self.name.split('::').last) return Support::Inflector.pluralize(name).to_sym end # # Loads and initialize the resources. # # @api private # def load(records,query) resources = super(records,query) resources.each { |resource| resource.send :initialize } return resources end end # # Instance methods that are added when {Model} is included into a class. # module InstanceMethods # # Formats the attributes of the model into human readable names # and values. # # @param [Hash] options # Additional options. # # @option options [Array] :exclude ([]) # A list of attribute names to exclude. # # @yield [name, value] # If a block is given, it will be passed the name and humanized # value of each attribute. # # @yieldparam [String] name # The humanized name of the attribute. # # @yieldparam [String] value # The human readable value of the attribute. # # @return [Hash{String => String}] # A hash of the humanly readable names and values of the attributes. # # @api semipublic # def humanize_attributes(options={}) exclude = [:id, :type] if options[:exclude] exclude += options[:exclude] end formatter = lambda { |value| if value.kind_of?(Array) value.map(&formatter).join(', ') elsif value.kind_of?(Symbol) Support::Inflector.humanize(value) else value.to_s end } formatted = {} self.attributes.each do |name,value| next if (value.nil? || (value.respond_to?(:empty?) && value.empty?)) unless (exclude.include?(name) || value.nil?) name = name.to_s unless name[-3..-1] == '_id' name = Support::Inflector.humanize(name) value = formatter.call(value) if block_given? yield name, value end formatted[name] = value end end end return formatted end end end end