class Avo::Fields::Field

def database_id(model)

Try to see if the field has a different database ID than it's name
def database_id(model)
  begin
    foreign_key(model)
  rescue => exception
    id
  end
end

def fetch_for_action(model, resource)

def fetch_for_action(model, resource)
  fields = {
    id: id,
    # computed: block.present?,
  }
  # Fill the properties with values
  @field_properties.each do |name, value|
    fields[name] = self.send(name)
  end
  # Set initial value
  # fields[:value] = model.send(id) if model_or_class(model) == 'model' and model.methods.include? id
  # Set default value for create view
  if fields[:default].present? and fields[:default].respond_to? :call
    fields[:value] = fields[:default].call model, resource, self
  else
    fields[:value] = fields[:default]
  end
  # Run callback block if present
  # if computable and @block.present?
  #   fields[:computed_value] = @block.call model, resource, self
  #   fields[:value] = fields[:computed_value]
  # end
  # Run each field's custom hydration
  fields.merge! self.hydrate_field(fields, model, resource, :create)
  # Run the value through resolver if present
  fields[:value] = @format_using.call fields[:value] if @format_using.present?
  fields
end

def fetch_for_resource(model, resource, view)

def fetch_for_resource(model, resource, view)
  fields = {
    id: id,
    computed: block.present?,
  }
  # Fill the properties with values
  @field_properties.each do |name, value|
    fields[name] = self.send(name)
  end
  # Set model value
  fields[:value] = model.send(id) if model_or_class(model) == 'model' and model.methods.include? id
  # Set default value for create view
  if view === :create
    if fields[:default].present? and fields[:default].respond_to? :call
      fields[:value] = fields[:default].call model, resource, view, self
    else
      fields[:value] = fields[:default]
    end
  end
  # Run callback block if present
  if computable and @block.present?
    fields[:computed_value] = @block.call model, resource, view, self
    fields[:value] = fields[:computed_value]
  end
  # Run each field's custom hydration
  fields.merge! self.hydrate_field(fields, model, resource, view)
  # Run the value through resolver if present
  fields[:value] = @format_using.call fields[:value] if @format_using.present?
  fields
end

def fill_field(model, key, value)

def fill_field(model, key, value)
  return model unless model.methods.include? key.to_sym
  model.send("#{key}=", value)
  model
end

def has_own_panel?

def has_own_panel?
  false
end

def hydrate_field(fields, model, resource)

def hydrate_field(fields, model, resource)
  final_value = fields[:value]
  if fields[:computed_value].present?
    final_value = fields[:computed_value]
  end
  {
    value: final_value
  }
end

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

def initialize(id, **args, &block)
  super(id, **args, &block)
  @defaults ||= {}
  args = @defaults.merge(args).symbolize_keys
  null_values = [nil, '', *args[:null_values]]
  # The field properties as a hash {property: default_value}
  @field_properties = {
    id: id,
    name: id.to_s.humanize,
    block: block,
    component: 'field',
    required: false,
    readonly: false,
    updatable: true,
    sortable: false,
    nullable: false,
    null_values: null_values,
    computable: true,
    is_array_param: false,
    format_using: false,
    placeholder: id.to_s.camelize,
    help: nil,
    default: nil,
  }
  # Set the values in the following order
  # - app defaults
  # - field defaults
  # - field option
  @field_properties.each do |name, default_value|
    final_value = args[name.to_sym]
    self.send("#{name}=", name != 'null_values' && (final_value.nil? || !defined?(final_value)) ? default_value : final_value)
  end
  # Set the visibility
  show_on args[:show_on] if args[:show_on].present?
  hide_on args[:hide_on] if args[:hide_on].present?
  only_on args[:only_on] if args[:only_on].present?
  except_on args[:except_on] if args[:except_on].present?
end

def model_or_class(model)

def model_or_class(model)
  if model.class == String
    return 'class'
  else
    return 'model'
  end
end

def resolve_attribute(value)

def resolve_attribute(value)
  value
end