Skip to content

Commit

Permalink
Revert "fix accepts_nested_attributes_for triggering db connection …
Browse files Browse the repository at this point in the history
…in rails 7.2 (DmitryTsepelev#194)"

This reverts commit bec6015.
  • Loading branch information
evaniainbrooks committed Nov 29, 2024
1 parent 2a35d18 commit 80883ac
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 56 deletions.
36 changes: 12 additions & 24 deletions lib/store_model/nested_attributes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,6 @@ def self.included(base) # :nodoc:
end

module ClassMethods # :nodoc:
# gather storemodel attribute types on the class-level
def store_model_attribute_types
@store_model_attribute_types ||= {}
end

# add storemodel type of attribute if it is storemodel type
def attribute(name, type = nil, **)
store_model_attribute_types[name.to_s] = type if type.is_a?(Types::Base)
super
end

# Enables handling of nested StoreModel::Model attributes
#
# @param associations [Array] list of associations and options to define attributes, for example:
Expand Down Expand Up @@ -49,7 +38,8 @@ def accepts_nested_attributes_for(*attributes)
options = attributes.extract_options!

attributes.each do |attribute|
if nested_attribute_type(attribute).is_a?(Types::Base)
case nested_attribute_type(attribute)
when Types::OneBase, Types::ManyBase
options.reverse_merge!(allow_destroy: false, update_only: false)
define_store_model_attr_accessors(attribute, options)
else
Expand All @@ -60,19 +50,17 @@ def accepts_nested_attributes_for(*attributes)

private

# when db connection is not available, it becomes impossible to read attributes types from
# ActiveModel::AttributeRegistration::ClassMethods.attribute_types, because activerecord
# overrides _default_attributes and triggers db connection.
# for activerecord model only use attribute_types if it has db connected
#
# @param attribute [String, Symbol]
# @return [StoreModel::Types::Base, nil]
# If attribute defined in ActiveRecord model but you dont yet have database created
# you cannot access attribute types.
# To handle this case, we can use ActiveRecord::Attributes 'attributes_to_define_after_schema_loads'
# which stores information about custom defined attributes.
# See ActiveRecord::Attributes#atribute
# If #accepts_nested_attributes_for is used inside active model instance
# schema is not required to determine attribute type so we can still use attribute_types
# If schema loaded the attribute_types already populated and we can safely use it
# See ActiveRecord::ModelSchema#load_schema!
def nested_attribute_type(attribute)
if self < ActiveRecord::Base && !schema_loaded?
store_model_attribute_types[attribute.to_s]
else
attribute_types[attribute.to_s]
end
attribute_types[attribute.to_s]
end

def define_store_model_attr_accessors(attribute, options) # rubocop:disable Metrics/MethodLength
Expand Down
1 change: 0 additions & 1 deletion lib/store_model/types.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# frozen_string_literal: true

require "store_model/types/polymorphic_helper"
require "store_model/types/base"

require "store_model/types/one_base"
require "store_model/types/one"
Expand Down
25 changes: 0 additions & 25 deletions lib/store_model/types/base.rb

This file was deleted.

18 changes: 16 additions & 2 deletions lib/store_model/types/many_base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,18 @@

module StoreModel
module Types
# Implements type for handling an array of StoreModel::Model
class ManyBase < Base
# Implements ActiveModel::Type::Value type for handling an array of
# StoreModel::Model
class ManyBase < ActiveModel::Type::Value
attr_reader :model_klass

# Returns type
#
# @return [Symbol]
def type
raise NotImplementedError
end

# Casts +value+ from DB or user to StoreModel::Model instance
#
# @param value [Object] a value to cast
Expand Down Expand Up @@ -60,6 +70,10 @@ def cast_model_type_value(_value)
raise NotImplementedError
end

def raise_cast_error(_value)
raise NotImplementedError
end

private

# rubocop:disable Style/RescueModifier
Expand Down
17 changes: 15 additions & 2 deletions lib/store_model/types/one_base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,17 @@

module StoreModel
module Types
# Implements type for handling an instance of StoreModel::Model
class OneBase < Base
# Implements ActiveModel::Type::Value type for handling an instance of StoreModel::Model
class OneBase < ActiveModel::Type::Value
attr_reader :model_klass

# Returns type
#
# @return [Symbol]
def type
raise NotImplementedError
end

# Casts +value+ from DB or user to StoreModel::Model instance
#
# @param value [Object] a value to cast
Expand All @@ -27,6 +36,10 @@ def changed_in_place?(raw_old_value, new_value)

protected

def raise_cast_error(_value)
raise NotImplementedError
end

def model_instance(_value)
raise NotImplementedError
end
Expand Down
3 changes: 1 addition & 2 deletions spec/store_model/nested_attributes_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -535,8 +535,7 @@ def self.name
end
end

it { expect { subject }.not_to(raise_error) }
it { expect(subject.instance_methods).to(include(:suppliers_attributes=)) }
it { expect { subject }.to raise_error(ActiveRecord::StatementInvalid) }
end
end
end
Expand Down

0 comments on commit 80883ac

Please sign in to comment.