require 'activerecord' # = 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(options = {}) options[:only] = [options[:only]] if options[:only] && !options[:only].is_a?(Array) options[:except] = [options[:except]] if options[:except] && !options[:except].is_a?(Array) parts = [] address_parts_fields.each do |part| if part.is_a?(Array) # We only want to allow 2d arrays subparts = [] part.flatten.each do |subpart| next if !respond_to?(subpart) value = send(subpart) next if value.to_s.blank? || (options[:only] && !options[:only].include?(subpart)) || (options[:except] && options[:except].include?(subpart)) subparts << value end parts << subparts unless subparts.compact.empty? else next if !respond_to?(part) value = send(part) next if value.to_s.strip == "" || (options[:only] && !options[:only].include?(part)) || (options[:except] && options[:except].include?(part)) parts << value end end result = parts.collect do |part| if part.is_a?(Array) part.collect{|sub| sub.to_s.strip.blank? ? nil : sub}.join(" ") else part.to_s.strip.blank? ? nil : part end end return result.compact end private def address_parts_fields self.class.address_parts_fields end end end ActiveRecord::Base.send(:include, Addresslogic)