class Avo::Fields::BaseField

def assign_value(record:, value:)

Used by Avo to fill the record with the default value on :new and :edit views
def assign_value(record:, value:)
  id = type == "belongs_to" ? foreign_key : database_id
  if record.send(id).nil?
    record.send("#{id}=", value)
  end
end

def component_for_view(view = :index)

Try and build the component class or fallback to a blank one
def component_for_view(view = :index)
  # Use the edit variant for all "update" views
  view = :edit if view.in? [:new, :create, :update]
  component_class = "#{view_component_namespace}::#{view.to_s.camelize}Component"
  component_class.constantize
rescue
  unless Rails.env.test?
    Avo.logger.info "Failed to find component for the `#{self.class}` field on the `#{view}` view."
  end
  # When returning nil, a race condition happens and throws an error in some environments.
  # See https://github.com/avo-hq/avo/pull/365
  ::Avo::BlankFieldComponent
end

def custom?

def custom?
  !method(:initialize).source_location.first.include?("lib/avo/field")
rescue
  true
end

def custom_name?

def custom_name?
  !@name.nil?
end

def database_id

Try to see if the field has a different database ID than it's name
def database_id
  foreign_key
rescue
  id
end

def default_name

def default_name
  @id.to_s.humanize(keep_id_suffix: true)
end

def fill_field(record, key, value, params)

Fills the record with the received value on create and update actions.
def fill_field(record, key, value, params)
  return record unless record.methods.include? key.to_sym
  if @update_using.present?
    value = Avo::ExecutionContext.new(
      target: @update_using,
      record: record,
      key: key,
      value: value,
      resource: resource,
      field: self
    ).handle
  end
  record.public_send("#{key}=", value)
  record
end

def has_own_panel?

def has_own_panel?
  false
end

def hidden_in_reflection?

def hidden_in_reflection?
  !visible_in_reflection?
end

def in_action?

def in_action?
  @action.present?
end

def initialize(id, **args, &block)

def initialize(id, **args, &block)
  @id = id
  @name = args[:name]
  @translation_key = args[:translation_key]
  @block = block
  @required = args.dig(:required) # Value if :required present on args, nil otherwise
  @readonly = args[:readonly] || false
  @disabled = args[:disabled] || false
  @sortable = args[:sortable] || false
  @nullable = args[:nullable] || false
  @null_values = args[:null_values] || [nil, ""]
  @format_using = args[:format_using] || nil
  @update_using = args[:update_using] || nil
  @placeholder = args[:placeholder]
  @autocomplete = args[:autocomplete] || nil
  @help = args[:help] || nil
  @default = args[:default] || nil
  @visible = args[:visible]
  @as_avatar = args[:as_avatar] || false
  @html = args[:html] || nil
  @view = args[:view] || nil
  @value = args[:value] || nil
  @stacked = args[:stacked] || nil
  @for_presentation_only = args[:for_presentation_only] || false
  @resource = args[:resource]
  @args = args
  @computable = true
  @computed = block.present?
  @computed_value = nil
  post_initialize if respond_to?(:post_initialize)
end

def is_model?(model)

def is_model?(model)
  model_or_class(model) == "model"
end

def model_or_class(model)

def model_or_class(model)
  if model.instance_of?(String)
    "class"
  else
    "model"
  end
end

def name

We'll fallback to humanizing the id
Secondly we'll try to find a translation key
We'll first check to see if the user passed a name
Getting the name of the resource (user/users, post/posts)
def name
  return @name if custom_name?
  if translation_key
    translated_name default: default_name
  else
    default_name
  end
end

def on_create?

def on_create?
  @view.in?([:new, :create])
end

def options_for_filter

def options_for_filter
  options
end

def placeholder

def placeholder
  Avo::ExecutionContext.new(target: @placeholder || name, record: record, resource: @resource, view: @view).handle
end

def plural_name

def plural_name
  default = name.pluralize
  if translation_key
    translated_plural_name default: default
  else
    default
  end
end

def record_errors

def record_errors
  return {} if record.nil?
  record.errors
end

def resolve_attribute(value)

def resolve_attribute(value)
  value
end

def should_fill_with_default_value?

def should_fill_with_default_value?
  on_create? || in_action?
end

def table_header_label

def table_header_label
  name
end

def to_permitted_param

def to_permitted_param
  id.to_sym
end

def translated_name(default:)

def translated_name(default:)
  t(translation_key, count: 1, default: default).humanize
end

def translated_plural_name(default:)

def translated_plural_name(default:)
  t(translation_key, count: 2, default: default).humanize
end

def translation_key

def translation_key
  @translation_key || "avo.field_translations.#{@id}"
end

def type

def type
  self.class.name.demodulize.to_s.underscore.gsub("_field", "")
end

def updatable

def updatable
  !is_disabled? && visible?
end

def value(property = nil)

def value(property = nil)
  return @value if @value.present?
  property ||= id
  # Get record value
  final_value = record.send(property) if is_model?(record) && record.respond_to?(property)
  # On new views and actions modals we need to prefill the fields with the default value
  if should_fill_with_default_value? && default.present?
    final_value = computed_default_value
  end
  # Run computable callback block if present
  if computable && block.present?
    final_value = Avo::ExecutionContext.new(
      target: block,
      record: record,
      resource: @resource,
      view: @view,
      field: self,
      include: self.class.included_modules
    ).handle
  end
  # Run the value through resolver if present
  if format_using.present?
    final_value = Avo::ExecutionContext.new(
      target: format_using,
      value: final_value,
      record: record,
      resource: resource,
      view: view,
      field: self,
      include: self.class.included_modules
    ).handle
  end
  final_value
end

def view_component_name

def view_component_name
  "#{type.camelize}Field"
end

def view_component_namespace

For custom components the namespace will be different than Avo::Fields so we should take that into account.
def view_component_namespace
  "#{self.class.to_s.deconstantize}::#{view_component_name}"
end

def visible_in_reflection?

def visible_in_reflection?
  true
end