Module: LazyRecord::Collections

Includes:
Nesting
Defined in:
lib/lazy_record/collections.rb

Overview

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

Constant Summary collapse

COLLECTION_MODULE_NAME =
:Collections
NESTED_ATTRS_MODULE_NAME =
:NestedAttributes

Instance Method Summary collapse

Methods included from Nesting

#apply_nesting, #apply_nesting_one_level_back, #lazy_const_get, #lazy_const_get_one_level_back

Instance Method Details

#_add_collection_methods(*collections) ⇒ Object



71
72
73
74
75
76
77
78
79
80
# 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) ⇒ Object



39
40
41
42
43
44
45
# 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

#_collectionsObject



47
48
49
# File 'lib/lazy_record/collections.rb', line 47

def _collections
  @_collections ||= {}
end

#_define_collection_counter(collection) ⇒ Object



31
32
33
34
35
36
37
# File 'lib/lazy_record/collections.rb', line 31

def _define_collection_counter(collection)
  module_eval "    def \#{collection}_count\n      \#{collection}.count\n    end\n  RUBY\nend\n", __FILE__, __LINE__ + 1

#_define_collection_counts_to_sObject



51
52
53
54
55
56
57
58
# 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) ⇒ Object



13
14
15
16
17
18
19
20
# 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 "    def \#{collection}\n      @\#{collection} ||= Relation.new(klass: \#{klass})\n    end\n  RUBY\nend\n", __FILE__, __LINE__ + 1

#_define_collection_setter(collection, options) ⇒ Object



22
23
24
25
26
27
28
29
# 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 "    def \#{collection}=(coll)\n      @\#{collection} = Relation.new(klass: \#{klass}, collection: coll)\n    end\n  RUBY\nend\n", __FILE__, __LINE__ + 1

#_define_collectionsObject



60
61
62
63
# File 'lib/lazy_record/collections.rb', line 60

def _define_collections
  collections = _collections
  define_method(:collections) { collections }
end

#_no_collection_error(collection) ⇒ Object

Raises:

  • (ArgumentError)


107
108
109
110
111
112
113
# 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) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
# 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 "    def \#{collection}_attributes=(collection_attributes)\n      collection_attributes.values.each do |attributes|\n        \#{collection} << \#{class_name}.new(attributes)\n      end\n    end\n  RUBY\nend\n", __FILE__, __LINE__ + 1

#lr_accepts_nested_attributes_for(*collections) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
# 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) ⇒ Object



65
66
67
68
69
# 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