Class: ViewComponent::Form::FieldComponent

Inherits:
BaseComponent show all
Defined in:
app/components/view_component/form/field_component.rb

Instance Attribute Summary collapse

Attributes inherited from BaseComponent

#form, #object_name, #options

Instance Method Summary collapse

Methods inherited from BaseComponent

#html_class, #object_errors, #object_errors?

Methods included from ClassNamesHelper

#build_tag_values, #class_names

Constructor Details

#initialize(form, object_name, method_name, options = {}) ⇒ FieldComponent

Returns a new instance of FieldComponent.



13
14
15
16
17
18
# File 'app/components/view_component/form/field_component.rb', line 13

def initialize(form, object_name, method_name, options = {})
  # See: https://github.com/rails/rails/blob/83217025a171593547d1268651b446d3533e2019/actionview/lib/action_view/helpers/tags/base.rb#L13
  @method_name = method_name.to_s.dup

  super(form, object_name, options)
end

Instance Attribute Details

#method_nameObject (readonly)

Returns the value of attribute method_name.



9
10
11
# File 'app/components/view_component/form/field_component.rb', line 9

def method_name
  @method_name
end

Instance Method Details

#callObject



20
21
22
23
24
# File 'app/components/view_component/form/field_component.rb', line 20

def call
  raise "`self.tag_klass' should be defined in #{self.class.name}" unless self.class.tag_klass

  self.class.tag_klass.new(object_name, method_name, @view_context, options).render
end

#label_textObject



66
67
68
69
70
71
# File 'app/components/view_component/form/field_component.rb', line 66

def label_text
  content ||= ActionView::Helpers::Tags::Translator.new(object, object_name, method_name,
                                                        scope: "helpers.label").translate
  content ||= method_name.humanize
  content
end

#method_errorsObject



26
27
28
29
30
31
32
33
# File 'app/components/view_component/form/field_component.rb', line 26

def method_errors
  return [] unless method_errors?

  @method_errors ||= object_errors.to_hash
                                  .fetch_values(*object_method_names) { nil }
                                  .flatten.compact
                                  .map(&:upcase_first)
end

#method_errors?Boolean

Returns:

  • (Boolean)


36
37
38
39
40
# File 'app/components/view_component/form/field_component.rb', line 36

def method_errors?
  return false unless object_errors

  (object_errors.attribute_names & object_method_names).any?
end

#object_method_namesObject



53
54
55
56
57
58
59
60
61
62
63
# File 'app/components/view_component/form/field_component.rb', line 53

def object_method_names
  @object_method_names ||= begin
    object_method_names = [method_name.to_sym]
    if method_name.end_with?("_id") && object.respond_to?(singular_association_method_name)
      object_method_names << singular_association_method_name
    elsif method_name.end_with?("_ids") && object.respond_to?(collection_association_method_name)
      object_method_names << collection_association_method_name
    end
    object_method_names
  end
end

#optional?(context: validation_context) ⇒ Boolean

Returns:

  • (Boolean)


73
74
75
76
77
# File 'app/components/view_component/form/field_component.rb', line 73

def optional?(context: validation_context)
  return false if object.nil?

  !required?(context: context)
end

#required?(context: validation_context) ⇒ Boolean

Returns:

  • (Boolean)


79
80
81
82
83
# File 'app/components/view_component/form/field_component.rb', line 79

def required?(context: validation_context)
  return false if object.nil?

  validators(context: context).any?(ActiveModel::Validations::PresenceValidator)
end

#validators(context: validation_context) ⇒ Object



85
86
87
88
89
90
91
92
93
# File 'app/components/view_component/form/field_component.rb', line 85

def validators(context: validation_context)
  method_validators.select do |validator|
    if context.nil?
      validator.options[:on].blank?
    else
      Array(validator.options[:on]).include?(context&.to_sym)
    end
  end
end

#valueObject



49
50
51
# File 'app/components/view_component/form/field_component.rb', line 49

def value
  object.public_send(method_name)
end