Module: ActiveType::VirtualAttributes

Extended by:
ActiveSupport::Concern
Included in:
Object, Record
Defined in:
lib/active_type/virtual_attributes.rb

Defined Under Namespace

Modules: ClassMethods, Serialization Classes: Builder, VirtualColumn

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.attribute_for_inspect(value) ⇒ Object



137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/active_type/virtual_attributes.rb', line 137

def self.attribute_for_inspect(value)
  if value.is_a?(String) && value.length > 50
    "#{value[0, 50]}...".inspect
  elsif value.is_a?(Date) || value.is_a?(Time)
    %("#{value.to_formatted_s(:db)}")
  elsif value.is_a?(Array) && value.size > 10
    inspected = value.first(10).inspect
    %(#{inspected[0...-1]}, ...])
  else
    value.inspect
  end
end

.deep_dup(hash) ⇒ Object



129
130
131
132
133
134
135
# File 'lib/active_type/virtual_attributes.rb', line 129

def self.deep_dup(hash)
  result = hash.dup
  result.each do |key, value|
    result[key] = value.dup if value.duplicable?
  end
  result
end

Instance Method Details

#[](name) ⇒ Object



209
210
211
# File 'lib/active_type/virtual_attributes.rb', line 209

def [](name)
  read_existing_virtual_attribute(name) { super }
end

#[]=(name, value) ⇒ Object



221
222
223
# File 'lib/active_type/virtual_attributes.rb', line 221

def []=(name, value)
  write_existing_virtual_attribute(name, value) { super }
end

#_read_attribute(name) ⇒ Object



213
214
215
# File 'lib/active_type/virtual_attributes.rb', line 213

def _read_attribute(name)
  read_existing_virtual_attribute(name) { super }
end

#_write_attribute(name, value) ⇒ Object



225
226
227
# File 'lib/active_type/virtual_attributes.rb', line 225

def _write_attribute(name, value)
  write_existing_virtual_attribute(name, value) { super }
end

#attribute_changed?(attr) ⇒ Boolean

Returns:

  • (Boolean)


257
258
259
260
261
262
263
264
# File 'lib/active_type/virtual_attributes.rb', line 257

def attribute_changed?(attr, **)
  attr = attr.to_s
  if virtual_attributes.key?(attr)
    virtual_attributes_were[attr] != send(attr)
  else
    super
  end
end

#attributesObject



233
234
235
236
237
# File 'lib/active_type/virtual_attributes.rb', line 233

def attributes
  self.class._virtual_column_names.each_with_object(super) do |name, attrs|
    attrs[name] = read_virtual_attribute(name)
  end
end

#attributes_for_inspectObject



294
295
296
# File 'lib/active_type/virtual_attributes.rb', line 294

def attributes_for_inspect
  self.class.attributes_for_inspect == :all ? attributes.keys : self.class.attributes_for_inspect
end

#changed?Boolean

Returns:

  • (Boolean)


239
240
241
# File 'lib/active_type/virtual_attributes.rb', line 239

def changed?
  self.class._virtual_column_names.any? { |attr| virtual_attributes_were[attr] != send(attr) } || super
end

#changed_for_autosave?Boolean

Returns:

  • (Boolean)


243
244
245
# File 'lib/active_type/virtual_attributes.rb', line 243

def changed_for_autosave?
  changed? || super
end

#changesObject



247
248
249
250
251
252
253
254
255
# File 'lib/active_type/virtual_attributes.rb', line 247

def changes
  changes = self.class._virtual_column_names.each_with_object({}) do |attr, changes|
    current_value = send(attr)
    previous_value = virtual_attributes_were[attr]
    changes[attr] = [previous_value, current_value] if  previous_value != current_value
  end

  super.merge(changes)
end

#changes_appliedObject



266
267
268
269
270
271
272
273
# File 'lib/active_type/virtual_attributes.rb', line 266

def changes_applied
  super

  virtual_attributes.each do |attr, _|
    value = read_virtual_attribute(attr)
    virtual_attributes_were[attr] = value.duplicable? ? value.clone : value
  end
end

#full_inspectObject



302
303
304
# File 'lib/active_type/virtual_attributes.rb', line 302

def full_inspect
  inspect_with_attributes(attributes.keys)
end

#initialize_dup(other) ⇒ Object



173
174
175
176
177
178
179
# File 'lib/active_type/virtual_attributes.rb', line 173

def initialize_dup(other)
  @virtual_attributes_cache = {}
  @virtual_attributes = VirtualAttributes.deep_dup(virtual_attributes)
  @virtual_attributes_were = VirtualAttributes.deep_dup(virtual_attributes_were)

  super
end

#inspectObject



298
299
300
# File 'lib/active_type/virtual_attributes.rb', line 298

def inspect
  inspect_with_attributes(attributes_for_inspect)
end

#inspect_with_attributes(attribute_names) ⇒ Object

Returns the contents of the record as a nicely formatted string.



307
308
309
310
311
312
313
314
315
316
# File 'lib/active_type/virtual_attributes.rb', line 307

def inspect_with_attributes(attribute_names)
  inspection = attribute_names.collect do |name|
    name = name.to_s
    if attributes.key?(name)
      value = attributes[name]
      "#{name}: #{VirtualAttributes.attribute_for_inspect(value)}"
    end
  end.compact.sort.join(", ")
  "#<#{self.class} #{inspection}>"
end

#read_attribute(name) ⇒ Object



217
218
219
# File 'lib/active_type/virtual_attributes.rb', line 217

def read_attribute(name)
  read_existing_virtual_attribute(name) { super }
end

#read_existing_virtual_attribute(name, &block_when_not_virtual) ⇒ Object



193
194
195
196
197
198
199
# File 'lib/active_type/virtual_attributes.rb', line 193

def read_existing_virtual_attribute(name, &block_when_not_virtual)
  if self.singleton_class._has_virtual_column?(name)
    read_virtual_attribute(name)
  else
    yield
  end
end

#read_virtual_attribute(name) ⇒ Object



275
276
277
278
279
280
281
282
283
284
285
286
# File 'lib/active_type/virtual_attributes.rb', line 275

def read_virtual_attribute(name)
  name = name.to_s
  if virtual_attributes_cache.has_key?(name)
    virtual_attributes_cache[name]
  else
    virtual_attributes_cache[name] = begin
      virtual_column = self.singleton_class._virtual_column(name)
      raw_value = virtual_attributes.fetch(name) { virtual_column.default_value(self) }
      virtual_column.type_cast(raw_value)
    end
  end
end

#virtual_attributesObject



181
182
183
# File 'lib/active_type/virtual_attributes.rb', line 181

def virtual_attributes
  @virtual_attributes ||= {}
end

#virtual_attributes_cacheObject



189
190
191
# File 'lib/active_type/virtual_attributes.rb', line 189

def virtual_attributes_cache
  @virtual_attributes_cache ||= {}
end

#virtual_attributes_wereObject



185
186
187
# File 'lib/active_type/virtual_attributes.rb', line 185

def virtual_attributes_were
  @virtual_attributes_were ||= {}
end

#write_attribute(name, value) ⇒ Object



229
230
231
# File 'lib/active_type/virtual_attributes.rb', line 229

def write_attribute(name, value)
  write_existing_virtual_attribute(name, value) { super }
end

#write_existing_virtual_attribute(name, value, &block_when_not_virtual) ⇒ Object



201
202
203
204
205
206
207
# File 'lib/active_type/virtual_attributes.rb', line 201

def write_existing_virtual_attribute(name, value, &block_when_not_virtual)
  if self.singleton_class._has_virtual_column?(name)
    write_virtual_attribute(name, value)
  else
    yield
  end
end

#write_virtual_attribute(name, value) ⇒ Object



288
289
290
291
292
# File 'lib/active_type/virtual_attributes.rb', line 288

def write_virtual_attribute(name, value)
  name = name.to_s
  virtual_attributes_cache.delete(name)
  virtual_attributes[name] = value
end