# ActiveRecord Hacks: # # 1. Dynamic "nice_date" # Basically, i got tired of typing object.created_at.strftime("%m-%d-%Y") # so i came up with the following method_missing hack for any Time # attribute in an ActiveRecord object. Just prepend "nice_" in # front of any Datetime attribute and you will get a nicely formatted # date string. Plus some other goodies :) # # # Examples: # object.created_at # => Mon Dec 04 12:36:55 CST 2006 # object.nice_created_at # => "12-04-2006" (mm-dd-YYYY) # object.nice_created_at(:euro) # => "04-12-2006" (dd-mm-YYYY) # # plus, for you guys (and gals) that like using slashes instead of dashes: # object.nice_created_at(:slash) # => "12/04/2006" (mm/dd/YYYY) # object.nice_created_at(:euro_slash) # => "04/12/2006" (dd/mm/YYYY) # # and finally: # object.nice_created_at(:rss) # => "Mon, 04 Dec 2006 12:36:55 -0600" (rfc822) # # NOTE** # If the method does not return a value of class Time, then a NoMethodError # will be thrown # # # 2. Dynamic SEO formatting. # Any method that returns a string can use this dynamic method. # This method will create an SEO friendly string out of the attribute # chosen (for use mainly in URLS). It will append the objects id # (not the object_id, but the id key from the database) so that you # can use params[:id] and not have to create new routes. # # Example: # puts object.id # => 1 # object.title = " Rails is freaking awesome, didn't you know that? " # puts object.seo_title # => "1-rails-is-freaking-awesome-didnt-you-know-that" # # # 3. nice_name # This one is pretty simple. I found myself adding this same method to # alot of my applications. Basically it looks for an attribute called "first_name" # and one called "last_name" and combines them together with a space in between. # # Example: # object.first_name = "jake" # object.last_name = "varghese" # object.nice_name # => "jake varghese" # # NOTE** # If the method doesn't have EITHER first_name or last_name, then a NoMethodError # will be thrown. It must have both attributes # # 4. create/new from XML # Create an ActiveRecord Object from XML. This method relies on the basics of AR's # current to_xml string (basically, it must be formatted as such). # The differences between new_from_xml and create_from_xml are the same as the differences # between AR.new and AR.create # # If your XML string contains multiple records, it will parse out each record and # create an object. The "multiple record" call returns an array like find(:all) # # # Example: # person = Person.create_from_xml(xml_string) class ActiveRecord::Base def nice_name if @attributes.include?("first_name") && @attributes.include?("last_name") return first_name + " " + last_name else raise NoMethodError end end def method_missing_with_nice_time(method_id, *args, &block) method_name = method_id.to_s if md = /nice_([_a-zA-Z]\w*)/.match(method_name) attribute_names = md.captures.last.split('_and_') method_missing_without_nice_time(method_id, *args, &block) unless attribute_names.all? { |name| self.class.column_methods_hash.include?(name.to_sym) } attribute = attribute_names.first argument = args.flatten.first || "%m-%d-%Y" argument = "%d-%m-%Y" if argument == :euro argument = "%d/%m/%Y" if argument == :euro_slash argument = "%m/%d/%Y" if argument == :slash #raise args.inspect if self.send(attribute.to_sym).class.to_s =~ /Time/ unless argument == :rss self.send(attribute.to_sym).strftime(argument) else self.send(attribute.to_sym).to_s(:rfc822) end end else method_missing_without_nice_time(method_id, *args, &block) end end alias_method_chain :method_missing, :nice_time def method_missing_with_seo(method_id, *args, &block) method_name = method_id.to_s if md = /seo_([_a-zA-Z]\w*)/.match(method_name) attribute_names = md.captures.last.split('_and_') method_missing_without_seo(method_id, *args, &block) unless attribute_names.all? { |name| self.class.column_methods_hash.include?(name.to_sym) } attribute = attribute_names.first #raise args.inspect if self.send(attribute.to_sym).class == String self.id.to_s + "-" + self.send(attribute.to_sym).seo_friendly else method_missing_without_seo(method_id, *args, &block) end else method_missing_without_seo(method_id, *args, &block) end end alias_method_chain :method_missing, :seo def self.new_from_xml(xml_str) self.create_obj_from_xml(xml_str, :new) end def self.create_from_xml(xml_str) self.create_obj_from_xml(xml_str, :create) end private def self.create_obj_from_xml(xml_str, creation_method) obj_hash = Hash.from_xml(xml_str) # if we have multiple records in the XML string, we will have to parse out each record if obj_hash.keys.include?(self.class_name.pluralize.downcase) output = [] objects = obj_hash.send(self.class_name.pluralize.downcase).send(self.class_name.downcase) objects.each do |object| output << self.send(creation_method, object) end return output else attribs = obj_hash.send(self.class_name.downcase) return self.send(creation_method, attribs) end end end