Skip to content

Commit 6240136

Browse files
authored
Configurable polymorphic class name resolution (#79)
1 parent a7e3430 commit 6240136

File tree

8 files changed

+36
-8
lines changed

8 files changed

+36
-8
lines changed

CHANGELOG.MD

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
# Changelog
2+
3+
## Subroutine 4.2.0
4+
5+
If you are using polymorphic association fields, you can now customize how Subroutine
6+
resolves those class names to a ruby class by setting a global callable/lambda/proc:
7+
8+
```ruby
9+
::Subroutine.constantize_polymorphic_class_name = ->(class_name) do
10+
class_name.classify.constantize
11+
end
12+
```
13+
114
## Subroutine 4.1.4
215

316
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`.
@@ -16,7 +29,7 @@ to string and re-parsing to a Time object. This fixes issues with losing usec pr
1629

1730
## Subroutine 4.1.0
1831

19-
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.
32+
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.
2033

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

3851
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`.
3952

53+
Polymorphic association fields now resolve class names via `klass.camelize.constantize`,
54+
previously was `klass.classify.constantize`.
55+
4056
## Subroutine 3.0
4157

4258
Add support for Rails 6.1. Drop support for Rails 6.0 and lower.

gemfiles/rails_6.1.gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
PATH
22
remote: ..
33
specs:
4-
subroutine (4.1.5)
4+
subroutine (4.2.0)
55
activemodel (>= 6.1)
66
activesupport (>= 6.1)
77

gemfiles/rails_7.0.gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
PATH
22
remote: ..
33
specs:
4-
subroutine (4.1.5)
4+
subroutine (4.2.0)
55
activemodel (>= 6.1)
66
activesupport (>= 6.1)
77

gemfiles/rails_7.1.gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
PATH
22
remote: ..
33
specs:
4-
subroutine (4.1.5)
4+
subroutine (4.2.0)
55
activemodel (>= 6.1)
66
activesupport (>= 6.1)
77

gemfiles/rails_7.2.gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
PATH
22
remote: ..
33
specs:
4-
subroutine (4.1.5)
4+
subroutine (4.2.0)
55
activemodel (>= 6.1)
66
activesupport (>= 6.1)
77

lib/subroutine.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,18 @@
1616

1717
module Subroutine
1818

19+
# Used by polymorphic association fields to resolve the class name to a ruby class
20+
def self.constantize_polymorphic_class_name(class_name)
21+
return @constantize_polymorphic_class_name.call(class_name) if defined?(@constantize_polymorphic_class_name)
22+
23+
class_name.camelize.constantize
24+
end
25+
26+
# When you need to customize how a polymorphic class name is resolved, you can set this callable/lambda/proc
27+
def self.constantize_polymorphic_class_name=(callable)
28+
@constantize_polymorphic_class_name = callable
29+
end
30+
1931
def self.include_defaults_in_params=(bool)
2032
@include_defaults_in_params = !!bool
2133
end

lib/subroutine/association_fields.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ def fetch_association_instance(config)
177177
get_field(config.foreign_type_method)
178178
end
179179

180-
klass = klass.camelize.constantize if klass.is_a?(String)
180+
klass = Subroutine.constantize_polymorphic_class_name(klass) if klass.is_a?(String)
181181
return nil unless klass
182182

183183
foreign_key = config.foreign_key_method

lib/subroutine/version.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
module Subroutine
44

55
MAJOR = 4
6-
MINOR = 1
7-
PATCH = 5
6+
MINOR = 2
7+
PATCH = 0
88
PRE = nil
99

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

0 commit comments

Comments
 (0)