Class: IntrospectiveAdmin::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/introspective_admin/base.rb

Class Method Summary collapse

Class Method Details

.column_list(model, extras = []) ⇒ Object



35
36
37
38
39
40
# File 'lib/introspective_admin/base.rb', line 35

def column_list(model, extras=[])
  model.columns.map {|c|
    ref_name = c.name.sub(/(_type|_id)$/,'')
    model.reflections[ref_name] ? ref_name : c.name
  }.uniq-['created_at','updated_at']-exclude_params+extras
end

.exclude_paramsObject



23
24
25
# File 'lib/introspective_admin/base.rb', line 23

def exclude_params
  [] # do not display the field in the index page and forms.
end

.include_virtual_attributesObject



27
28
29
# File 'lib/introspective_admin/base.rb', line 27

def include_virtual_attributes
  [] #
end


48
49
50
51
52
53
54
55
56
57
58
# File 'lib/introspective_admin/base.rb', line 48

def link_record(dsl, record)
  link_text = record.try(:name) || record.try(:title) || record.class.to_s
  link_href = begin dsl.send("admin_#{record.class.name.underscore}_path", record.id) rescue false end
  if link_href
    dsl.link_to link_text, link_href
  elsif link_text
    link_text
  else
    record
  end
end

.params_list(model, extras = []) ⇒ Object



42
43
44
45
46
# File 'lib/introspective_admin/base.rb', line 42

def params_list(model, extras=[])
  model.columns.map {|c|
    polymorphic?(model,c.name) ? c.name.sub(/_id$/,'')+"_assign" : c.name
  }+extras
end

.polymorphic?(model, column) ⇒ Boolean

Returns:

  • (Boolean)


31
32
33
# File 'lib/introspective_admin/base.rb', line 31

def polymorphic?(model,column)
  (model.reflections[column.sub(/_id$/,'')].try(:options)||{})[:polymorphic]
end

.register(model, &block) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/introspective_admin/base.rb', line 60

def register(model, &block)
  # Defining activeadmin pages will break pending migrations:
  begin ActiveRecord::Migration.check_all_pending! rescue return end

  klass         = self
  model_name    = model.to_s.underscore
  nested_config = Hash[model.nested_attributes_options.reject {|name,o|
    klass.exclude_params.include?("#{name}_attributes")
  }.map {|assoc,options|
    reflection       = model.reflections[assoc.to_s]
    reflection_class = reflection.class_name.constantize
    # merge the options of the nested attribute and relationship declarations
    options = options.merge(reflection_class.reflections[assoc.to_s].try(:options) || {})
    options[:class]   = reflection_class
    options[:columns] = klass.column_list(reflection_class)
    options[:params]  = klass.params_list(reflection_class)
    options[:reflection]            = reflection
    options[:polymorphic_reference] = reflection.options[:as].to_s
    [assoc, options]
  }]

  ActiveAdmin.register model do
    instance_eval &block if block_given? # Evalutate the passed black for overrides to the defaults

    controller do
      def scoped_collection
        super.includes super.nested_attributes_options.keys
      end
    end

    index do
      selectable_column
      cols = model.columns.map(&:name)-klass.exclude_params
      cols.each_with_index do |c,i|
        reflection = model.reflections.detect {|k,v| v.foreign_key == c }
        if reflection
          column c do |o|
            klass.link_record(self,o.send(reflection.first))
          end
        else
          column c
        end
      end
      actions
    end

    show do
      instance = self.send(model_name)

      attributes_table do
        model.columns.each do |c|
          next if (c.name =~ /password/)
          reflection = model.reflections.detect {|k,v| v.foreign_key == c.name }
          if reflection
            row c.name do |o|
              klass.link_record(self,instance.send(reflection.first))
            end
          else
            row c.name
          end

        end

        nested_config.each do |assoc,options|
          panel assoc.capitalize do
            table_for instance.send(assoc) do
              options[:columns].each do |c|
                if options[:class].reflections[c]
                  column( c ) do |r|
                    klass.link_record(self,r.send(c)) if r
                  end
                else
                  column c
                end
              end

              admin_route = begin url_for(['admin', options[:class].name.underscore]) rescue false end
              if admin_route
                column 'actions' do |child|
                  span link_to "View",   url_for(['admin', child])
                  span link_to "Edit",   url_for(['edit','admin',child])
                  span link_to "Delete", url_for(['admin',child]), method: :delete, confirm: "Are you sure you want to delete this?"
                end
              end
            end
          end
        end
      end
    end

    permit_params klass.params_list(model, klass.include_virtual_attributes) + [Hash[nested_config.map{|assoc,o|
      ["#{assoc}_attributes", o[:params]+[(o[:allow_destroy] ? :_destroy : '')] ]
    }]]

    form do |f|
      f.semantic_errors *f.object.errors.messages.keys
      f.actions

      klass.column_list(model, klass.include_virtual_attributes).each do |column|
        if column == model.primary_key
        elsif klass.polymorphic?(model,column)
          f.input column+"_assign", collection: model.send("#{column}_assign_options")
        elsif model.respond_to?("options_for_#{column}")
          f.input column, collection: model.send("options_for_#{column}", f.object)
        else
          f.input column
        end
      end

      div { '&nbsp'.html_safe }

      nested_config.each do |assoc,options|
        aclass  = options[:class]
        columns = options[:columns]-[aclass.primary_key]
        f.inputs do
          f.has_many assoc, allow_destroy: options[:allow_destroy] do |r|
            columns.each do |c|
              if c == model_name || c == options[:polymorphic_reference]
                # the join to the parent is implicit
              elsif klass.polymorphic?(aclass,c)
                r.input "#{c}_assign", collection: aclass.send("#{c}_assign_options")
              elsif aclass.reflections[c] && aclass.respond_to?("options_for_#{c}")
                # If the class has an options_for_<column> method defined use that
                # rather than the default behavior, pass the instance for scoping,
                # e.g. UserProjectJob.options_for_job is scoped by the Project's
                # jobs:
                r.input c, collection: aclass.send("options_for_#{c}",f.object)
              else
                r.input c
              end
            end
          end
        end
      end
    end

  end
end