class Madmin::Resource

Public Class Methods

attribute(name, type = nil, **options) click to toggle source
# File lib/madmin/resource.rb, line 33
def attribute(name, type = nil, **options)
  type ||= infer_type(name)
  field = options[:field] || field_for_type(type)

  attributes[name] = OpenStruct.new(
    name: name,
    type: type,
    field: field.new(**options.merge(attribute_name: name, model: model))
  )
end
display_name(record) click to toggle source
# File lib/madmin/resource.rb, line 80
def display_name(record)
  "#{record.class} ##{record.id}"
end
edit_path(record) click to toggle source
# File lib/madmin/resource.rb, line 66
def edit_path(record)
  route_name = "edit_madmin_#{model.model_name.singular}_path"

  url_helpers.send(route_name, record.to_param)
end
friendly_model?() click to toggle source
# File lib/madmin/resource.rb, line 84
def friendly_model?
  model.respond_to? :friendly
end
friendly_name() click to toggle source
# File lib/madmin/resource.rb, line 44
def friendly_name
  model_name.gsub("::", " / ")
end
get_attribute(name) click to toggle source
# File lib/madmin/resource.rb, line 29
def get_attribute(name)
  attributes[name]
end
index_path(options = {}) click to toggle source
# File lib/madmin/resource.rb, line 48
def index_path(options = {})
  route_name = "madmin_#{model.model_name.plural}_path"

  url_helpers.send(route_name, options)
end
inherited(base) click to toggle source
Calls superclass method
# File lib/madmin/resource.rb, line 7
def inherited(base)
  base.attributes = attributes.dup
  base.scopes = scopes.dup
  super
end
model() click to toggle source
# File lib/madmin/resource.rb, line 13
def model
  model_name.constantize
end
model_find(id) click to toggle source
# File lib/madmin/resource.rb, line 17
def model_find(id)
  friendly_model? ? model.friendly.find(id) : model.find(id)
end
model_name() click to toggle source
# File lib/madmin/resource.rb, line 21
def model_name
  to_s.chomp("Resource").classify
end
new_path() click to toggle source
# File lib/madmin/resource.rb, line 54
def new_path
  route_name = "new_madmin_#{model.model_name.singular}_path"

  url_helpers.send(route_name)
end
param_key() click to toggle source
# File lib/madmin/resource.rb, line 72
def param_key
  model.model_name.param_key
end
permitted_params() click to toggle source
# File lib/madmin/resource.rb, line 76
def permitted_params
  attributes.values.filter_map { |a| a.field.to_param if a.field.visible?(:form) }
end
scope(name) click to toggle source
# File lib/madmin/resource.rb, line 25
def scope(name)
  scopes << name
end
searchable_attributes() click to toggle source
# File lib/madmin/resource.rb, line 92
def searchable_attributes
  attributes.values.select { |a| a.field.searchable? }
end
show_path(record) click to toggle source
# File lib/madmin/resource.rb, line 60
def show_path(record)
  route_name = "madmin_#{model.model_name.singular}_path"

  url_helpers.send(route_name, record.to_param)
end
sortable_columns() click to toggle source
# File lib/madmin/resource.rb, line 88
def sortable_columns
  model.column_names
end

Private Class Methods

field_for_type(type) click to toggle source
# File lib/madmin/resource.rb, line 98
      def field_for_type(type)
        {
          binary: Fields::String,
          blob: Fields::Text,
          boolean: Fields::Boolean,
          date: Fields::Date,
          datetime: Fields::DateTime,
          decimal: Fields::Decimal,
          enum: Fields::Enum,
          float: Fields::Float,
          hstore: Fields::Json,
          integer: Fields::Integer,
          json: Fields::Json,
          jsonb: Fields::Json,
          primary_key: Fields::String,
          string: Fields::String,
          text: Fields::Text,
          time: Fields::Time,
          timestamp: Fields::Time,
          password: Fields::Password,

          # Postgres specific types
          bit: Fields::String,
          bit_varying: Fields::String,
          box: Fields::String,
          cidr: Fields::String,
          circle: Fields::String,
          citext: Fields::Text,
          daterange: Fields::String,
          inet: Fields::String,
          int4range: Fields::String,
          int8range: Fields::String,
          interval: Fields::String,
          line: Fields::String,
          lseg: Fields::String,
          ltree: Fields::String,
          macaddr: Fields::String,
          money: Fields::String,
          numrange: Fields::String,
          oid: Fields::String,
          path: Fields::String,
          point: Fields::String,
          polygon: Fields::String,
          tsrange: Fields::String,
          tstzrange: Fields::String,
          tsvector: Fields::String,
          uuid: Fields::String,
          xml: Fields::Text,

          # Associations
          attachment: Fields::Attachment,
          attachments: Fields::Attachments,
          belongs_to: Fields::BelongsTo,
          polymorphic: Fields::Polymorphic,
          has_many: Fields::HasMany,
          has_one: Fields::HasOne,
          rich_text: Fields::RichText,
          nested_has_many: Fields::NestedHasMany
        }.fetch(type)
      rescue
        raise ArgumentError, <<~MESSAGE
          Couldn't find attribute or association '#{name}' with type '#{type}' on #{model} model

            To fix this, either:

            1. Remove 'attribute #{name}' from app/madmin/resources/#{model.to_s.underscore}_resource.rb
            2. Or add the missing attribute or association to the #{model} model
        MESSAGE
      end
infer_type(name) click to toggle source
# File lib/madmin/resource.rb, line 168
def infer_type(name)
  name_string = name.to_s

  if model.attribute_types.include?(name_string)
    column_type = model.attribute_types[name_string]
    if column_type.is_a? ActiveRecord::Enum::EnumType
      :enum
    else
      column_type.type || :string
    end
  elsif (association = model.reflect_on_association(name))
    type_for_association(association)
  elsif model.reflect_on_association(:"rich_text_#{name_string}")
    :rich_text
  elsif model.reflect_on_association(:"#{name_string}_attachment")
    :attachment
  elsif model.reflect_on_association(:"#{name_string}_attachments")
    :attachments

  # has_secure_password
  elsif model.attribute_types.include?("#{name_string}_digest") || name_string.ends_with?("_confirmation")
    :password
  end
end
type_for_association(association) click to toggle source
# File lib/madmin/resource.rb, line 193
def type_for_association(association)
  if association.has_one?
    :has_one
  elsif association.collection?
    :has_many
  elsif association.polymorphic?
    :polymorphic
  else
    :belongs_to
  end
end
url_helpers() click to toggle source
# File lib/madmin/resource.rb, line 205
def url_helpers
  @url_helpers ||= Rails.application.routes.url_helpers
end