Created
June 14, 2011 17:52
-
-
Save yrgoldteeth/1025443 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# **Whereabouts** is a Rails plugin that generates a polymorphic, inheritable | |
# Address model. Install it as a Rails plugin (Rails 3.x+ required) | |
# | |
# rails plugin install http://github.com/yrgoldteeth/whereabouts.git | |
# | |
# The most simple use case creates a has_one relationship with | |
# a generic Address: | |
# | |
# class Foo < ActiveRecord::Base | |
# has_whereabouts | |
# end | |
# | |
# f = Foo.new | |
# f.build_address | |
# | |
# Also, a model can have any number of different inherited types of Addresses, | |
# i.e. shipping address and mailing address | |
# | |
# class Foo < ActiveRecord::Base | |
# has_whereabouts :shipping | |
# has_whereabouts :mailing | |
# end | |
# | |
# f = Foo.new | |
# f.build_shipping | |
# f.build_mailing | |
# | |
# If you have the [Ruby Geocoder](http://www.rubygeocoder.com) specified in | |
# your project's Gemfile, adding {:geocode => true} to the has_whereabouts | |
# definition will automatically geocode and populate the latitude and | |
# longitude fields for the record. | |
# | |
# class Foo < ActiveRecord::Base | |
# has_whereabouts :shipping, {:geocode => true} | |
# end | |
# | |
# You can see the source on [github](https://github.com/yrgoldteeth/whereabouts), and | |
# this page was generated with the wonderful | |
# [rocco](http://rtomayko.github.com/rocco/) documentation generator. | |
# Hey, that's [me](http://ndfine.com) | |
module Yrgoldteeth | |
# **Whereabouts** | |
module Has | |
module Whereabouts | |
# Extend the ClassMethods module | |
def self.included(base) | |
base.extend ClassMethods | |
end | |
# **ClassMethods** | |
module ClassMethods | |
# Accepts a symbol that will define the inherited | |
# type of Address. Defaults to the parent class. | |
def has_whereabouts klass=:address, options={} | |
unless klass == :address | |
create_address_class(klass.to_s.titleize.gsub(' ','')) | |
end | |
# Set the has_one relationship and accepts_nested_attributes_for. | |
has_one klass, :as => :addressable, :dependent => :destroy | |
accepts_nested_attributes_for klass | |
# Check for fields to validate | |
if options[:validate] | |
set_validators(klass, options[:validate]) | |
define_singleton_method :validate_address? do true end | |
else | |
define_singleton_method :validate_address? do false end | |
end | |
# Check for geocode in options | |
# and confirm geocoder is defined | |
if options[:geocode] && options[:geocode] == true && defined?(Geocoder) | |
set_geocoding(klass) | |
end | |
end | |
def set_validators klass, fields=[] | |
klass.to_s.titleize.constantize.class_eval do | |
fields.each do |f| | |
validates_presence_of f, :if => lambda {|a| a.addressable_type.constantize.validate_address?} | |
end | |
end | |
end | |
def set_geocoding klass | |
klass.to_s.titleize.constantize.class_eval do | |
geocoded_by :geocode_address | |
after_validation :geocode, :if => lambda {|o| o.new_record? || o.changed?} | |
end | |
end | |
# Generate a new class using Address as the superclass. | |
# Accepts a string defining the inherited type. | |
def create_address_class(class_name, &block) | |
klass = Class.new Address, &block | |
Object.const_set class_name, klass | |
end | |
end | |
end | |
end | |
end | |
# Include the modules into ActiveRecord::Base | |
ActiveRecord::Base.send(:include, Yrgoldteeth::Has::Whereabouts) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment