Module: Airtable::ORM::Persistence
Constant Summary collapse
- BATCH_SIZE =
10- MAX_FIND_MANY_IDS =
500
Instance Method Summary collapse
-
#apply_response_fields(data) ⇒ Object
Apply response fields from a create, update, or batch operation.
-
#assign_persistence_state(id:, created_at:, persisted:) ⇒ Object
Assign persistence metadata (id, created_at, persisted flag).
- #client ⇒ Object
-
#create_record ⇒ Object
Create a new record via API.
-
#destroy ⇒ Object
Destroy the record.
-
#destroyed? ⇒ Boolean
Check if this record has been destroyed.
-
#handle_persistence_response(response) ⇒ Object
Handle API response from create/update operations.
-
#initialize(**attributes) ⇒ Object
Initialize a record with symbol attributes Usage: new(email: "test@example.com", first_name: "John").
-
#new_record? ⇒ Boolean
Check if this is a new record (not yet saved).
-
#persisted? ⇒ Boolean
Check if this record has been saved.
-
#previously_new_record? ⇒ Boolean
Check if this record was new before the last save.
-
#reload ⇒ Object
Reload the record from the API.
-
#save(validate: true) ⇒ Object
Save the record (create or update).
-
#save!(validate: true) ⇒ Object
Save the record, raising an error if it fails.
-
#update(attributes) ⇒ Object
Update attributes and save.
-
#update!(attributes) ⇒ Object
Update attributes and save, raising an error if it fails.
-
#update_record ⇒ Object
Update only changed fields via PATCH.
Instance Method Details
#apply_response_fields(data) ⇒ Object
Apply response fields from a create, update, or batch operation. Uses changes_applied (not clear_changes_information) so after_save callbacks can inspect previous_changes / saved_change_to_*? methods.
304 305 306 307 308 309 310 311 312 313 314 315 316 317 |
# File 'lib/airtable/orm/persistence.rb', line 304 def apply_response_fields(data) @previously_new_record = new_record? data = data.with_indifferent_access symbol_attrs = self.class.fields_to_symbol_attributes(data[:fields]) symbol_attrs.each { |key, value| write_raw_attribute(key, value) } assign_persistence_state( id: data[:id], created_at: data[:createdTime] ? Time.iso8601(data[:createdTime].to_s) : nil, persisted: true ) changes_applied end |
#assign_persistence_state(id:, created_at:, persisted:) ⇒ Object
Assign persistence metadata (id, created_at, persisted flag)
295 296 297 298 299 |
# File 'lib/airtable/orm/persistence.rb', line 295 def assign_persistence_state(id:, created_at:, persisted:) @id = id @created_at = created_at @persisted = persisted end |
#client ⇒ Object
319 320 321 |
# File 'lib/airtable/orm/persistence.rb', line 319 def client self.class.client end |
#create_record ⇒ Object
Create a new record via API
335 336 337 338 339 340 341 342 |
# File 'lib/airtable/orm/persistence.rb', line 335 def create_record run_callbacks :create do body = { fields: fields_for_create } response = client.connection.post(self.class.api_path, body) handle_persistence_response(response) true end end |
#destroy ⇒ Object
Destroy the record
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 |
# File 'lib/airtable/orm/persistence.rb', line 259 def destroy raise Airtable::ORM::RecordNotDestroyed, "Cannot destroy a new record" if new_record? run_callbacks :destroy do response = client.connection.delete(self.class.api_path(id)) parsed_response = response.body if response.success? @persisted = false @destroyed = true freeze self else Airtable::ORM::Http::Client.raise_api_error(response.status, parsed_response) end end end |
#destroyed? ⇒ Boolean
Check if this record has been destroyed
210 211 212 |
# File 'lib/airtable/orm/persistence.rb', line 210 def destroyed? @destroyed == true end |
#handle_persistence_response(response) ⇒ Object
Handle API response from create/update operations
324 325 326 327 328 329 330 331 332 |
# File 'lib/airtable/orm/persistence.rb', line 324 def handle_persistence_response(response) parsed = response.body if response.success? apply_response_fields(parsed) else Airtable::ORM::Http::Client.raise_api_error(response.status, parsed) end end |
#initialize(**attributes) ⇒ Object
Initialize a record with symbol attributes Usage: new(email: "test@example.com", first_name: "John")
184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/airtable/orm/persistence.rb', line 184 def initialize(**attributes) # Initialize as a new record (not persisted, not destroyed) @id = nil @created_at = nil @persisted = false @destroyed = false @previously_new_record = false # Initialize ActiveModel::Attributes super() # Set attributes using ActiveModel's assign_attributes assign_attributes(attributes) if attributes.present? end |
#new_record? ⇒ Boolean
Check if this is a new record (not yet saved)
200 201 202 |
# File 'lib/airtable/orm/persistence.rb', line 200 def new_record? !@persisted && !@destroyed end |
#persisted? ⇒ Boolean
Check if this record has been saved
205 206 207 |
# File 'lib/airtable/orm/persistence.rb', line 205 def persisted? @persisted == true end |
#previously_new_record? ⇒ Boolean
Check if this record was new before the last save
215 216 217 |
# File 'lib/airtable/orm/persistence.rb', line 215 def previously_new_record? @previously_new_record == true end |
#reload ⇒ Object
Reload the record from the API
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 |
# File 'lib/airtable/orm/persistence.rb', line 278 def reload raise Airtable::ORM::RecordNotPersisted, "Cannot reload a new record" if new_record? fresh_record = self.class.find(id) # Copy attributes from fresh record using raw attribute access self.class.attribute_types.each_key do |name| write_raw_attribute(name.to_sym, fresh_record.read_raw_attribute(name.to_sym)) end @created_at = fresh_record.created_at clear_changes_information self end |
#save(validate: true) ⇒ Object
Save the record (create or update)
220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/airtable/orm/persistence.rb', line 220 def save(validate: true) return false if validate && invalid? result = run_callbacks(:save) do new_record? ? create_record : update_record end result != false rescue Airtable::ORM::ApiError false end |
#save!(validate: true) ⇒ Object
Save the record, raising an error if it fails. Unlike save, lets ApiError propagate with full error details.
234 235 236 237 238 239 240 241 242 243 244 |
# File 'lib/airtable/orm/persistence.rb', line 234 def save!(validate: true) raise Airtable::ORM::RecordInvalid, self if validate && invalid? result = run_callbacks(:save) do new_record? ? create_record : update_record end raise Airtable::ORM::RecordNotSaved, "Failed to save the record" if result == false true end |
#update(attributes) ⇒ Object
Update attributes and save
247 248 249 250 |
# File 'lib/airtable/orm/persistence.rb', line 247 def update(attributes) assign_attributes(attributes) save end |
#update!(attributes) ⇒ Object
Update attributes and save, raising an error if it fails
253 254 255 256 |
# File 'lib/airtable/orm/persistence.rb', line 253 def update!(attributes) assign_attributes(attributes) save! end |
#update_record ⇒ Object
Update only changed fields via PATCH. Fields changed TO nil are sent (to clear them in Airtable); unchanged nil fields are not sent.
346 347 348 349 350 351 352 353 354 355 356 357 358 |
# File 'lib/airtable/orm/persistence.rb', line 346 def update_record unless changed? clear_changes_information return true end run_callbacks :update do body = { fields: fields_for_update } response = client.connection.patch(self.class.api_path(id), body) handle_persistence_response(response) true end end |