action_form 0.6.5 → 0.6.7

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: 72382d4935502742cc4736c21c7964185e8fdb154972bc4ae38ae9497c18009d
4
- data.tar.gz: a28f5cc2229551ce6a116721d8c34a4d134a2acc1bea9c1b081e633c20f60834
3
+ metadata.gz: d9e95531741195220dd865f28be51b1787718ca2e30638d6bf56aa0407738318
4
+ data.tar.gz: 13711adfe6a993e256644a455cd30f43c711fcf4205d2c8ecbf21d614b927959
5
5
  SHA512:
6
- metadata.gz: 6efb2e07f6de58b2d25af0e9dcaf3d0c779a7a72ea7d70acf0a840ceb70d74053902742b659369e99d7b723660e2bcac87784a9c17b1bfa3ad2f876d7e92d93b
7
- data.tar.gz: 4fd0ede2b1ef5bc8a74f12ceefd75e4d5af245abe4a26cf60fa294320198904af6f2be66245beac5a96f45c7bb72f4f0409a2f352e6f068e0cdf3f558f338dd8
6
+ metadata.gz: aecaa123a9681d574d43af444d3ddaf5323c6c8b504af40f89cdefa8a462d60174b368c730d4041078d387442bc7cdfcaee1d48ee1b22bbcfe516ae11ab8a54e
7
+ data.tar.gz: cb795dabe51f9720690579a89568cfbe805fa7a43e93c51d8ed741501e63531eb3ee582c206009e07863390cbcc5583f0bc63f7f316e2fb1399aadb51bd46afd
data/README.md CHANGED
@@ -692,9 +692,9 @@ class ProductForm < ActionForm::Base
692
692
  end
693
693
  ```
694
694
 
695
- #### **Custom Host Object**
695
+ #### **Custom Owner Object**
696
696
 
697
- You can pass a custom host object when initializing a form, allowing you to separate form logic from business logic:
697
+ You can pass a custom owner object when initializing a form, allowing you to separate form logic from business logic:
698
698
 
699
699
  ```ruby
700
700
  class HostObject
@@ -1492,11 +1492,6 @@ Use `ActionForm::Rails::Base` instead of `ActionForm::Base` for Rails applicatio
1492
1492
  class UserForm < ActionForm::Rails::Base
1493
1493
  resource_model User
1494
1494
 
1495
- element :name do
1496
- input type: :text
1497
- output type: :string, presence: true
1498
- end
1499
-
1500
1495
  element :email do
1501
1496
  input type: :email
1502
1497
  output type: :string, presence: true
@@ -1512,10 +1507,41 @@ class UserForm < ActionForm::Rails::Base
1512
1507
  output type: :string
1513
1508
  end
1514
1509
 
1510
+ subform :profile, default: {} do
1511
+ element :name do
1512
+ input(type: :text)
1513
+ output(type: :string)
1514
+ end
1515
+
1516
+ params do
1517
+ validates :name, presence: { if: :owner_check_profile_name? }
1518
+ end
1519
+ end
1520
+
1521
+ many :devices, default: [{}] do
1522
+ subform do
1523
+ element :name do
1524
+ input(type: :text)
1525
+ output(type: :string)
1526
+ end
1527
+
1528
+ params do
1529
+ validates :name, presence: { if: :owner_check_devices_name? }
1530
+ end
1531
+ end
1532
+ end
1533
+
1515
1534
  # Custom parameter validation for Rails integration
1516
1535
  params do
1517
1536
  validates :password, presence: true, length: { minimum: 6 }
1518
1537
  validates :password, confirmation: true
1538
+ # You can customize nested schema from example above like this
1539
+ profile_attributes_schema do
1540
+ validates :name, presence: { if: :owner_check_profile_name? }
1541
+ end
1542
+ devices_attributes_schema do
1543
+ validates :name, presence: { if: :owner_check_devices_name? }
1544
+ end
1519
1545
  end
1520
1546
  end
1521
1547
  ```
@@ -1613,6 +1639,8 @@ params[:user][:addresses_attributes] = {
1613
1639
 
1614
1640
  #### **Controller Integration**
1615
1641
 
1642
+ There is a separate gem for Rails integration [steel_wheel|https://github.com/andriy-baran/steel_wheel]
1643
+
1616
1644
  ```ruby
1617
1645
  class UsersController < ApplicationController
1618
1646
  def new
@@ -27,9 +27,7 @@ module ActionForm
27
27
  def inherited(subclass)
28
28
  super
29
29
  subclass.elements = elements.dup
30
- subclass.scope = scope.dup
31
- subclass.params_definition = Class.new(params_definition)
32
- subclass.params_definition.form_class = subclass
30
+ subclass.scope = scope&.dup
33
31
  end
34
32
  end
35
33
 
@@ -69,6 +67,13 @@ module ActionForm
69
67
  view_context.render html: call.html_safe
70
68
  end
71
69
 
70
+ def internal_call(parent: nil, state: nil, &block)
71
+ @_view_context ||= state&.user_context&.dig(:rails_view_context)
72
+ @_view_context ||= parent.helpers if parent.respond_to?(:helpers)
73
+ @_view_context ||= parent.view_context if parent.respond_to?(:view_context)
74
+ super
75
+ end
76
+
72
77
  def helpers
73
78
  @_view_context
74
79
  end
@@ -24,7 +24,6 @@ module ActionForm
24
24
 
25
25
  # TODO: add support for outputless elements
26
26
  def element(name, &block)
27
- @params_definition = nil
28
27
  elements[name] = Class.new(ActionForm::Element)
29
28
  elements[name].class_eval(&block)
30
29
  define_singleton_method(:"#{name}_element") do |klass = nil, &block|
@@ -33,7 +32,6 @@ module ActionForm
33
32
  end
34
33
 
35
34
  def many(name, default: nil, &block)
36
- @params_definition = nil
37
35
  subform_definition = Class.new(ActionForm::SubformsCollection)
38
36
  subform_definition.host_class = self
39
37
  subform_definition.class_eval(&block) if block
@@ -45,7 +43,6 @@ module ActionForm
45
43
  end
46
44
 
47
45
  def subform(name, default: nil, &block)
48
- @params_definition = nil
49
46
  elements[name] = Class.new(subform_class)
50
47
  elements[name].class_eval(&block)
51
48
  elements[name].default = default if default
@@ -50,18 +50,6 @@ module ActionForm
50
50
  end
51
51
  end
52
52
 
53
- def params_definition(scope: self.scope)
54
- return super unless scope
55
-
56
- @params_definitions ||= Hash.new do |h, key|
57
- h[key] = begin
58
- klass = super
59
- Class.new(self.class.params_class) { has scope, klass }
60
- end
61
- end
62
- @params_definitions[scope]
63
- end
64
-
65
53
  private
66
54
 
67
55
  def subform_html_name(name, index: nil)
@@ -17,14 +17,27 @@ module ActionForm
17
17
  @params_definition ||= create_params_definition
18
18
  end
19
19
 
20
+ def params_blocks
21
+ @params_blocks ||= []
22
+ end
23
+
20
24
  def params(&block)
21
- @params_definition = Class.new(params_definition, &block) if block
25
+ params_blocks << block if block
26
+ end
27
+
28
+ def inherited_params_blocks
29
+ parent = superclass
30
+ blocks = []
31
+ while parent.respond_to?(:params_blocks)
32
+ parent.params_blocks.each { |block| blocks.unshift(block) }
33
+ parent = parent.superclass
34
+ end
35
+ blocks
22
36
  end
23
37
 
24
- def create_params_definition # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
38
+ def create_params_definition(elements_definitions: elements) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
25
39
  schema = Class.new(params_class)
26
- schema.form_class = self
27
- elements.each do |name, element_definition|
40
+ elements_definitions.each do |name, element_definition|
28
41
  if element_definition < ActionForm::SubformsCollection
29
42
  # nested forms are passed as a hash that looks like this:
30
43
  # { "0" => { "id" => "1" }, "1" => { "id" => "2" } }
@@ -44,40 +57,25 @@ module ActionForm
44
57
  schema.public_send(method_name, name, **options)
45
58
  end
46
59
  end
60
+ patches = inherited_params_blocks + params_blocks
61
+ patches.each do |block|
62
+ schema = Class.new(schema, &block)
63
+ end
64
+ schema.form_class = self
47
65
  schema
48
66
  end
49
67
  end
50
68
 
51
69
  module InstanceMethods # rubocop:disable Style/Documentation
52
- def params_definition(*)
70
+ def params_definition
53
71
  @params_definition ||= create_params_definition
54
72
  end
55
73
 
56
- def create_params_definition # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
74
+ def create_params_definition
57
75
  schema = Class.new(self.class.params_class)
58
76
  schema.form_class = self.class
59
- elements_instances.select(&:render?).each do |element|
60
- case element
61
- when ActionForm::SubformsCollection
62
- # nested forms are passed as a hash that looks like this:
63
- # { "0" => { "id" => "1" }, "1" => { "id" => "2" } }
64
- # it is coercing to an array of hashes:
65
- # [['0', { "id" => "1" }], ['1', { "id" => "2" }]]
66
- # we need to normalize it to an array of hashes:
67
- # [ { "id" => "1" }, { "
68
- # id" => "2" } ]
69
- schema.each(:"#{element.name}_attributes", element.subforms.first.params_definition,
70
- normalize: ->(value) { value.flatten.select { |v| v.is_a?(Hash) } },
71
- default: element.class.default)
72
- when ActionForm::Subform
73
- schema.has(:"#{element.name}_attributes", element.params_definition, default: element.class.default)
74
- when ActionForm::Element
75
- options = element.class.output_options.dup
76
- method_name = options.delete(:type)
77
- schema.public_send(method_name, element.name, **options)
78
- end
79
- end
80
- schema
77
+ renderable_elements = elements_instances.select(&:render?).to_h { |element| [element.name, element.class] }
78
+ self.class.create_params_definition(elements_definitions: renderable_elements)
81
79
  end
82
80
  end
83
81
  end
@@ -22,7 +22,7 @@ module ActionForm
22
22
 
23
23
  def inherited(subclass)
24
24
  super
25
- subclass.subform_definition = subform_definition
25
+ subclass.subform_definition = Class.new(subform_definition) if subform_definition
26
26
  subclass.default = default
27
27
  subclass.host_class = host_class
28
28
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActionForm
4
- VERSION = "0.6.5"
4
+ VERSION = "0.6.7"
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.6.5
4
+ version: 0.6.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrii Baran