Skip to content

Commit

Permalink
Configurable polymorphic class name resolution (#79)
Browse files Browse the repository at this point in the history
  • Loading branch information
fusion2004 authored Dec 19, 2024
1 parent a7e3430 commit 6240136
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 8 deletions.
18 changes: 17 additions & 1 deletion CHANGELOG.MD
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
# Changelog

## Subroutine 4.2.0

If you are using polymorphic association fields, you can now customize how Subroutine
resolves those class names to a ruby class by setting a global callable/lambda/proc:

```ruby
::Subroutine.constantize_polymorphic_class_name = ->(class_name) do
class_name.classify.constantize
end
```

## Subroutine 4.1.4

Fields using the time/timestamp/datetime caster will now default back to the old behavior, and use a `precision:` option to opt-in to the new behavior introduced in `v4.1.1`.
Expand All @@ -16,7 +29,7 @@ to string and re-parsing to a Time object. This fixes issues with losing usec pr

## Subroutine 4.1.0

A field can no opt out of the natural assignment behavior of ActiveSupport::HashWithIndifferentAccess. Top level param groups are still accessible via indifferent access but if a field sets the `bypass_indifferent_assignment` option to `true` the HashWithIndifferentAccess assignment behavior will be bypassed in favor of direct Hash-like assignment.
A field can now opt out of the natural assignment behavior of ActiveSupport::HashWithIndifferentAccess. Top level param groups are still accessible via indifferent access but if a field sets the `bypass_indifferent_assignment` option to `true` the HashWithIndifferentAccess assignment behavior will be bypassed in favor of direct Hash-like assignment.

```ruby
class MyOp < Subroutine::Op
Expand All @@ -37,6 +50,9 @@ The `Subroutine::Fields` module now contains a class_attribute that allows the a

Removed all usage of `ungrouped` params and refactored the storage of grouped params. Params are now stored in either the provided group or the defaults group and accessed via provided_params, params, default_params, and params_with_defaults. Grouped params are accessed the same way but with the group name prefixed eg. `my_private_default_params`.

Polymorphic association fields now resolve class names via `klass.camelize.constantize`,
previously was `klass.classify.constantize`.

## Subroutine 3.0

Add support for Rails 6.1. Drop support for Rails 6.0 and lower.
Expand Down
2 changes: 1 addition & 1 deletion gemfiles/rails_6.1.gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: ..
specs:
subroutine (4.1.5)
subroutine (4.2.0)
activemodel (>= 6.1)
activesupport (>= 6.1)

Expand Down
2 changes: 1 addition & 1 deletion gemfiles/rails_7.0.gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: ..
specs:
subroutine (4.1.5)
subroutine (4.2.0)
activemodel (>= 6.1)
activesupport (>= 6.1)

Expand Down
2 changes: 1 addition & 1 deletion gemfiles/rails_7.1.gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: ..
specs:
subroutine (4.1.5)
subroutine (4.2.0)
activemodel (>= 6.1)
activesupport (>= 6.1)

Expand Down
2 changes: 1 addition & 1 deletion gemfiles/rails_7.2.gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: ..
specs:
subroutine (4.1.5)
subroutine (4.2.0)
activemodel (>= 6.1)
activesupport (>= 6.1)

Expand Down
12 changes: 12 additions & 0 deletions lib/subroutine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@

module Subroutine

# Used by polymorphic association fields to resolve the class name to a ruby class
def self.constantize_polymorphic_class_name(class_name)
return @constantize_polymorphic_class_name.call(class_name) if defined?(@constantize_polymorphic_class_name)

class_name.camelize.constantize
end

# When you need to customize how a polymorphic class name is resolved, you can set this callable/lambda/proc
def self.constantize_polymorphic_class_name=(callable)
@constantize_polymorphic_class_name = callable
end

def self.include_defaults_in_params=(bool)
@include_defaults_in_params = !!bool
end
Expand Down
2 changes: 1 addition & 1 deletion lib/subroutine/association_fields.rb
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ def fetch_association_instance(config)
get_field(config.foreign_type_method)
end

klass = klass.camelize.constantize if klass.is_a?(String)
klass = Subroutine.constantize_polymorphic_class_name(klass) if klass.is_a?(String)
return nil unless klass

foreign_key = config.foreign_key_method
Expand Down
4 changes: 2 additions & 2 deletions lib/subroutine/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
module Subroutine

MAJOR = 4
MINOR = 1
PATCH = 5
MINOR = 2
PATCH = 0
PRE = nil

VERSION = [MAJOR, MINOR, PATCH, PRE].compact.join(".")
Expand Down

0 comments on commit 6240136

Please sign in to comment.