Class: Swarm::HiveDweller
- Inherits:
-
Object
- Object
- Swarm::HiveDweller
- Extended by:
- Enumerable
- Defined in:
- lib/swarm/hive_dweller.rb
Direct Known Subclasses
Defined Under Namespace
Classes: MissingTypeError, RecordNotFoundError
Class Attribute Summary collapse
-
.associations ⇒ Object
readonly
Returns the value of attribute associations.
-
.columns ⇒ Object
readonly
Returns the value of attribute columns.
Instance Attribute Summary collapse
-
#hive ⇒ Object
readonly
Returns the value of attribute hive.
-
#id ⇒ Object
readonly
Returns the value of attribute id.
Class Method Summary collapse
- .all(hive: Hive.default, subtypes: true) ⇒ Object
- .create(hive: Hive.default, **args) ⇒ Object
- .define_getter(arg) ⇒ Object
- .define_setter(arg) ⇒ Object
- .each(hive: Hive.default, subtypes: true) ⇒ Object
- .fetch(key, hive: Hive.default) ⇒ Object
- .ids(hive: Hive.default) ⇒ Object
- .inherited(subclass) ⇒ Object
- .many_to_one(association_name, class_name: nil, key: nil) ⇒ Object
- .new_from_storage(**args) ⇒ Object
- .one_to_many(association_name, class_name: nil, foreign_key: nil) ⇒ Object
- .reify_from_hash(hsh, hive: Hive.default) ⇒ Object
- .set_columns(*args) ⇒ Object
- .storage_id_for_key(key) ⇒ Object
- .storage_type ⇒ Object
Instance Method Summary collapse
- #==(other) ⇒ Object
- #attributes ⇒ Object
- #change_attribute(key, value, record: true) ⇒ Object
- #changed? ⇒ Boolean
- #delete ⇒ Object
-
#initialize(hive: Hive.default, **args) ⇒ HiveDweller
constructor
A new instance of HiveDweller.
- #new? ⇒ Boolean
- #reload! ⇒ Object
- #save ⇒ Object
- #set_attributes(args, record_changes: true) ⇒ Object
- #storage ⇒ Object
- #storage_id ⇒ Object
- #to_hash ⇒ Object
Constructor Details
#initialize(hive: Hive.default, **args) ⇒ HiveDweller
Returns a new instance of HiveDweller.
10 11 12 13 14 |
# File 'lib/swarm/hive_dweller.rb', line 10 def initialize(hive: Hive.default, **args) @hive = hive @changed_attributes = {} set_attributes(args, record_changes: false) end |
Class Attribute Details
.associations ⇒ Object (readonly)
Returns the value of attribute associations.
97 98 99 |
# File 'lib/swarm/hive_dweller.rb', line 97 def associations @associations end |
.columns ⇒ Object (readonly)
Returns the value of attribute columns.
97 98 99 |
# File 'lib/swarm/hive_dweller.rb', line 97 def columns @columns end |
Instance Attribute Details
#hive ⇒ Object (readonly)
Returns the value of attribute hive.
8 9 10 |
# File 'lib/swarm/hive_dweller.rb', line 8 def hive @hive end |
#id ⇒ Object (readonly)
Returns the value of attribute id.
8 9 10 |
# File 'lib/swarm/hive_dweller.rb', line 8 def id @id end |
Class Method Details
.all(hive: Hive.default, subtypes: true) ⇒ Object
211 212 213 214 215 |
# File 'lib/swarm/hive_dweller.rb', line 211 def all(hive: Hive.default, subtypes: true) hive.storage.all_of_type(storage_type, subtypes: subtypes).map { |hsh| reify_from_hash(hsh.dup, hive: hive) } end |
.create(hive: Hive.default, **args) ⇒ Object
168 169 170 |
# File 'lib/swarm/hive_dweller.rb', line 168 def create(hive: Hive.default, **args) new(hive: hive, created_at: Time.now, **args).save end |
.define_getter(arg) ⇒ Object
120 121 122 123 124 125 126 127 128 |
# File 'lib/swarm/hive_dweller.rb', line 120 def define_getter(arg) define_method(arg) { val = instance_variable_get(:"@#{arg}") if /_at$/.match(arg) && val.is_a?(String) val = Time.parse(val) end val } end |
.define_setter(arg) ⇒ Object
114 115 116 117 118 |
# File 'lib/swarm/hive_dweller.rb', line 114 def define_setter(arg) define_method("#{arg}=") do |value| change_attribute(arg, value) end end |
.each(hive: Hive.default, subtypes: true) ⇒ Object
200 201 202 203 204 205 206 207 208 209 |
# File 'lib/swarm/hive_dweller.rb', line 200 def each(hive: Hive.default, subtypes: true) return to_enum(__method__, hive: hive, subtypes: subtypes) unless block_given? ids(hive: hive).each do |id| object = fetch(id, hive: hive) if (subtypes && object.is_a?(self)) || object.instance_of?(self) yield object end end end |
.fetch(key, hive: Hive.default) ⇒ Object
191 192 193 194 |
# File 'lib/swarm/hive_dweller.rb', line 191 def fetch(key, hive: Hive.default) hsh = hive.storage[storage_id_for_key(key)].dup reify_from_hash(hsh, hive: hive) end |
.ids(hive: Hive.default) ⇒ Object
196 197 198 |
# File 'lib/swarm/hive_dweller.rb', line 196 def ids(hive: Hive.default) hive.storage.ids_for_type(storage_type) end |
.inherited(subclass) ⇒ Object
99 100 101 102 103 104 |
# File 'lib/swarm/hive_dweller.rb', line 99 def inherited(subclass) super subclass.instance_variable_set(:@columns, []) subclass.instance_variable_set(:@associations, {}) subclass.set_columns :updated_at, :created_at end |
.many_to_one(association_name, class_name: nil, key: nil) ⇒ Object
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/swarm/hive_dweller.rb', line 151 def many_to_one(association_name, class_name: nil, key: nil) define_method(association_name) do memo = instance_variable_get(:"@#{association_name}") memo || begin key ||= :"#{association_name}_id" associated_id = send(key) return nil unless associated_id klass = Swarm::Support.constantize((class_name || association_name).to_s) instance_variable_set(:"@#{association_name}", klass.fetch(associated_id, hive: hive)) end end @associations[association_name] = { type: :many_to_one, class_name: class_name || association_name, key: key } end |
.new_from_storage(**args) ⇒ Object
184 185 186 187 188 189 |
# File 'lib/swarm/hive_dweller.rb', line 184 def new_from_storage(**args) id = args.delete(:id) new(**args).tap { |instance| instance.instance_variable_set(:@id, id) } end |
.one_to_many(association_name, class_name: nil, foreign_key: nil) ⇒ Object
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/swarm/hive_dweller.rb', line 130 def one_to_many(association_name, class_name: nil, foreign_key: nil) define_method(association_name) do memo = instance_variable_get(:"@#{association_name}") memo || begin associations = hive.storage.load_associations( association_name, owner: self, class_name: class_name || association_name, foreign_key: foreign_key ) entities = associations.map { |association| self.class.reify_from_hash(association, hive: hive) } instance_variable_set(:"@#{association_name}", entities) end end define_method(:"add_to_#{association_name}") do |associated| hive.storage.add_association( association_name, associated, owner: self, class_name: class_name || association_name, foreign_key: foreign_key ) end @associations[association_name] = { type: :one_to_many, class_name: class_name || association_name, foreign_key: foreign_key } end |
.reify_from_hash(hsh, hive: Hive.default) ⇒ Object
217 218 219 220 221 222 223 224 |
# File 'lib/swarm/hive_dweller.rb', line 217 def reify_from_hash(hsh, hive: Hive.default) Support.symbolize_keys!(hsh) raise MissingTypeError, hsh.inspect unless hsh[:type] Swarm::Support.constantize(hsh.delete(:type)).new_from_storage( **hsh.merge(hive: hive) ) end |
.set_columns(*args) ⇒ Object
106 107 108 109 110 111 112 |
# File 'lib/swarm/hive_dweller.rb', line 106 def set_columns(*args) args.each do |arg| define_setter(arg) define_getter(arg) end @columns |= args end |
.storage_id_for_key(key) ⇒ Object
176 177 178 179 180 181 182 |
# File 'lib/swarm/hive_dweller.rb', line 176 def storage_id_for_key(key) if key.match(/^#{storage_type}:/) key else "#{storage_type}:#{key}" end end |
.storage_type ⇒ Object
172 173 174 |
# File 'lib/swarm/hive_dweller.rb', line 172 def storage_type name.split("::").last end |
Instance Method Details
#==(other) ⇒ Object
42 43 44 |
# File 'lib/swarm/hive_dweller.rb', line 42 def ==(other) other.is_a?(self.class) && other.to_hash == to_hash end |
#attributes ⇒ Object
68 69 70 71 72 |
# File 'lib/swarm/hive_dweller.rb', line 68 def attributes self.class.columns.each_with_object({}) { |col_name, hsh| hsh[col_name.to_sym] = send(:"#{col_name}") } end |
#change_attribute(key, value, record: true) ⇒ Object
35 36 37 38 39 40 |
# File 'lib/swarm/hive_dweller.rb', line 35 def change_attribute(key, value, record: true) if record @changed_attributes[key] = [send(key), value] end instance_variable_set(:"@#{key}", value) end |
#changed? ⇒ Boolean
20 21 22 |
# File 'lib/swarm/hive_dweller.rb', line 20 def changed? !@changed_attributes.empty? end |
#delete ⇒ Object
54 55 56 57 |
# File 'lib/swarm/hive_dweller.rb', line 54 def delete storage.delete(storage_id) self end |
#new? ⇒ Boolean
16 17 18 |
# File 'lib/swarm/hive_dweller.rb', line 16 def new? id.nil? end |
#reload! ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/swarm/hive_dweller.rb', line 82 def reload! hsh = hive.storage[storage_id] self.class.columns.each do |column| instance_variable_set(:"@#{column}", hsh[column.to_s]) end self.class.associations.each_key do |name| instance_variable_set(:"@#{name}", nil) end @changed_attributes = {} self end |
#save ⇒ Object
59 60 61 62 63 64 65 66 |
# File 'lib/swarm/hive_dweller.rb', line 59 def save if new? || changed? @id ||= Swarm::Support. storage[storage_id] = to_hash.merge(updated_at: Time.now) reload! end self end |
#set_attributes(args, record_changes: true) ⇒ Object
24 25 26 27 28 29 30 31 32 33 |
# File 'lib/swarm/hive_dweller.rb', line 24 def set_attributes(args, record_changes: true) unknown_arguments = args.keys - self.class.columns unless unknown_arguments.empty? raise ArgumentError, "unknown keywords: #{unknown_arguments.join(', ')}" end args.each do |key, value| change_attribute(key, value, record: record_changes) end end |
#storage ⇒ Object
50 51 52 |
# File 'lib/swarm/hive_dweller.rb', line 50 def storage @hive.storage end |
#storage_id ⇒ Object
46 47 48 |
# File 'lib/swarm/hive_dweller.rb', line 46 def storage_id self.class.storage_id_for_key(id) end |
#to_hash ⇒ Object
74 75 76 77 78 79 80 |
# File 'lib/swarm/hive_dweller.rb', line 74 def to_hash hsh = { id: id, type: self.class.name } hsh.merge(attributes) end |