Sha256: 872701c27dea60b19247f0befcd5b250036ffa64b38287afbca5b33d4799fa40

Contents?: true

Size: 1.51 KB

Versions: 1

Compression:

Stored size: 1.51 KB

Contents

module HasDefaultAssociation
  extend ActiveSupport::Concern
  
  included do
    # no-op 
  end

  module ClassMethods
    # Declare default associations for ActiveRecord models.
    # 
    #   # Build a new association on demand
    #   belongs_to :address
    #   has_default_association :address 
    #
    #   # Build a custom assocation on demand
    #   belongs_to :address
    #   has_default_association :address do |model|
    #     Address.new(:name => model.full_name)
    #   end
    # 
    # =Options
    # 
    # +eager+ will instantiate a default assocation when a
    # model is initialized.
    # 
    def has_default_association *names, &default_proc
      opts = names.extract_options!
      opts.assert_valid_keys(:eager)
      
      names.each do |name|
        create_default_association(name, default_proc)
        add_default_association_callback(name) if opts[:eager]
      end
    end
    
    alias_method :has_default_associations, :has_default_association 
    
    private
    
    def create_default_association name, default_proc
      setter = :"#{name}="
      
      default_proc ||= proc do |model| 
        model.association(name).build
      end
      
      define_method(name) do
        target = association(name).load_target
        return target unless target.blank?
        
        self.send setter, default_proc.call(self)
      end
    end
    
    def add_default_association_callback name
      after_initialize do
        self.send(name) unless persisted?
      end
    end
    
  end
  
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
has_default_association-0.0.1 lib/has_default_association.rb