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 +4 -4
- data/README.md +47 -24
- data/lib/action_form/composition.rb +15 -10
- data/lib/action_form/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b0f29b8e09e9fd398ad1442b60c537cabe004f8f53ea208b904e3c924e922972
|
|
4
|
+
data.tar.gz: 7329122a3632b906e1ddc1c1d6ac7d0de4814270372682d10184677fdba3f8b7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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.
|
|
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
|
-
#
|
|
642
|
+
# Use owner_ prefix to delegate to owner's method
|
|
643
643
|
def render?
|
|
644
|
-
|
|
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
|
-
|
|
655
|
+
owner_variants_name_render? # Delegates to owner.variants_name_render?
|
|
656
656
|
end
|
|
657
657
|
end
|
|
658
658
|
|
|
659
659
|
def render?
|
|
660
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
748
|
+
owner_variants_price_render? # Calls HostObject#variants_price_render?
|
|
749
749
|
end
|
|
750
750
|
end
|
|
751
751
|
|
|
752
752
|
def render?
|
|
753
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
-
#
|
|
819
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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,
|
|
31
|
-
|
|
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
|
-
|
|
36
|
-
|
|
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
|
data/lib/action_form/version.rb
CHANGED