Module: ActiveRecord::Bitemporal::Persistence
- Includes:
- PersistenceOptionable
- Included in:
- Bitemporalize::InstanceMethods
- Defined in:
- lib/activerecord-bitemporal/bitemporal.rb
Overview
create, update, destroy に処理をフックする
Defined Under Namespace
Modules: EachAssociation, PersistenceOptionable
Instance Method Summary collapse
- #_create_record(attribute_names = self.attribute_names) ⇒ Object
-
#_find_record ⇒ Object
MEMO: Since Rails 7.1 #_find_record refers to a record with find_by!(@primary_key => id) But if @primary_key is "id", it can't refer to the intended record, so we hack it to refer to the record based on self.class.bitemporal_id_key see: https://github.com/rails/rails/blob/v7.1.0/activerecord/lib/active_record/persistence.rb#L1152-#L1171.
- #_update_row(attribute_names, attempted_action = 'update') ⇒ Object
- #destroy(force_delete: false, operated_at: nil) ⇒ Object
- #save ⇒ Object
- #save! ⇒ Object
Methods included from PersistenceOptionable
#bitemporal_at, #bitemporal_option_merge_with_association!, #force_update, #force_update?, #transaction_at, #transaction_datetime, #valid_at, #valid_date, #valid_datetime
Methods included from Optionable
#bitemporal_option, #bitemporal_option_merge!, #with_bitemporal_option
Instance Method Details
#_create_record(attribute_names = self.attribute_names) ⇒ Object
345 346 347 348 349 350 351 |
# File 'lib/activerecord-bitemporal/bitemporal.rb', line 345 def _create_record(attribute_names = self.attribute_names) bitemporal_assign_initialize_value(valid_datetime: self.valid_datetime) ActiveRecord::Bitemporal.valid_at!(self[valid_from_key]) { super() } end |
#_find_record ⇒ Object
MEMO: Since Rails 7.1 #_find_record refers to a record with find_by!(@primary_key => id) But if @primary_key is "id", it can't refer to the intended record, so we hack it to refer to the record based on self.class.bitemporal_id_key see: https://github.com/rails/rails/blob/v7.1.0/activerecord/lib/active_record/persistence.rb#L1152-#L1171
435 436 437 438 439 440 |
# File 'lib/activerecord-bitemporal/bitemporal.rb', line 435 def _find_record(*) tmp_primary_key, @primary_key = @primary_key, self.class.bitemporal_id_key super ensure @primary_key = tmp_primary_key end |
#_update_row(attribute_names, attempted_action = 'update') ⇒ Object
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 |
# File 'lib/activerecord-bitemporal/bitemporal.rb', line 367 def _update_row(attribute_names, attempted_action = 'update') current_valid_record, before_instance, after_instance = bitemporal_build_update_records(valid_datetime: self.valid_datetime, force_update: self.force_update?) # MEMO: このメソッドに来るまでに validation が発動しているので、以後 validate は考慮しなくて大丈夫 ActiveRecord::Base.transaction(requires_new: true) do current_valid_record&.update_transaction_to(current_valid_record.transaction_to) before_instance&.save_without_bitemporal_callbacks!(validate: false) # NOTE: after_instance always exists after_instance.save_without_bitemporal_callbacks!(validate: false) @previously_force_updated = self.force_update? # update 後に新しく生成したインスタンスのデータを移行する @_swapped_id_previously_was = swapped_id @_swapped_id = after_instance.swapped_id self[valid_from_key] = after_instance[valid_from_key] self[valid_to_key] = after_instance[valid_to_key] self.transaction_from = after_instance.transaction_from self.transaction_to = after_instance.transaction_to 1 # MEMO: Must return false instead of nil, if `#_update_row` failure. end || false end |
#destroy(force_delete: false, operated_at: nil) ⇒ Object
391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 |
# File 'lib/activerecord-bitemporal/bitemporal.rb', line 391 def destroy(force_delete: false, operated_at: nil) return super() if force_delete ActiveRecord::Base.transaction(requires_new: true) do @destroyed = false _run_destroy_callbacks { operated_at ||= Time.current target_datetime = valid_datetime || operated_at duplicated_instance = self.class.find_at_time(target_datetime, self.id).dup @destroyed = update_transaction_to(operated_at) @previously_force_updated = force_update? # force_update の場合は削除時の状態の履歴を残さない unless force_update? # 削除時の状態を履歴レコードとして保存する duplicated_instance[valid_to_key] = target_datetime duplicated_instance.transaction_from = operated_at duplicated_instance.save_without_bitemporal_callbacks!(validate: false) if @destroyed @_swapped_id_previously_was = swapped_id @_swapped_id = duplicated_instance.swapped_id self[valid_from_key] = duplicated_instance[valid_from_key] self[valid_to_key] = duplicated_instance[valid_to_key] self.transaction_from = duplicated_instance.transaction_from self.transaction_to = duplicated_instance.transaction_to end end } raise ActiveRecord::RecordInvalid unless @destroyed self end rescue => e @destroyed = false @_association_destroy_exception = ActiveRecord::RecordNotDestroyed.new("Failed to destroy the record: class=#{e.class}, message=#{e.}", self) @_association_destroy_exception.set_backtrace(e.backtrace) false end |
#save ⇒ Object
353 354 355 356 357 358 |
# File 'lib/activerecord-bitemporal/bitemporal.rb', line 353 def save(**) ActiveRecord::Base.transaction(requires_new: true) do self.class.where(bitemporal_id: self.id).lock!.pluck(:id) if self.id super end end |
#save! ⇒ Object
360 361 362 363 364 365 |
# File 'lib/activerecord-bitemporal/bitemporal.rb', line 360 def save!(**) ActiveRecord::Base.transaction(requires_new: true) do self.class.where(bitemporal_id: self.id).lock!.pluck(:id) if self.id super end end |