Class: VirtualBox::AbstractModel Abstract
- Inherits:
-
Object
- Object
- VirtualBox::AbstractModel
- Includes:
- AbstractModel::Attributable, AbstractModel::Dirty, AbstractModel::Relatable, AbstractModel::Validatable
- Defined in:
- lib/virtualbox/abstract_model.rb,
lib/virtualbox/abstract_model/dirty.rb,
lib/virtualbox/abstract_model/relatable.rb,
lib/virtualbox/abstract_model/validatable.rb,
lib/virtualbox/abstract_model/attributable.rb
Overview
This class is abstract.
AbstractModel is the base class used for most of virtualbox's classes. It provides convenient ActiveRecord-style model behavior to subclasses.
Direct Known Subclasses
AttachedDevice, ForwardedPort, Global, Image, Media, Nic, SharedFolder, StorageController, USB, VM
Class Method Summary
- + (Object) reload!
- + (Boolean) reload? Returns whether or not the class should be reloaded.
- + (Object) reloaded!
Instance Method Summary
- - (Object) destroy(*args) Destroys the model.
- - (Object) errors Returns the errors for a model.
- - (Object) existing_record! Explicitly sets the model to not be a new record.
- - (Object) inspect Creates a human-readable format for this model.
- - (Boolean) lazy_attribute?(*args) Overriding Attributable#lazy_attribute? to always return false for new records, since new records shouldn't load lazy data.
- - (Boolean) lazy_relationship?(*args) Overriding Relatable#lazy_relationship? to always return false for new records, since new records shouldn't load lazy data.
- - (Object) new_record! Explicitly resets the model to a new record.
- - (Boolean) new_record? Returns a boolean denoting if the record is new or existing.
- - (Object) populate_attributes(attribs, opts = {}) Sets the initial attributes from a hash.
- - (Object) populate_relationship(name, data) Populates a single relationship with the given data.
- - (Object) populate_relationships(data) Loads and populates the relationships with the given data.
- - (Object) reload! Signals to the class that it should be reloaded.
- - (Object) save(*args) Saves the model attributes and relationships.
- - (Object) save_attribute(key, value, *args) Saves a single attribute of the model.
- - (Object) set_relationship(key, value) Overwrites Relatable#set_relationship to set the dirty state of the relationship.
- - (Object) validate(*args) Validates the model and relationships.
- - (Object) write_attribute(name, value) Overwrites Attributable#write_attribute to set the dirty state of the written attribute.
Methods included from AbstractModel::Attributable
#attributes, #has_attribute?, included, #loaded_attribute?, #read_attribute, #readonly_attribute?
Methods included from AbstractModel::Dirty
#changed?, #changes, #clear_dirty!, #ignore_dirty, #method_missing, #set_dirty!
Methods included from AbstractModel::Relatable
#destroy_relationship, #destroy_relationships, #has_relationship?, included, #loaded_relationship?, #read_relationship, #relationship_data, #save_relationship, #save_relationships
Methods included from AbstractModel::Validatable
#add_error, #clear_errors, #valid?, #validates_presence_of
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class VirtualBox::AbstractModel::Dirty
Class Method Details
+ (Object) reload!
25 26 27 |
# File 'lib/virtualbox/abstract_model.rb', line 25 def reload! @_reload = true end |
+ (Boolean) reload?
Returns whether or not the class should be reloaded.
21 22 23 |
# File 'lib/virtualbox/abstract_model.rb', line 21 def reload? !!@_reload end |
+ (Object) reloaded!
29 30 31 |
# File 'lib/virtualbox/abstract_model.rb', line 29 def reloaded! @_reload = false end |
Instance Method Details
- (Object) destroy(*args)
Destroys the model. The exact behaviour of this method is expected to be defined on the subclasses. This method on AbstractModel simply propagates the destroy to the dependent relationships. For more information on relationships, see Relatable.
202 203 204 205 206 207 |
# File 'lib/virtualbox/abstract_model.rb', line 202 def destroy(*args) # Destroy dependent relationships self.class.relationships.each do |name, | destroy_relationship(name, *args) if [:dependent] == :destroy end end |
- (Object) errors
Returns the errors for a model.
66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/virtualbox/abstract_model.rb', line 66 def errors error_hash = super self.class.relationships.each do |name, | next unless && [:klass].respond_to?(:errors_for_relationship) relationship_errors = [:klass].errors_for_relationship(self, relationship_data[name]) error_hash.merge!({ :foos => relationship_errors }) if relationship_errors.length > 0 end error_hash end |
- (Object) existing_record!
Explicitly sets the model to not be a new record. If you're using this method outside of virtualbox library core, you should really be asking yourself "why?"
61 62 63 |
# File 'lib/virtualbox/abstract_model.rb', line 61 def existing_record! @new_record = false end |
- (Object) inspect
Creates a human-readable format for this model. This method overrides the
default #<class>
syntax since this doesn't work well for AbstractModels.
Instead, it abbreviates it, instead showing all the attributes and their
values, and ...
for relationships. For attributes which are themselves
AbstractModels, it shows the class name to avoid extremely verbose inspections
and infinite loops.
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 |
# File 'lib/virtualbox/abstract_model.rb', line 215 def inspect values = [] self.class.attributes.each do |name, | value = read_attribute(name) value = if value.is_a?(AbstractModel) "#<#{value.class.name}>" else value.inspect end values.push("#{name.inspect}=#{value}") end self.class.relationships.each do |name, | values.push("#{name.inspect}=...") end "#<#{self.class} #{values.sort.join(", ")}>".strip end |
- (Boolean) lazy_attribute?(*args)
Overriding Attributable#lazy_attribute? to always return false for new records, since new records shouldn't load lazy data.
127 128 129 130 |
# File 'lib/virtualbox/abstract_model.rb', line 127 def lazy_attribute?(*args) return false if new_record? super end |
- (Boolean) lazy_relationship?(*args)
Overriding Relatable#lazy_relationship? to always return false for new records, since new records shouldn't load lazy data.
134 135 136 137 |
# File 'lib/virtualbox/abstract_model.rb', line 134 def lazy_relationship?(*args) return false if new_record? super end |
- (Object) new_record!
Explicitly resets the model to a new record. If you're using this method outside of virtualbox library core, you should really be asking yourself "why?"
54 55 56 |
# File 'lib/virtualbox/abstract_model.rb', line 54 def new_record! @new_record = true end |
- (Boolean) new_record?
Returns a boolean denoting if the record is new or existing. This method is provided for subclasses to use to differentiate between creating a new object or saving an existing one. An example of this is HardDrive#save which will create a new hard drive if it didn't previously exist, or save an old one if it did exist.
46 47 48 49 |
# File 'lib/virtualbox/abstract_model.rb', line 46 def new_record? new_record! if @new_record.nil? @new_record end |
- (Object) populate_attributes(attribs, opts = {})
Sets the initial attributes from a hash. This method is meant to be used once to initially setup the attributes. It is not a mass-assignment method for updating attributes.
This method does not affect dirtiness, but also does not clear it. This means that if you call populate_attributes, the same attributes that were dirty before the call will be dirty after the call (but no more and no less). This distinction is important because most subclasses of AbstractModel only save changed attributes, and ignore unchanged attributes. Attempting to change attributes through this method will cause them to not be saved, which is surely unexpected behaviour for most users.
Calling this method will also cause the model to assume that it is not a new record (see #new_record?).
154 155 156 157 158 159 160 161 162 163 |
# File 'lib/virtualbox/abstract_model.rb', line 154 def populate_attributes(attribs, opts={}) ignore_dirty do super(attribs) populate_relationships(attribs) unless opts[:ignore_relationships] end # No longer a new record existing_record! end |
- (Object) populate_relationship(name, data)
Populates a single relationship with the given data.
178 179 180 181 |
# File 'lib/virtualbox/abstract_model.rb', line 178 def populate_relationship(name, data) existing_record! ignore_dirty { super } end |
- (Object) populate_relationships(data)
Loads and populates the relationships with the given data. This method is meant to be used once to initially setup the relatoinships.
This methods does not affect dirtiness, but also does not clear it.
Calling this method will also cuase the model to assume that it is not a new record (see #new_record?)
172 173 174 175 |
# File 'lib/virtualbox/abstract_model.rb', line 172 def populate_relationships(data) existing_record! ignore_dirty { super } end |
- (Object) reload!
Signals to the class that it should be reloaded. This simply toggles a boolean value to true. It is up to the subclass to implement functionality around it. See reload?
37 38 39 |
# File 'lib/virtualbox/abstract_model.rb', line 37 def reload! self.class.reload! end |
- (Object) save(*args)
Saves the model attributes and relationships.
The method can be passed any arbitrary arguments, which are implementation specific (see VM#save, which does this).
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/virtualbox/abstract_model.rb', line 98 def save(*args) # Go through changed attributes and call save_attribute for # those only changes.each do |key, values| save_attribute(key, values[1], *args) end # Go through and only save the loaded relationships, since # only those would be modified. self.class.relationships.each do |name, | next if lazy_relationship?(name) && !loaded_relationship?(name) save_relationship(name, *args) end # No longer a new record @new_record = false end |
- (Object) save_attribute(key, value, *args)
Saves a single attribute of the model. This method on the abstract model does nothing on its own, and is expected to be overridden by any subclasses.
This method clears the dirty status of the attribute.
121 122 123 |
# File 'lib/virtualbox/abstract_model.rb', line 121 def save_attribute(key, value, *args) clear_dirty!(key) end |
- (Object) set_relationship(key, value)
Overwrites Relatable#set_relationship to set the dirty state of the relationship. See Dirty#set_dirty! as well.
192 193 194 195 196 |
# File 'lib/virtualbox/abstract_model.rb', line 192 def set_relationship(key, value) existing = relationship_data[key] new_value = super set_dirty!(key, existing, new_value) end |
- (Object) validate(*args)
Validates the model and relationships.
80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/virtualbox/abstract_model.rb', line 80 def validate(*args) # First clear all previous errors clear_errors # Then do the validations failed = false self.class.relationships.each do |name, | next unless && [:klass].respond_to?(:validate_relationship) failed = true if ![:klass].validate_relationship(self, relationship_data[name], *args) end return !failed end |
- (Object) write_attribute(name, value)
Overwrites Attributable#write_attribute to set the dirty state of the written attribute. See Dirty#set_dirty! as well.
185 186 187 188 |
# File 'lib/virtualbox/abstract_model.rb', line 185 def write_attribute(name, value) set_dirty!(name, read_attribute(name), value) unless lazy_attribute?(name) && !loaded_attribute?(name) super end |