Class: SheetsDB::Worksheet::Row
- Inherits:
-
Object
- Object
- SheetsDB::Worksheet::Row
show all
- Defined in:
- lib/sheets_db/worksheet/row.rb
Defined Under Namespace
Classes: AssociationAlreadyRegisteredError, AttributeAlreadyRegisteredError
Class Attribute Summary collapse
Instance Attribute Summary collapse
Class Method Summary
collapse
-
.attribute(name, type: String, multiple: false, transform: 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
Constructor Details
#initialize(worksheet:, row_position:) ⇒ Row
Returns a new instance of Row.
104
105
106
107
108
109
110
|
# File 'lib/sheets_db/worksheet/row.rb', line 104
def initialize(worksheet:, row_position:)
@worksheet = worksheet
@row_position = row_position
@loaded_attributes = {}
@loaded_associations = {}
@changed_foreign_items = []
end
|
Class Attribute Details
.association_definitions ⇒ Object
Returns the value of attribute association_definitions.
8
9
10
|
# File 'lib/sheets_db/worksheet/row.rb', line 8
def association_definitions
@association_definitions
end
|
Instance Attribute Details
#changed_foreign_items ⇒ Object
Returns the value of attribute changed_foreign_items.
102
103
104
|
# File 'lib/sheets_db/worksheet/row.rb', line 102
def changed_foreign_items
@changed_foreign_items
end
|
#loaded_associations ⇒ Object
Returns the value of attribute loaded_associations.
102
103
104
|
# File 'lib/sheets_db/worksheet/row.rb', line 102
def loaded_associations
@loaded_associations
end
|
#loaded_attributes ⇒ Object
Returns the value of attribute loaded_attributes.
102
103
104
|
# File 'lib/sheets_db/worksheet/row.rb', line 102
def loaded_attributes
@loaded_attributes
end
|
#row_position ⇒ Object
Returns the value of attribute row_position.
102
103
104
|
# File 'lib/sheets_db/worksheet/row.rb', line 102
def row_position
@row_position
end
|
#worksheet ⇒ Object
Returns the value of attribute worksheet.
102
103
104
|
# File 'lib/sheets_db/worksheet/row.rb', line 102
def worksheet
@worksheet
end
|
Class Method Details
.attribute(name, type: String, multiple: false, transform: 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)
register_attribute(name, type: type, multiple: multiple, transform: transform, association: false)
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
10
11
12
13
14
|
# File 'lib/sheets_db/worksheet/row.rb', line 10
def inherited(subclass)
super
subclass.instance_variable_set(:@attribute_definitions, @attribute_definitions)
subclass.instance_variable_set(:@association_definitions, @association_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, **options)
if attribute_definitions.fetch(name, nil)
raise AttributeAlreadyRegisteredError, name
end
attribute_definitions[name] = options
end
|
Instance Method Details
#add_element_to_attribute(name, value) ⇒ Object
141
142
143
|
# File 'lib/sheets_db/worksheet/row.rb', line 141
def add_element_to_attribute(name, value)
modify_collection_attribute(name, value, remove: false)
end
|
#associations ⇒ Object
189
190
191
192
193
|
# File 'lib/sheets_db/worksheet/row.rb', line 189
def associations
get_all_attributes do |options|
options.fetch(:association, false)
end
end
|
#attributes ⇒ Object
183
184
185
186
187
|
# File 'lib/sheets_db/worksheet/row.rb', line 183
def attributes
get_all_attributes do |options|
!options.fetch(:association, false)
end
end
|
#get_all_attributes(&block) ⇒ Object
195
196
197
198
199
200
|
# File 'lib/sheets_db/worksheet/row.rb', line 195
def get_all_attributes(&block)
self.class.attribute_definitions.each_with_object({}) { |(name, options), memo|
memo[name] = send(name) if block.call(options)
memo
}
end
|
#get_modified_attribute(name) ⇒ Object
112
113
114
115
|
# File 'lib/sheets_db/worksheet/row.rb', line 112
def get_modified_attribute(name)
loaded_attributes.fetch(name, {}).
fetch(:changed)
end
|
#get_persisted_attribute(name) ⇒ Object
117
118
119
120
121
|
# File 'lib/sheets_db/worksheet/row.rb', line 117
def get_persisted_attribute(name)
loaded_attributes[name] ||= {}
loaded_attributes[name][:original] ||=
worksheet.attribute_at_row_position(name, row_position)
end
|
#modify_collection_attribute(name, value, remove:) ⇒ Object
128
129
130
131
132
133
134
135
136
137
138
139
|
# File 'lib/sheets_db/worksheet/row.rb', line 128
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
|
#reload! ⇒ Object
149
150
151
152
|
# File 'lib/sheets_db/worksheet/row.rb', line 149
def reload!
worksheet.reload!
reset_attributes_and_associations_cache
end
|
#remove_element_from_attribute(name, value) ⇒ Object
145
146
147
|
# File 'lib/sheets_db/worksheet/row.rb', line 145
def remove_element_from_attribute(name, value)
modify_collection_attribute(name, value, remove: true)
end
|
#reset_attributes_and_associations_cache ⇒ Object
166
167
168
169
|
# File 'lib/sheets_db/worksheet/row.rb', line 166
def reset_attributes_and_associations_cache
@loaded_attributes = {}
@loaded_associations = {}
end
|
#save! ⇒ Object
154
155
156
157
158
|
# File 'lib/sheets_db/worksheet/row.rb', line 154
def save!
worksheet.update_attributes_at_row_position(staged_attributes, row_position: row_position)
save_changed_foreign_items!
reset_attributes_and_associations_cache
end
|
#save_changed_foreign_items! ⇒ Object
160
161
162
163
164
|
# File 'lib/sheets_db/worksheet/row.rb', line 160
def save_changed_foreign_items!
changed_foreign_items.each do |foreign_item|
foreign_item.save!
end
end
|
#spreadsheet ⇒ Object
179
180
181
|
# File 'lib/sheets_db/worksheet/row.rb', line 179
def spreadsheet
worksheet.spreadsheet
end
|
#stage_attribute_modification(name, value) ⇒ Object
123
124
125
126
|
# File 'lib/sheets_db/worksheet/row.rb', line 123
def stage_attribute_modification(name, value)
loaded_attributes[name] ||= {}
loaded_attributes[name][:changed] = value
end
|
#staged_attributes ⇒ Object
171
172
173
174
175
176
177
|
# File 'lib/sheets_db/worksheet/row.rb', line 171
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
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
|
# File 'lib/sheets_db/worksheet/row.rb', line 202
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
|