Class: SheetsDB::Worksheet::Row
- Inherits:
-
Object
- Object
- SheetsDB::Worksheet::Row
- Defined in:
- lib/sheets_db/worksheet/row.rb
Defined Under Namespace
Classes: AssociationAlreadyRegisteredError, AttributeAlreadyRegisteredError
Instance Attribute Summary collapse
-
#changed_foreign_items ⇒ Object
readonly
Returns the value of attribute changed_foreign_items.
-
#loaded_associations ⇒ Object
readonly
Returns the value of attribute loaded_associations.
-
#loaded_attributes ⇒ Object
readonly
Returns the value of attribute loaded_attributes.
-
#row_position ⇒ Object
readonly
Returns the value of attribute row_position.
-
#worksheet ⇒ Object
readonly
Returns the value of attribute worksheet.
Class Method Summary collapse
- .association_definitions ⇒ Object
- .attribute(name, type: String, multiple: false, transform: nil, column_name: nil, aliases: [], if_column_missing: nil) ⇒ Object
- .attribute_definitions ⇒ Object
- .belongs_to_association(name, from_collection:, foreign_key:, multiple: false) ⇒ Object
- .belongs_to_many(name, from_collection:, foreign_key:) ⇒ Object
- .belongs_to_one(name, from_collection:, foreign_key:) ⇒ Object
- .has_association(name, from_collection:, key:, multiple: false) ⇒ Object
- .has_many(name, from_collection:, key:) ⇒ Object
- .has_one(name, from_collection:, key:) ⇒ Object
- .inherited(subclass) ⇒ Object
- .register_attribute(name, **options) ⇒ Object
Instance Method Summary collapse
- #==(other) ⇒ Object (also: #eql?)
- #add_element_to_attribute(name, value) ⇒ Object
- #assign_next_row_position_if_not_set ⇒ Object
- #associations ⇒ Object
- #attributes ⇒ Object
- #column_names ⇒ Object
- #get_all_attributes(&block) ⇒ Object
- #get_modified_attribute(name) ⇒ Object
- #get_persisted_attribute(name) ⇒ Object
- #hash ⇒ Object
-
#initialize(worksheet:, row_position:) ⇒ Row
constructor
A new instance of Row.
- #modify_collection_attribute(name, value, remove:) ⇒ Object
- #new_row? ⇒ Boolean
- #reload! ⇒ Object
- #remove_element_from_attribute(name, value) ⇒ Object
- #reset_attributes_and_associations_cache ⇒ Object
- #save! ⇒ Object
- #save_changed_foreign_items! ⇒ Object
- #spreadsheet ⇒ Object
- #stage_attribute_modification(name, value) ⇒ Object
- #stage_attributes(new_attribute_set) ⇒ Object
- #staged_attributes ⇒ Object
- #to_hash(depth: 0) ⇒ Object
- #update_attributes!(new_attribute_set) ⇒ Object
Constructor Details
#initialize(worksheet:, row_position:) ⇒ Row
Returns a new instance of Row.
108 109 110 111 112 113 114 |
# File 'lib/sheets_db/worksheet/row.rb', line 108 def initialize(worksheet:, row_position:) @worksheet = worksheet @row_position = row_position @loaded_attributes = {} @loaded_associations = {} @changed_foreign_items = [] end |
Instance Attribute Details
#changed_foreign_items ⇒ Object (readonly)
Returns the value of attribute changed_foreign_items.
106 107 108 |
# File 'lib/sheets_db/worksheet/row.rb', line 106 def changed_foreign_items @changed_foreign_items end |
#loaded_associations ⇒ Object (readonly)
Returns the value of attribute loaded_associations.
106 107 108 |
# File 'lib/sheets_db/worksheet/row.rb', line 106 def loaded_associations @loaded_associations end |
#loaded_attributes ⇒ Object (readonly)
Returns the value of attribute loaded_attributes.
106 107 108 |
# File 'lib/sheets_db/worksheet/row.rb', line 106 def loaded_attributes @loaded_attributes end |
#row_position ⇒ Object (readonly)
Returns the value of attribute row_position.
106 107 108 |
# File 'lib/sheets_db/worksheet/row.rb', line 106 def row_position @row_position end |
#worksheet ⇒ Object (readonly)
Returns the value of attribute worksheet.
106 107 108 |
# File 'lib/sheets_db/worksheet/row.rb', line 106 def worksheet @worksheet end |
Class Method Details
.association_definitions ⇒ Object
101 102 103 |
# File 'lib/sheets_db/worksheet/row.rb', line 101 def association_definitions attribute_definitions.select { |_, value| value[:association] } end |
.attribute(name, type: String, multiple: false, transform: nil, column_name: nil, aliases: [], if_column_missing: nil) ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/sheets_db/worksheet/row.rb', line 16 def attribute(name, type: String, multiple: false, transform: nil, column_name: nil, aliases: [], if_column_missing: nil) register_attribute(name, type: type, multiple: multiple, transform: transform, column_name: (column_name || name).to_s, association: false, aliases: aliases, if_column_missing: if_column_missing) define_method(name) do begin get_modified_attribute(name) rescue KeyError get_persisted_attribute(name) end end define_method("#{name}=") do |value| stage_attribute_modification(name, value) end end |
.attribute_definitions ⇒ Object
97 98 99 |
# File 'lib/sheets_db/worksheet/row.rb', line 97 def attribute_definitions @attribute_definitions ||= {} end |
.belongs_to_association(name, from_collection:, foreign_key:, multiple: false) ⇒ Object
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/sheets_db/worksheet/row.rb', line 57 def belongs_to_association(name, from_collection:, foreign_key:, multiple: false) register_attribute(name, from_collection: from_collection, foreign_key: foreign_key, multiple: multiple, association: true) define_method(name) do @loaded_associations[name] ||= begin response = spreadsheet.find_associations_by_attribute(from_collection, foreign_key, id) multiple ? response : response.first end end define_method("#{name}=") do |value| existing_values = Array(send(name)) Array(value).each do |foreign_item| next if existing_values.delete(foreign_item) foreign_item.add_element_to_attribute(foreign_key, id) @changed_foreign_items << foreign_item end existing_values.each do |existing_foreign_item| existing_foreign_item.remove_element_from_attribute(foreign_key, id) @changed_foreign_items << existing_foreign_item end @loaded_associations[name] = value end end |
.belongs_to_many(name, from_collection:, foreign_key:) ⇒ Object
86 87 88 |
# File 'lib/sheets_db/worksheet/row.rb', line 86 def belongs_to_many(name, from_collection:, foreign_key:) belongs_to_association(name, from_collection: from_collection, foreign_key: foreign_key, multiple: true) end |
.belongs_to_one(name, from_collection:, foreign_key:) ⇒ Object
82 83 84 |
# File 'lib/sheets_db/worksheet/row.rb', line 82 def belongs_to_one(name, from_collection:, foreign_key:) belongs_to_association(name, from_collection: from_collection, foreign_key: foreign_key, multiple: false) end |
.has_association(name, from_collection:, key:, multiple: false) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/sheets_db/worksheet/row.rb', line 32 def has_association(name, from_collection:, key:, multiple: false) register_attribute(name, from_collection: from_collection, key: key, multiple: multiple, association: true) define_method(name) do @loaded_associations[name] ||= begin response = spreadsheet.find_associations_by_ids(from_collection, Array(send(key))) multiple ? response : response.first end end define_method("#{name}=") do |value| assignment_value = multiple ? value.map(&:id) : value.id send("#{key}=", assignment_value) @loaded_associations[name] = value end end |
.has_many(name, from_collection:, key:) ⇒ Object
53 54 55 |
# File 'lib/sheets_db/worksheet/row.rb', line 53 def has_many(name, from_collection:, key:) has_association(name, from_collection: from_collection, key: key, multiple: true) end |
.has_one(name, from_collection:, key:) ⇒ Object
49 50 51 |
# File 'lib/sheets_db/worksheet/row.rb', line 49 def has_one(name, from_collection:, key:) has_association(name, from_collection: from_collection, key: key, multiple: false) end |
.inherited(subclass) ⇒ Object
8 9 10 11 12 13 14 |
# File 'lib/sheets_db/worksheet/row.rb', line 8 def inherited(subclass) super subclass.instance_variable_set( :@attribute_definitions, Marshal.load(Marshal.dump(@attribute_definitions)) ) end |
.register_attribute(name, **options) ⇒ Object
90 91 92 93 94 95 |
# File 'lib/sheets_db/worksheet/row.rb', line 90 def register_attribute(name, **) if attribute_definitions.fetch(name, nil) raise AttributeAlreadyRegisteredError, name end attribute_definitions[name] = end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
249 250 251 252 253 |
# File 'lib/sheets_db/worksheet/row.rb', line 249 def ==(other) other.is_a?(self.class) && other.worksheet == worksheet && other.row_position == row_position end |
#add_element_to_attribute(name, value) ⇒ Object
164 165 166 |
# File 'lib/sheets_db/worksheet/row.rb', line 164 def add_element_to_attribute(name, value) modify_collection_attribute(name, value, remove: false) end |
#assign_next_row_position_if_not_set ⇒ Object
186 187 188 |
# File 'lib/sheets_db/worksheet/row.rb', line 186 def assign_next_row_position_if_not_set @row_position ||= worksheet.next_available_row_position end |
#associations ⇒ Object
218 219 220 221 222 |
# File 'lib/sheets_db/worksheet/row.rb', line 218 def associations get_all_attributes do || .fetch(:association, false) end end |
#attributes ⇒ Object
212 213 214 215 216 |
# File 'lib/sheets_db/worksheet/row.rb', line 212 def attributes get_all_attributes do || !.fetch(:association, false) end end |
#column_names ⇒ Object
116 117 118 |
# File 'lib/sheets_db/worksheet/row.rb', line 116 def column_names worksheet.column_names end |
#get_all_attributes(&block) ⇒ Object
224 225 226 227 228 229 |
# File 'lib/sheets_db/worksheet/row.rb', line 224 def get_all_attributes(&block) self.class.attribute_definitions.each_with_object({}) { |(name, ), memo| memo[name] = send(name) if block.call() memo } end |
#get_modified_attribute(name) ⇒ Object
124 125 126 127 |
# File 'lib/sheets_db/worksheet/row.rb', line 124 def get_modified_attribute(name) loaded_attributes.fetch(name, {}). fetch(:changed) end |
#get_persisted_attribute(name) ⇒ Object
129 130 131 132 133 |
# File 'lib/sheets_db/worksheet/row.rb', line 129 def get_persisted_attribute(name) loaded_attributes[name] ||= {} loaded_attributes[name][:original] ||= worksheet.attribute_at_row_position(name, row_position) end |
#hash ⇒ Object
257 258 259 |
# File 'lib/sheets_db/worksheet/row.rb', line 257 def hash [self.class, worksheet, row_position].hash end |
#modify_collection_attribute(name, value, remove:) ⇒ Object
151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/sheets_db/worksheet/row.rb', line 151 def modify_collection_attribute(name, value, remove:) attribute_definition = self.class.attribute_definitions.fetch(name, {}) existing_value = Array(send(name)) return if remove && !existing_value.include?(value) return if !remove && existing_value.include?(value) assignment_value = if attribute_definition[:multiple] remove ? existing_value - [value] : existing_value.concat([value]) else remove ? nil : value end send("#{name}=", assignment_value) end |
#new_row? ⇒ Boolean
120 121 122 |
# File 'lib/sheets_db/worksheet/row.rb', line 120 def new_row? row_position.nil? end |
#reload! ⇒ Object
172 173 174 175 176 |
# File 'lib/sheets_db/worksheet/row.rb', line 172 def reload! worksheet.reload! reset_attributes_and_associations_cache self end |
#remove_element_from_attribute(name, value) ⇒ Object
168 169 170 |
# File 'lib/sheets_db/worksheet/row.rb', line 168 def remove_element_from_attribute(name, value) modify_collection_attribute(name, value, remove: true) end |
#reset_attributes_and_associations_cache ⇒ Object
194 195 196 197 198 |
# File 'lib/sheets_db/worksheet/row.rb', line 194 def reset_attributes_and_associations_cache @loaded_attributes = {} @loaded_associations = {} self end |
#save! ⇒ Object
178 179 180 181 182 183 184 |
# File 'lib/sheets_db/worksheet/row.rb', line 178 def save! assign_next_row_position_if_not_set worksheet.update_attributes_at_row_position(staged_attributes, row_position: row_position) save_changed_foreign_items! reset_attributes_and_associations_cache self end |
#save_changed_foreign_items! ⇒ Object
190 191 192 |
# File 'lib/sheets_db/worksheet/row.rb', line 190 def save_changed_foreign_items! changed_foreign_items.each(&:save!) end |
#spreadsheet ⇒ Object
208 209 210 |
# File 'lib/sheets_db/worksheet/row.rb', line 208 def spreadsheet worksheet.spreadsheet end |
#stage_attribute_modification(name, value) ⇒ Object
135 136 137 138 |
# File 'lib/sheets_db/worksheet/row.rb', line 135 def stage_attribute_modification(name, value) loaded_attributes[name] ||= {} loaded_attributes[name][:changed] = value end |
#stage_attributes(new_attribute_set) ⇒ Object
140 141 142 143 144 |
# File 'lib/sheets_db/worksheet/row.rb', line 140 def stage_attributes(new_attribute_set) new_attribute_set.each do |name, value| send(:"#{name}=", value) end end |
#staged_attributes ⇒ Object
200 201 202 203 204 205 206 |
# File 'lib/sheets_db/worksheet/row.rb', line 200 def staged_attributes loaded_attributes.each_with_object({}) { |(key, value), hsh| next unless value hsh[key] = value[:changed] if value[:changed] hsh } end |
#to_hash(depth: 0) ⇒ Object
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
# File 'lib/sheets_db/worksheet/row.rb', line 231 def to_hash(depth: 0) hashed_associations = if depth > 0 Hash[ associations.map { |name, association| association_hash = if association.is_a?(Array) association.map { |item| item.to_hash(depth: depth - 1) } else association.to_hash(depth: depth - 1) end [name, association_hash] } ] else {} end attributes.merge(hashed_associations) end |
#update_attributes!(new_attribute_set) ⇒ Object
146 147 148 149 |
# File 'lib/sheets_db/worksheet/row.rb', line 146 def update_attributes!(new_attribute_set) stage_attributes(new_attribute_set) save! end |