Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reference only handling #196

Merged
merged 3 commits into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/iknow_view_models/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module IknowViewModels
VERSION = '3.11.0'
VERSION = '3.12.0'
end
4 changes: 4 additions & 0 deletions lib/view_model/active_record/update_data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,10 @@ def has_key?(name)

delegate :new?, :child_update?, :auto_child_update?, to: :metadata

def reference_only?
attributes.empty? && associations.empty? && referenced_associations.empty?
end

def self.parse_hashes(root_subtree_hashes, referenced_subtree_hashes = {})
valid_reference_keys = referenced_subtree_hashes.keys.to_set

Expand Down
15 changes: 12 additions & 3 deletions lib/view_model/active_record/update_operation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ def built?
@built
end

def reference_only?
update_data.reference_only? && reparent_to.nil? && reposition_to.nil?
end

# Evaluate a built update tree, applying and saving changes to the models.
def run!(deserialize_context:)
raise ViewModel::DeserializationError::Internal.new('Internal error: UpdateOperation run before build') unless built?
Expand Down Expand Up @@ -123,9 +127,14 @@ def run!(deserialize_context:)
end
end

# validate
deserialize_context.run_callback(ViewModel::Callbacks::Hook::BeforeValidate, viewmodel)
viewmodel.validate!
# If a request makes no assertions about the model, we don't demand
# that the current state of the model is valid. This permits making
# edits to other models that refer to this model when this model is
# invalid.
unless reference_only? && !viewmodel.new_model?
deserialize_context.run_callback(ViewModel::Callbacks::Hook::BeforeValidate, viewmodel)
viewmodel.validate!
end

# Save if the model has been altered. Covers not only models with
# view changes but also lock version assertions.
Expand Down
12 changes: 11 additions & 1 deletion lib/view_model/migration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,18 @@ class ViewModel::Migration
require 'view_model/migration/one_way_error'
require 'view_model/migration/unspecified_version_error'

REFERENCE_ONLY_KEYS = [
ViewModel::TYPE_ATTRIBUTE,
ViewModel::ID_ATTRIBUTE,
ViewModel::VERSION_ATTRIBUTE,
].freeze

def up(view, _references)
raise ViewModel::Migration::OneWayError.new(view[ViewModel::TYPE_ATTRIBUTE], :up)
# Only a reference-only view may be (trivially) migrated up without an
# explicit migration.
if (view.keys - REFERENCE_ONLY_KEYS).present?
raise ViewModel::Migration::OneWayError.new(view[ViewModel::TYPE_ATTRIBUTE], :up)
end
end

def down(view, _references)
Expand Down
Loading