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
- #new? ⇒ Boolean
-
#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.
569 570 571 572 573 574 575 576 577 |
# File 'lib/view_model/active_record/update_data.rb', line 569 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
561 562 563 564 565 566 567 |
# File 'lib/view_model/active_record/update_data.rb', line 561 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
579 580 581 582 |
# File 'lib/view_model/active_record/update_data.rb', line 579 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
643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 |
# File 'lib/view_model/active_record/update_data.rb', line 643 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
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 558 559 |
# File 'lib/view_model/active_record/update_data.rb', line 527 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
599 600 601 602 603 604 605 606 607 608 609 |
# File 'lib/view_model/active_record/update_data.rb', line 599 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
611 612 613 614 |
# File 'lib/view_model/active_record/update_data.rb', line 611 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 |
#new? ⇒ Boolean
523 524 525 |
# File 'lib/view_model/active_record/update_data.rb', line 523 def new? id.nil? || .new? end |
#preload_dependencies ⇒ Object
Updates in terms of activerecord associations: used for preloading subtree associations necessary to perform update.
618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 |
# File 'lib/view_model/active_record/update_data.rb', line 618 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.
585 586 587 588 589 590 591 592 593 594 595 596 597 |
# File 'lib/view_model/active_record/update_data.rb', line 585 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 |