action_form 0.5.1 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4d93e3e3b61abdc0ceb51759d16f352819d45ccbe1667998484473934da50ff2
4
- data.tar.gz: 5f35ee9cc4f39a5ae05eaa445f3f230deef097089bfc88853acab530241ec0f9
3
+ metadata.gz: b0f29b8e09e9fd398ad1442b60c537cabe004f8f53ea208b904e3c924e922972
4
+ data.tar.gz: 7329122a3632b906e1ddc1c1d6ac7d0de4814270372682d10184677fdba3f8b7
5
5
  SHA512:
6
- metadata.gz: cbfb9b48199cda2dc7ca78c368c58ecf3628fe5ef508f37e1dc7bfe4a4d3c9a6506ad210552c20e1575e6c50dfc3bac2d08512e3c4d70e9b296dfd9f2819b708
7
- data.tar.gz: c71f8a0fc1c8aa5967f25d5f56702da3bccfa246ca0eae947d80403b80dcb0d46ce75e0a076b41976750e37bccdf4b1b99eac933eca595a3b3a824293a9b82f4
6
+ metadata.gz: 4816aeccc78086c98025948f61011c981c925d038e5313c329affe14b0b9e00d6a701ef39096bbfedf60eaecdcb6cb6d289a8d1870e95a2de3458205ad8aa240
7
+ data.tar.gz: 3a00c86ea6fbe974801a59338ac5209f512fdf729538bbc34253e6f06f85e4d99e40a5f7f1b752027df2f0d82ded9d583e89fc06583f186096dfbb8497313f3a
data/README.md CHANGED
@@ -627,7 +627,7 @@ ActionForm includes a composition system that allows form components (elements,
627
627
 
628
628
  #### **How Composition Works**
629
629
 
630
- When you create a form, all nested elements and subforms automatically have access to their owner through the `owner` accessor. Methods called on elements or subforms that are not defined locally are automatically delegated up the ownership chain, allowing you to access methods from the parent form or a custom host object.
630
+ When you create a form, all nested elements and subforms automatically have access to their owner through the `owner` accessor. To delegate methods to the owner, you must prefix method calls with `owner_`. The `owner_` prefix is automatically stripped, and the method is then searched for on the ownership chain, allowing you to access methods from the parent form or a custom host object.
631
631
 
632
632
  #### **Automatic Ownership Chain**
633
633
 
@@ -639,9 +639,9 @@ class ProductForm < ActionForm::Base
639
639
  input(type: :text)
640
640
  output(type: :string)
641
641
 
642
- # This method can call methods on the owner (ProductForm)
642
+ # Use owner_ prefix to delegate to owner's method
643
643
  def render?
644
- name_render? # Delegates to owner.name_render?
644
+ owner_name_render? # Delegates to owner.name_render?
645
645
  end
646
646
  end
647
647
 
@@ -652,12 +652,12 @@ class ProductForm < ActionForm::Base
652
652
  output(type: :string)
653
653
 
654
654
  def render?
655
- variants_name_render? # Delegates to owner.variants_name_render?
655
+ owner_variants_name_render? # Delegates to owner.variants_name_render?
656
656
  end
657
657
  end
658
658
 
659
659
  def render?
660
- variants_subform_render? # Delegates to owner.variants_subform_render?
660
+ owner_variants_subform_render? # Delegates to owner.variants_subform_render?
661
661
  end
662
662
  end
663
663
  end
@@ -668,12 +668,12 @@ class ProductForm < ActionForm::Base
668
668
  output(type: :string)
669
669
 
670
670
  def render?
671
- manufacturer_name_render? # Delegates to owner.manufacturer_name_render?
671
+ owner_manufacturer_name_render? # Delegates to owner.manufacturer_name_render?
672
672
  end
673
673
  end
674
674
  end
675
675
 
676
- # Methods accessible by nested components
676
+ # Methods accessible by nested components via owner_ prefix
677
677
  def name_render?
678
678
  true
679
679
  end
@@ -725,7 +725,7 @@ class ProductForm < ActionForm::Base
725
725
  output(type: :string)
726
726
 
727
727
  def render?
728
- name_render? # Calls HostObject#name_render?
728
+ owner_name_render? # Calls HostObject#name_render? via owner_ prefix
729
729
  end
730
730
  end
731
731
 
@@ -736,7 +736,7 @@ class ProductForm < ActionForm::Base
736
736
  output(type: :string)
737
737
 
738
738
  def render?
739
- variants_name_render? # Calls HostObject#variants_name_render?
739
+ owner_variants_name_render? # Calls HostObject#variants_name_render?
740
740
  end
741
741
  end
742
742
 
@@ -745,12 +745,12 @@ class ProductForm < ActionForm::Base
745
745
  output(type: :float)
746
746
 
747
747
  def render?
748
- variants_price_render? # Calls HostObject#variants_price_render?
748
+ owner_variants_price_render? # Calls HostObject#variants_price_render?
749
749
  end
750
750
  end
751
751
 
752
752
  def render?
753
- variants_subform_render? # Calls HostObject#variants_subform_render?
753
+ owner_variants_subform_render? # Calls HostObject#variants_subform_render?
754
754
  end
755
755
  end
756
756
  end
@@ -761,7 +761,7 @@ class ProductForm < ActionForm::Base
761
761
  output(type: :string)
762
762
 
763
763
  def render?
764
- manufacturer_name_render? # Calls HostObject#manufacturer_name_render?
764
+ owner_manufacturer_name_render? # Calls HostObject#manufacturer_name_render?
765
765
  end
766
766
  end
767
767
  end
@@ -775,7 +775,7 @@ form = ProductForm.new(object: product, owner: host)
775
775
 
776
776
  #### **Ownership Chain Traversal**
777
777
 
778
- The composition system supports multi-level ownership chains. When a method is called on an element or subform, it searches up the ownership chain until it finds the method:
778
+ The composition system supports multi-level ownership chains. When a method is called with the `owner_` prefix on an element or subform, it searches up the ownership chain until it finds the method:
779
779
 
780
780
  ```ruby
781
781
  class GrandparentForm < ActionForm::Base
@@ -795,18 +795,19 @@ class ChildForm < ActionForm::Base
795
795
  input(type: :text)
796
796
 
797
797
  def render?
798
- shared_helper # Will find ParentForm#shared_helper first
798
+ owner_shared_helper # Will find ParentForm#shared_helper first
799
799
  end
800
800
  end
801
801
  end
802
802
 
803
803
  # If ChildForm has ParentForm as owner, and ParentForm has GrandparentForm as owner:
804
- # The method lookup order is: ChildForm -> ParentForm -> GrandparentForm
804
+ # The method lookup order is: ParentForm -> GrandparentForm
805
+ # Note: Methods must be prefixed with owner_ to trigger delegation
805
806
  ```
806
807
 
807
808
  #### **Accessing Owner Directly**
808
809
 
809
- You can access the owner directly using the `owner` accessor:
810
+ You can access the owner directly using the `owner` accessor. However, for delegation, it's recommended to use the `owner_` prefix pattern:
810
811
 
811
812
  ```ruby
812
813
  class ProductForm < ActionForm::Base
@@ -815,15 +816,26 @@ class ProductForm < ActionForm::Base
815
816
  output(type: :string)
816
817
 
817
818
  def disabled?
818
- # Access owner's methods directly
819
- owner.current_user && !owner.current_user.admin?
819
+ # Preferred: Use owner_ prefix for delegation
820
+ owner_is_discount_disabled?
821
+
822
+ # Alternative: Direct access via owner accessor (requires owner to be set)
823
+ # owner.current_user && !owner.current_user.admin?
820
824
  end
821
825
 
822
826
  def placeholder
823
- owner.discount_placeholder_text
827
+ # Preferred: Use owner_ prefix
828
+ owner_discount_placeholder_text
829
+
830
+ # Alternative: Direct access
831
+ # owner.discount_placeholder_text
824
832
  end
825
833
  end
826
834
 
835
+ def is_discount_disabled?
836
+ current_user && !current_user.admin?
837
+ end
838
+
827
839
  def current_user
828
840
  @current_user ||= User.find(session[:user_id])
829
841
  end
@@ -834,6 +846,10 @@ class ProductForm < ActionForm::Base
834
846
  end
835
847
  ```
836
848
 
849
+ **When to use each approach:**
850
+ - **`owner_method_name`**: Recommended for delegation - automatically searches the ownership chain
851
+ - **`owner.method_name`**: Use when you need direct access and the owner is guaranteed to be set, or when chaining methods with safe navigation (`owner.current_user&.admin?`)
852
+
837
853
  #### **Ownership Hierarchy**
838
854
 
839
855
  The ownership hierarchy is automatically established as follows:
@@ -855,10 +871,15 @@ class OrderForm < ActionForm::Base
855
871
  output(type: :string)
856
872
 
857
873
  def render?
858
- owner.current_user&.admin?
874
+ # Use owner_ prefix to delegate to owner method
875
+ owner_can_render_admin_notes?
859
876
  end
860
877
  end
861
878
 
879
+ def can_render_admin_notes?
880
+ current_user&.admin?
881
+ end
882
+
862
883
  def current_user
863
884
  @current_user
864
885
  end
@@ -873,7 +894,8 @@ class RegistrationForm < ActionForm::Base
873
894
  output(type: :string)
874
895
 
875
896
  def disabled?
876
- owner.email_locked?
897
+ # Delegate to owner's email_locked? method
898
+ owner_email_locked?
877
899
  end
878
900
  end
879
901
 
@@ -882,7 +904,7 @@ class RegistrationForm < ActionForm::Base
882
904
  output(type: :string)
883
905
 
884
906
  def disabled?
885
- owner.email_locked?
907
+ owner_email_locked?
886
908
  end
887
909
  end
888
910
 
@@ -902,13 +924,14 @@ class SettingsForm < ActionForm::Base
902
924
  output(type: :bool)
903
925
 
904
926
  def render?
905
- owner.feature_enabled?(:advanced_settings)
927
+ # Delegate with owner_ prefix
928
+ owner_feature_enabled?(:advanced_settings)
906
929
  end
907
930
  end
908
931
  end
909
932
 
910
933
  def render?
911
- owner.feature_enabled?(:advanced_settings)
934
+ owner_feature_enabled?(:advanced_settings)
912
935
  end
913
936
  end
914
937
 
@@ -20,22 +20,27 @@ module ActionForm
20
20
 
21
21
  module InstanceMethods # rubocop:disable Style/Documentation
22
22
  def method_missing(name, *attrs, **kwargs, &block)
23
- if (handler = owners_chain.lazy.detect { |o| o.public_methods.include?(name) })
24
- handler.public_send(name, *attrs, **kwargs, &block)
25
- else
26
- super
27
- end
23
+ return super unless name.to_s.start_with?("owner_")
24
+
25
+ owner_method = name.to_s.sub("owner_", "").to_sym
26
+ return super unless (handler = owners_chain.detect { |o| o.public_methods.include?(owner_method) })
27
+
28
+ handler.public_send(owner_method, *attrs, **kwargs, &block)
28
29
  end
29
30
 
30
- def respond_to_missing?(method_name, _include_private = false)
31
- public_methods.detect { |m| m == :owner } || super
31
+ def respond_to_missing?(method_name, include_private = false)
32
+ return super unless method_name.to_s.start_with?("owner_")
33
+
34
+ owners_chain.any? { |o| o.respond_to?(method_name.to_s.sub("owner_", "").to_sym, include_private) }
32
35
  end
33
36
 
37
+ private
38
+
34
39
  def owners_chain
35
- obj = self
36
- Enumerator.new do |y|
40
+ @owners_chain ||= Enumerator.new do |y|
41
+ obj = self
37
42
  y << obj = obj.owner while obj.public_methods.include?(:owner)
38
- end
43
+ end.lazy
39
44
  end
40
45
  end
41
46
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActionForm
4
- VERSION = "0.5.1"
4
+ VERSION = "0.5.2"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: action_form
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrii Baran