Class: ViewModel::ActiveRecord::UpdateData
- Inherits:
-
Object
- Object
- ViewModel::ActiveRecord::UpdateData
- Defined in:
- lib/view_model/active_record/update_data.rb
Defined Under Namespace
Modules: Schemas
Instance Attribute Summary collapse
-
#associations ⇒ Object
Returns the value of attribute associations.
-
#attributes ⇒ Object
Returns the value of attribute attributes.
-
#metadata ⇒ Object
Returns the value of attribute metadata.
-
#referenced_associations ⇒ Object
Returns the value of attribute referenced_associations.
-
#viewmodel_class ⇒ Object
Returns the value of attribute viewmodel_class.
Class Method Summary collapse
- .check_duplicate_updates(updates, type:) ⇒ Object
- .empty_update_for(viewmodel) ⇒ Object
- .parse_associated(association_data, blame_reference, valid_reference_keys, child_hash) ⇒ Object
- .parse_hashes(root_subtree_hashes, referenced_subtree_hashes = {}) ⇒ Object
Instance Method Summary collapse
- #[](name) ⇒ Object
- #build_preload_specs(association_data, updates) ⇒ Object
- #has_key?(name) ⇒ Boolean
-
#initialize(viewmodel_class, metadata, hash_data, valid_reference_keys) ⇒ UpdateData
constructor
A new instance of UpdateData.
- #merge_preload_specs(association_data, specs) ⇒ Object
-
#preload_dependencies ⇒ Object
Updates in terms of activerecord associations: used for preloading subtree associations necessary to perform update.
-
#to_sequence(name, value) ⇒ Object
Produce a sequence of update datas for a given association update value, in the spirit of Array.wrap.
- #viewmodel_reference ⇒ Object
Constructor Details
#initialize(viewmodel_class, metadata, hash_data, valid_reference_keys) ⇒ UpdateData
Returns a new instance of UpdateData.
567 568 569 570 571 572 573 574 575 |
# File 'lib/view_model/active_record/update_data.rb', line 567 def initialize(viewmodel_class, , hash_data, valid_reference_keys) self.viewmodel_class = viewmodel_class self. = self.attributes = {} self.associations = {} self.referenced_associations = {} parse(hash_data, valid_reference_keys) end |
Instance Attribute Details
#associations ⇒ Object
Returns the value of attribute associations.
396 397 398 |
# File 'lib/view_model/active_record/update_data.rb', line 396 def associations @associations end |
#attributes ⇒ Object
Returns the value of attribute attributes.
396 397 398 |
# File 'lib/view_model/active_record/update_data.rb', line 396 def attributes @attributes end |
#metadata ⇒ Object
Returns the value of attribute metadata.
396 397 398 |
# File 'lib/view_model/active_record/update_data.rb', line 396 def @metadata end |
#referenced_associations ⇒ Object
Returns the value of attribute referenced_associations.
396 397 398 |
# File 'lib/view_model/active_record/update_data.rb', line 396 def referenced_associations @referenced_associations end |
#viewmodel_class ⇒ Object
Returns the value of attribute viewmodel_class.
396 397 398 |
# File 'lib/view_model/active_record/update_data.rb', line 396 def viewmodel_class @viewmodel_class end |
Class Method Details
.check_duplicate_updates(updates, type:) ⇒ Object
559 560 561 562 563 564 565 |
# File 'lib/view_model/active_record/update_data.rb', line 559 def self.check_duplicate_updates(updates, type:) # Ensure that no root is referred to more than once duplicates = updates.duplicates_by { |upd| upd.viewmodel_reference if upd.id } if duplicates.present? raise ViewModel::DeserializationError::DuplicateNodes.new(type, duplicates.keys) end end |
.empty_update_for(viewmodel) ⇒ Object
577 578 579 580 |
# File 'lib/view_model/active_record/update_data.rb', line 577 def self.empty_update_for(viewmodel) = ViewModel::Metadata.new(viewmodel.id, viewmodel.view_name, viewmodel.class.schema_version, false) self.new(viewmodel.class, , {}, []) end |
.parse_associated(association_data, blame_reference, valid_reference_keys, child_hash) ⇒ Object
641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 |
# File 'lib/view_model/active_record/update_data.rb', line 641 def self.parse_associated(association_data, blame_reference, valid_reference_keys, child_hash) = ViewModel.(child_hash) child_viewmodel_class = association_data.viewmodel_class_for_name(.view_name) if child_viewmodel_class.nil? raise ViewModel::DeserializationError::InvalidAssociationType.new( association_data.association_name.to_s, .view_name, blame_reference) end verify_schema_version!(child_viewmodel_class, .schema_version, .id) if .schema_version UpdateData.new(child_viewmodel_class, , child_hash, valid_reference_keys) end |
.parse_hashes(root_subtree_hashes, referenced_subtree_hashes = {}) ⇒ Object
525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 |
# File 'lib/view_model/active_record/update_data.rb', line 525 def self.parse_hashes(root_subtree_hashes, referenced_subtree_hashes = {}) valid_reference_keys = referenced_subtree_hashes.keys.to_set valid_reference_keys.each do |ref| unless ref.is_a?(String) raise ViewModel::DeserializationError::InvalidSyntax.new("Invalid reference string: #{ref}") end end # Construct root UpdateData root_updates = root_subtree_hashes.map do |subtree_hash| = ViewModel.(subtree_hash) viewmodel_class = ViewModel::Registry.for_view_name(.view_name) verify_schema_version!(viewmodel_class, .schema_version, .id) if .schema_version UpdateData.new(viewmodel_class, , subtree_hash, valid_reference_keys) end # Ensure that no root is referred to more than once check_duplicate_updates(root_updates, type: 'root') # Construct reference UpdateData referenced_updates = referenced_subtree_hashes.transform_values do |subtree_hash| = ViewModel.(subtree_hash) viewmodel_class = ViewModel::Registry.for_view_name(.view_name) verify_schema_version!(viewmodel_class, .schema_version, .id) if .schema_version UpdateData.new(viewmodel_class, , subtree_hash, valid_reference_keys) end check_duplicate_updates(referenced_updates.values, type: 'reference') return root_updates, referenced_updates end |
Instance Method Details
#[](name) ⇒ Object
503 504 505 506 507 508 509 510 511 512 |
# File 'lib/view_model/active_record/update_data.rb', line 503 def [](name) case name when :id id when :_type viewmodel_class.view_name else attributes.fetch(name) { associations.fetch(name) { referenced_associations.fetch(name) } } end end |
#build_preload_specs(association_data, updates) ⇒ Object
597 598 599 600 601 602 603 604 605 606 607 |
# File 'lib/view_model/active_record/update_data.rb', line 597 def build_preload_specs(association_data, updates) if association_data.polymorphic? updates.map do |update_data| target_model = update_data.viewmodel_class.model_class DeepPreloader::PolymorphicSpec.new( target_model.name => update_data.preload_dependencies) end else updates.map { |update_data| update_data.preload_dependencies } end end |
#has_key?(name) ⇒ Boolean
514 515 516 517 518 519 520 521 |
# File 'lib/view_model/active_record/update_data.rb', line 514 def has_key?(name) case name when :id, :_type true else attributes.has_key?(name) || associations.has_key?(name) || referenced_associations.has_key?(name) end end |
#merge_preload_specs(association_data, specs) ⇒ Object
609 610 611 612 |
# File 'lib/view_model/active_record/update_data.rb', line 609 def merge_preload_specs(association_data, specs) empty = association_data.polymorphic? ? DeepPreloader::PolymorphicSpec.new : DeepPreloader::Spec.new specs.inject(empty) { |acc, spec| acc.merge!(spec) } end |
#preload_dependencies ⇒ Object
Updates in terms of activerecord associations: used for preloading subtree associations necessary to perform update.
616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 |
# File 'lib/view_model/active_record/update_data.rb', line 616 def preload_dependencies deps = {} associations.merge(referenced_associations).each do |assoc_name, reference| association_data = self.viewmodel_class._association_data(assoc_name) preload_specs = build_preload_specs(association_data, to_sequence(assoc_name, reference)) referenced_deps = merge_preload_specs(association_data, preload_specs) if association_data.through? referenced_deps = DeepPreloader::Spec.new(association_data.indirect_reflection.name.to_s => referenced_deps) end deps[association_data.direct_reflection.name.to_s] = referenced_deps end DeepPreloader::Spec.new(deps) end |
#to_sequence(name, value) ⇒ Object
Produce a sequence of update datas for a given association update value, in the spirit of Array.wrap.
583 584 585 586 587 588 589 590 591 592 593 594 595 |
# File 'lib/view_model/active_record/update_data.rb', line 583 def to_sequence(name, value) association_data = self.viewmodel_class._association_data(name) case when value.nil? [] when association_data.referenced? [] when association_data.collection? # nested, because of referenced? check above value.update_datas else [value] end end |