Skip to content

Configurable polymorphic class name resolution #79

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

Merged
merged 3 commits into from
Dec 19, 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
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
Loading