# = Address Logic # # This is a simple module that you can include into any classm as long as it has a street1, street2, city, state, zip, and country (optional) # methods. Just include it into your class like so: # # class Address # apply_addresslogic :fields => [:street1, :street2, :city, [:state, :zip], :country] # end # # The above will return: # ["Street1", "Street2", "City", "State Zip", "Country"] # # This adds a sigle method: address_parts. More on this method below... module Addresslogic def self.included(base) base.extend ClassMethods end module ClassMethods attr_accessor :address_parts_fields def apply_addresslogic(args = {}) self.address_parts_fields = args[:fields] || [:street1, :street2, [:city, [:state, :zip]], :country] include Addresslogic::InstanceMethods end end module InstanceMethods # Returns the parts of an address in an array. Example: # # ["Street1", "Street2", "City", "State Zip", "Country"] # # This makes displaying addresses on your view pretty simple: # # address.address_parts.join("
") # # === Options # # * only: fields you want included in the result # * except: any fields you want excluded from the result def address_parts(*args) options = args.last.is_a?(Hash) ? args.pop : {} options[:only] = [options[:only]] if options[:only] && !options[:only].is_a?(Array) options[:except] = [options[:except]] if options[:except] && !options[:except].is_a?(Array) fields = args[0] || address_parts_fields level = args[1] || 0 parts = [] fields.each do |field| if field.is_a?(Array) has_sub_array = field.find { |item| item.is_a?(Array) } separator = has_sub_array ? ", " : " " sub_parts = address_parts(field, level + 1, options).join(separator) next if sub_parts.empty? parts << sub_parts else next if !respond_to?(field) value = send(field) next if value.to_s.strip == "" || (options[:only] && !options[:only].include?(field)) || (options[:except] && options[:except].include?(field)) parts << value end end parts end private def address_parts_fields self.class.address_parts_fields end end end Object.send(:include, Addresslogic)