Class: IronAdmin::Form::BelongsToComponent

Inherits:
ViewComponent::Base
  • Object
show all
Defined in:
app/components/iron_admin/form/belongs_to_component.rb

Overview

Renders a select dropdown for belongs_to associations.

Examples:

Basic belongs_to select

render IronAdmin::Form::BelongsToComponent.new(
  name: "record[organization_id]",
  association_class: Organization,
  selected: @record.organization_id
)

Constant Summary collapse

DEFAULT_OPTIONS_LIMIT =

Default limit for options before suggesting autocomplete.

Returns:

  • (Integer)
100
DISPLAY_METHOD_FALLBACKS =

Methods tried (in order) when no explicit display_method: is passed, or when the explicit method returns a blank value. Single source of truth lives on IronAdmin::ApplicationHelper so forms and show/index pages can never silently drift apart.

IronAdmin::ApplicationHelper::DISPLAY_METHODS

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name:, association_class:, selected: nil, display_method: nil, include_blank: true, disabled: false, has_error: false, options_limit: DEFAULT_OPTIONS_LIMIT, options_scope: nil) ⇒ BelongsToComponent

Returns a new instance of BelongsToComponent.

Parameters:

  • name (String)

    Select name

  • association_class (Class)

    Associated model class

  • selected (Integer, nil) (defaults to: nil)

    Selected ID

  • display_method (Symbol, Proc, nil) (defaults to: nil)

    Custom display method. Pass nil (the default) to let the component auto-detect a sensible label from IronAdmin::ApplicationHelper::DISPLAY_METHODS (:name, :title, :email, :label, :slug), falling back to "<Model> #<id>" if none of those exist.

  • include_blank (Boolean) (defaults to: true)

    Include blank option

  • disabled (Boolean) (defaults to: false)

    Disabled state

  • has_error (Boolean) (defaults to: false)

    Error state

  • options_limit (Integer) (defaults to: DEFAULT_OPTIONS_LIMIT)

    Max options

  • options_scope (Proc, nil) (defaults to: nil)

    Custom scope



64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'app/components/iron_admin/form/belongs_to_component.rb', line 64

def initialize(name:, association_class:, selected: nil, display_method: nil,
               include_blank: true, disabled: false, has_error: false,
               options_limit: DEFAULT_OPTIONS_LIMIT, options_scope: nil)
  @name = name
  @association_class = association_class
  @selected = selected
  @display_method = display_method
  @include_blank = include_blank
  @disabled = disabled
  @has_error = has_error
  @options_limit = options_limit
  @options_scope = options_scope
end

Instance Attribute Details

#association_classClass (readonly)

Returns The associated model class.

Returns:

  • (Class)

    The associated model class



28
29
30
# File 'app/components/iron_admin/form/belongs_to_component.rb', line 28

def association_class
  @association_class
end

#disabledBoolean (readonly)

Returns Whether input is disabled.

Returns:

  • (Boolean)

    Whether input is disabled



40
41
42
# File 'app/components/iron_admin/form/belongs_to_component.rb', line 40

def disabled
  @disabled
end

#display_methodSymbol (readonly)

Returns Method to call for display text.

Returns:

  • (Symbol)

    Method to call for display text



34
35
36
# File 'app/components/iron_admin/form/belongs_to_component.rb', line 34

def display_method
  @display_method
end

#has_errorBoolean (readonly)

Returns Whether input has error state.

Returns:

  • (Boolean)

    Whether input has error state



43
44
45
# File 'app/components/iron_admin/form/belongs_to_component.rb', line 43

def has_error
  @has_error
end

#include_blankBoolean (readonly)

Returns Whether to include blank option.

Returns:

  • (Boolean)

    Whether to include blank option



37
38
39
# File 'app/components/iron_admin/form/belongs_to_component.rb', line 37

def include_blank
  @include_blank
end

#nameString (readonly)

Returns Select name attribute.

Returns:

  • (String)

    Select name attribute



25
26
27
# File 'app/components/iron_admin/form/belongs_to_component.rb', line 25

def name
  @name
end

#options_limitInteger (readonly)

Returns Max options to load.

Returns:

  • (Integer)

    Max options to load



46
47
48
# File 'app/components/iron_admin/form/belongs_to_component.rb', line 46

def options_limit
  @options_limit
end

#options_scopeProc? (readonly)

Returns Custom scope for options.

Returns:

  • (Proc, nil)

    Custom scope for options



49
50
51
# File 'app/components/iron_admin/form/belongs_to_component.rb', line 49

def options_scope
  @options_scope
end

#selectedInteger? (readonly)

Returns Currently selected ID.

Returns:

  • (Integer, nil)

    Currently selected ID



31
32
33
# File 'app/components/iron_admin/form/belongs_to_component.rb', line 31

def selected
  @selected
end

Instance Method Details

#chevron_styleString

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns Inline CSS style for dropdown chevron.

Returns:

  • (String)

    Inline CSS style for dropdown chevron



139
140
141
142
143
144
# File 'app/components/iron_admin/form/belongs_to_component.rb', line 139

def chevron_style
  "background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' " \
    "viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' " \
    "stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e\"); background-position: right 0.5rem center; " \
    "background-repeat: no-repeat; background-size: 1.5em 1.5em; padding-right: 2.5rem;"
end

#option_label_for(record) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Resolves the option label for a single record. Mirrors IronAdmin::ApplicationHelper#display_record_label so callers who construct the component directly (or test it without rendering) get the same fallback behavior:

  1. Try the explicit display_method: (Proc or Symbol/ String) and return it if it produces a non-blank value.
  2. If the explicit method is absent or returns blank/nil, walk DISPLAY_METHOD_FALLBACKS and return the first non-blank one.
  3. Otherwise return "<Model> #<id>" so the option is at least identifiable.

Parameters:

  • record (Object)

    The associated record

Returns:

  • (String)

    The label



108
109
110
111
112
113
114
115
116
117
118
# File 'app/components/iron_admin/form/belongs_to_component.rb', line 108

def option_label_for(record)
  explicit = explicit_display_value(record)
  return explicit if explicit.present?

  DISPLAY_METHOD_FALLBACKS.each do |method|
    value = record.public_send(method) if record.respond_to?(method)
    return value if value.present?
  end

  "#{record.class.model_name.human} ##{record.id}"
end

#optionsArray<Array(String, Integer)>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns Options array for select tag.

Returns:

  • (Array<Array(String, Integer)>)

    Options array for select tag



86
87
88
89
90
91
# File 'app/components/iron_admin/form/belongs_to_component.rb', line 86

def options
  scope = options_scope ? association_class.instance_exec(&options_scope) : association_adapter.all
  association_adapter.limit(scope, options_limit).map do |record|
    [option_label_for(record), record.id]
  end
end

#select_classesString

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns CSS classes for select element.

Returns:

  • (String)

    CSS classes for select element



128
129
130
131
132
133
134
135
# File 'app/components/iron_admin/form/belongs_to_component.rb', line 128

def select_classes
  base = "block w-full appearance-none border px-3 py-2 text-sm shadow-sm outline-none " \
         "transition duration-150 ease-in-out #{theme.border_radius} #{theme.input_border} " \
         "#{theme.card_bg} #{theme.body_text} #{theme.input_focus}"
  base += " !border-red-400 !focus:border-red-500 !focus:ring-red-500/20" if has_error
  base += " bg-gray-50 cursor-not-allowed" if disabled
  base
end

#show_search_hint?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns Whether to show hint about more records available.

Returns:

  • (Boolean)

    Whether to show hint about more records available



122
123
124
# File 'app/components/iron_admin/form/belongs_to_component.rb', line 122

def show_search_hint?
  association_adapter.count > options_limit
end

#themeIronAdmin::Configuration::Theme

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns Theme configuration.

Returns:



80
81
82
# File 'app/components/iron_admin/form/belongs_to_component.rb', line 80

def theme
  IronAdmin.configuration.theme
end