module LazyRecord::Collections

Set up in-memory one-to-many relationships between objects

Constants

COLLECTION_MODULE_NAME
NESTED_ATTRS_MODULE_NAME

Public Instance Methods

_add_collection_methods(*collections) click to toggle source
# File lib/lazy_record/collections.rb, line 71
def _add_collection_methods(*collections)
  _add_to_collections(*collections)
  _define_collections
  _define_collection_counts_to_s
  _collections.each do |collection, options|
    _define_collection_getter(collection, options)
    _define_collection_setter(collection, options)
    _define_collection_counter(collection)
  end
end
_add_to_collections(*collections) click to toggle source
# File lib/lazy_record/collections.rb, line 39
def _add_to_collections(*collections)
  options = collections.extract_options!
  collections.each do |collection|
    class_name = options[:class_name] || collection.to_s.classify
    _collections[collection.to_sym] = { class_name: class_name }
  end
end
_collections() click to toggle source
# File lib/lazy_record/collections.rb, line 47
def _collections
  @_collections ||= {}
end
_define_collection_counter(collection) click to toggle source
# File lib/lazy_record/collections.rb, line 31
    def _define_collection_counter(collection)
      module_eval <<-RUBY, __FILE__, __LINE__ + 1
        def #{collection}_count
          #{collection}.count
        end
      RUBY
    end
_define_collection_counts_to_s() click to toggle source
# File lib/lazy_record/collections.rb, line 51
def _define_collection_counts_to_s
  define_method(:collection_counts_to_s) do
    collections.map do |collection, _options|
      "#{collection}_count: #{stringify_value(send("#{collection}_count"))}"
    end
  end
  private :collection_counts_to_s
end
_define_collection_getter(collection, options) click to toggle source
# File lib/lazy_record/collections.rb, line 13
    def _define_collection_getter(collection, options)
      klass = lazy_const_get_one_level_back(options[:class_name]).call
      module_eval <<-RUBY, __FILE__, __LINE__ + 1
        def #{collection}
          @#{collection} ||= Relation.new(klass: #{klass})
        end
      RUBY
    end
_define_collection_setter(collection, options) click to toggle source
# File lib/lazy_record/collections.rb, line 22
    def _define_collection_setter(collection, options)
      klass = lazy_const_get_one_level_back(options[:class_name]).call
      module_eval <<-RUBY, __FILE__, __LINE__ + 1
        def #{collection}=(coll)
          @#{collection} = Relation.new(klass: #{klass}, collection: coll)
        end
      RUBY
    end
_define_collections() click to toggle source
# File lib/lazy_record/collections.rb, line 60
def _define_collections
  collections = _collections
  define_method(:collections) { collections }
end
_no_collection_error(collection) click to toggle source
# File lib/lazy_record/collections.rb, line 107
def _no_collection_error(collection)
  klass = collection.to_s.classify
  klass = _collections.find { |_col, opt| opt[:class_name] == klass }.first
  suggestion = klass ? ". Did you mean #{klass}?" : ''
  msg = "#{self} doesn't have a collection of #{collection}#{suggestion}"
  raise ArgumentError, msg, caller
end
define_collection_attributes_setter(collection, options) click to toggle source
# File lib/lazy_record/collections.rb, line 82
    def define_collection_attributes_setter(collection, options)
      class_name = lazy_const_get_one_level_back(
        options.fetch(:class_name)
      ).call
      module_eval <<-RUBY, __FILE__, __LINE__ + 1
        def #{collection}_attributes=(collection_attributes)
          collection_attributes.values.each do |attributes|
            #{collection} << #{class_name}.new(attributes)
          end
        end
      RUBY
    end
lr_accepts_nested_attributes_for(*collections) click to toggle source
# File lib/lazy_record/collections.rb, line 95
def lr_accepts_nested_attributes_for(*collections)
  include mod = get_or_set_mod(COLLECTION_MODULE_NAME)
  mod.extend(Collections)
  mod.module_eval do
    collections.each do |collection|
      options = _collections[collection]
      _no_collection_error(collection) unless options
      define_collection_attributes_setter(collection, options)
    end
  end
end
lr_has_many(*collections) click to toggle source
# File lib/lazy_record/collections.rb, line 65
def lr_has_many(*collections)
  include mod = get_or_set_mod(COLLECTION_MODULE_NAME)
  mod.extend(Collections)
  mod.module_eval { _add_collection_methods(*collections) }
end