madmin 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +7 -82
  4. data/Rakefile +1 -6
  5. data/app/assets/config/manifest.js +2 -0
  6. data/app/assets/stylesheets/actiontext.scss +36 -0
  7. data/app/assets/stylesheets/{madmin/application.css → application.css} +2 -9
  8. data/app/controllers/madmin/application_controller.rb +6 -10
  9. data/app/controllers/madmin/dashboard_controller.rb +1 -3
  10. data/app/controllers/madmin/resource_controller.rb +72 -0
  11. data/app/helpers/madmin/application_helper.rb +1 -11
  12. data/app/views/layouts/madmin/application.html.erb +25 -26
  13. data/app/views/madmin/application/_form.html.erb +25 -0
  14. data/app/views/madmin/application/_navigation.html.erb +6 -0
  15. data/app/views/madmin/application/edit.html.erb +3 -0
  16. data/app/views/madmin/application/index.html.erb +35 -0
  17. data/app/views/madmin/application/new.html.erb +3 -0
  18. data/app/views/madmin/application/show.html.erb +24 -0
  19. data/app/views/madmin/dashboard/show.html.erb +1 -0
  20. data/app/views/madmin/fields/attachment/_form.html.erb +2 -0
  21. data/app/views/madmin/fields/attachment/_index.html.erb +3 -0
  22. data/app/views/madmin/fields/attachment/_show.html.erb +3 -0
  23. data/app/views/madmin/fields/attachments/_form.html.erb +2 -0
  24. data/app/views/madmin/fields/attachments/_index.html.erb +1 -0
  25. data/app/views/madmin/fields/attachments/_show.html.erb +7 -0
  26. data/app/views/madmin/fields/belongs_to/_form.html.erb +2 -14
  27. data/app/views/madmin/fields/belongs_to/_index.html.erb +2 -7
  28. data/app/views/madmin/fields/belongs_to/_show.html.erb +2 -8
  29. data/app/views/madmin/fields/boolean/_form.html.erb +2 -0
  30. data/app/views/madmin/fields/boolean/_index.html.erb +1 -0
  31. data/app/views/madmin/fields/boolean/_show.html.erb +1 -0
  32. data/app/views/madmin/fields/date/_form.html.erb +2 -0
  33. data/app/views/madmin/fields/date/_index.html.erb +1 -0
  34. data/app/views/madmin/fields/date/_show.html.erb +1 -0
  35. data/app/views/madmin/fields/date_time/_form.html.erb +2 -0
  36. data/app/views/madmin/fields/date_time/_index.html.erb +1 -0
  37. data/app/views/madmin/fields/date_time/_show.html.erb +1 -0
  38. data/app/views/madmin/fields/enum/_form.html.erb +3 -0
  39. data/app/views/madmin/fields/enum/_index.html.erb +1 -0
  40. data/app/views/madmin/fields/enum/_show.html.erb +1 -0
  41. data/app/views/madmin/fields/float/_form.html.erb +2 -0
  42. data/app/views/madmin/fields/float/_index.html.erb +1 -0
  43. data/app/views/madmin/fields/float/_show.html.erb +1 -0
  44. data/app/views/madmin/fields/has_many/_form.html.erb +2 -0
  45. data/app/views/madmin/fields/has_many/_index.html.erb +1 -0
  46. data/app/views/madmin/fields/has_many/_show.html.erb +4 -14
  47. data/app/views/madmin/fields/has_one/_form.html.erb +3 -0
  48. data/app/views/madmin/fields/has_one/_index.html.erb +3 -0
  49. data/app/views/madmin/fields/has_one/_show.html.erb +3 -12
  50. data/app/views/madmin/fields/integer/_form.html.erb +2 -0
  51. data/app/views/madmin/fields/integer/_index.html.erb +1 -0
  52. data/app/views/madmin/fields/integer/_show.html.erb +1 -0
  53. data/app/views/madmin/fields/json/_form.html.erb +2 -0
  54. data/app/views/madmin/fields/json/_index.html.erb +1 -0
  55. data/app/views/madmin/fields/json/_show.html.erb +1 -0
  56. data/app/views/madmin/fields/polymorphic/_form.html.erb +5 -32
  57. data/app/views/madmin/fields/polymorphic/_index.html.erb +3 -1
  58. data/app/views/madmin/fields/polymorphic/_show.html.erb +3 -14
  59. data/app/views/madmin/fields/rich_text/_form.html.erb +4 -0
  60. data/app/views/madmin/fields/rich_text/_index.html.erb +1 -0
  61. data/app/views/madmin/fields/rich_text/_show.html.erb +3 -0
  62. data/app/views/madmin/fields/string/_form.html.erb +2 -0
  63. data/app/views/madmin/fields/string/_index.html.erb +1 -0
  64. data/app/views/madmin/fields/string/_show.html.erb +1 -0
  65. data/app/views/madmin/fields/text/_form.html.erb +2 -4
  66. data/app/views/madmin/fields/text/_index.html.erb +1 -1
  67. data/app/views/madmin/fields/text/_show.html.erb +1 -8
  68. data/app/views/madmin/fields/time/_form.html.erb +2 -0
  69. data/app/views/madmin/fields/time/_index.html.erb +1 -0
  70. data/app/views/madmin/fields/time/_show.html.erb +1 -0
  71. data/lib/generators/madmin/install/install_generator.rb +24 -12
  72. data/lib/generators/madmin/resource/resource_generator.rb +83 -47
  73. data/lib/generators/madmin/resource/templates/controller.rb.tt +4 -0
  74. data/lib/generators/madmin/resource/templates/resource.rb.tt +11 -0
  75. data/lib/madmin.rb +33 -23
  76. data/lib/madmin/engine.rb +5 -2
  77. data/lib/madmin/field.rb +18 -47
  78. data/lib/madmin/fields/attachment.rb +6 -0
  79. data/lib/madmin/fields/attachments.rb +9 -0
  80. data/lib/madmin/fields/belongs_to.rb +18 -0
  81. data/lib/madmin/fields/boolean.rb +6 -0
  82. data/lib/madmin/fields/date.rb +6 -0
  83. data/lib/madmin/fields/date_time.rb +6 -0
  84. data/lib/madmin/fields/enum.rb +6 -0
  85. data/lib/madmin/fields/float.rb +6 -0
  86. data/lib/madmin/fields/has_many.rb +18 -0
  87. data/lib/madmin/fields/has_one.rb +6 -0
  88. data/lib/madmin/fields/integer.rb +6 -0
  89. data/lib/madmin/fields/json.rb +6 -0
  90. data/lib/madmin/fields/polymorphic.rb +17 -0
  91. data/lib/madmin/fields/rich_text.rb +6 -0
  92. data/lib/madmin/fields/string.rb +6 -0
  93. data/lib/madmin/fields/text.rb +6 -0
  94. data/lib/madmin/fields/time.rb +6 -0
  95. data/lib/madmin/generator_helpers.rb +24 -0
  96. data/lib/madmin/resource.rb +125 -0
  97. data/lib/madmin/version.rb +1 -1
  98. data/lib/tasks/madmin_tasks.rake +7 -0
  99. metadata +90 -97
  100. data/app/assets/config/madmin_manifest.js +0 -2
  101. data/app/assets/javascripts/madmin/application.js +0 -15
  102. data/app/assets/javascripts/madmin/dashboard.js +0 -2
  103. data/app/assets/javascripts/madmin/resources.js +0 -36
  104. data/app/assets/stylesheets/madmin/dashboard.css +0 -4
  105. data/app/assets/stylesheets/madmin/resources.css +0 -4
  106. data/app/controllers/madmin/base_controller.rb +0 -16
  107. data/app/controllers/madmin/resources_controller.rb +0 -97
  108. data/app/decorators/madmin/resource_decorator.rb +0 -16
  109. data/app/helpers/madmin/fields/polymorphic_helper.rb +0 -25
  110. data/app/jobs/madmin/application_job.rb +0 -4
  111. data/app/mailers/madmin/application_mailer.rb +0 -6
  112. data/app/models/madmin/application_record.rb +0 -5
  113. data/app/views/application/_navigation.html.erb +0 -17
  114. data/app/views/madmin/dashboard/index.html.erb +0 -6
  115. data/app/views/madmin/fields/check_box/_form.html.erb +0 -4
  116. data/app/views/madmin/fields/check_box/_index.html.erb +0 -1
  117. data/app/views/madmin/fields/check_box/_show.html.erb +0 -8
  118. data/app/views/madmin/fields/email/_form.html.erb +0 -4
  119. data/app/views/madmin/fields/email/_index.html.erb +0 -1
  120. data/app/views/madmin/fields/email/_show.html.erb +0 -8
  121. data/app/views/madmin/fields/number/_form.html.erb +0 -4
  122. data/app/views/madmin/fields/number/_index.html.erb +0 -1
  123. data/app/views/madmin/fields/number/_show.html.erb +0 -8
  124. data/app/views/madmin/fields/password/_form.html.erb +0 -4
  125. data/app/views/madmin/fields/password/_index.html.erb +0 -1
  126. data/app/views/madmin/fields/password/_show.html.erb +0 -8
  127. data/app/views/madmin/fields/select/_form.html.erb +0 -4
  128. data/app/views/madmin/fields/select/_index.html.erb +0 -1
  129. data/app/views/madmin/fields/select/_show.html.erb +0 -8
  130. data/app/views/madmin/fields/text_area/_form.html.erb +0 -4
  131. data/app/views/madmin/fields/text_area/_index.html.erb +0 -1
  132. data/app/views/madmin/fields/text_area/_show.html.erb +0 -8
  133. data/app/views/madmin/resources/_form.html.erb +0 -15
  134. data/app/views/madmin/resources/_scopes.html.erb +0 -10
  135. data/app/views/madmin/resources/edit.html.erb +0 -2
  136. data/app/views/madmin/resources/index.html.erb +0 -13
  137. data/app/views/madmin/resources/index/_content.html.erb +0 -33
  138. data/app/views/madmin/resources/new.html.erb +0 -2
  139. data/app/views/madmin/resources/show.html.erb +0 -10
  140. data/config/routes.rb +0 -11
  141. data/lib/generators/madmin/controller/USAGE +0 -8
  142. data/lib/generators/madmin/controller/controller_generator.rb +0 -10
  143. data/lib/generators/madmin/page/USAGE +0 -8
  144. data/lib/generators/madmin/page/page_generator.rb +0 -20
  145. data/lib/generators/madmin/page/templates/template.html.erb +0 -2
  146. data/lib/generators/madmin/page/templates/template.rb.erb +0 -10
  147. data/lib/generators/madmin/resource/templates/resource.rb.erb +0 -11
  148. data/lib/generators/madmin/views/views_generator.rb +0 -15
  149. data/lib/madmin/field/associatable.rb +0 -58
  150. data/lib/madmin/field/belongs_to.rb +0 -9
  151. data/lib/madmin/field/check_box.rb +0 -8
  152. data/lib/madmin/field/date_time.rb +0 -8
  153. data/lib/madmin/field/email.rb +0 -8
  154. data/lib/madmin/field/has_many.rb +0 -9
  155. data/lib/madmin/field/has_one.rb +0 -9
  156. data/lib/madmin/field/number.rb +0 -8
  157. data/lib/madmin/field/password.rb +0 -8
  158. data/lib/madmin/field/polymorphic.rb +0 -57
  159. data/lib/madmin/field/select.rb +0 -13
  160. data/lib/madmin/field/text.rb +0 -8
  161. data/lib/madmin/field/text_area.rb +0 -8
  162. data/lib/madmin/resourceable.rb +0 -72
  163. data/lib/madmin/resourceable/class_methods.rb +0 -152
  164. data/lib/madmin/resources.rb +0 -13
@@ -0,0 +1,4 @@
1
+ module Madmin
2
+ class <%= class_name.pluralize %>Controller < Madmin::ResourceController
3
+ end
4
+ end
@@ -0,0 +1,11 @@
1
+ class <%= class_name %>Resource < Madmin::Resource
2
+ # Attributes
3
+ <% attributes.each do |attribute_name| -%>
4
+ attribute :<%= attribute_name %><%= formatted_options_for_attribute(attribute_name) %>
5
+ <% end -%>
6
+
7
+ # Associations
8
+ <% associations.each do |association_name| -%>
9
+ attribute :<%= association_name %>
10
+ <% end -%>
11
+ end
@@ -1,30 +1,40 @@
1
1
  require "madmin/engine"
2
- require "madmin/resourceable"
3
- require "madmin/resources"
2
+
3
+ require "pagy"
4
4
 
5
5
  module Madmin
6
- class NoResourcesError < StandardError; end
7
- class ResourceNotFoundError < StandardError; end
8
- class WrongArgumentError < StandardError; end
9
- class UndefinedScopeError < StandardError; end
10
- class ScopeWithArgumentsError < StandardError; end
6
+ autoload :Field, "madmin/field"
7
+ autoload :GeneratorHelpers, "madmin/generator_helpers"
8
+ autoload :Resource, "madmin/resource"
9
+
10
+ module Fields
11
+ autoload :Boolean, "madmin/fields/boolean"
12
+ autoload :Integer, "madmin/fields/integer"
13
+ autoload :String, "madmin/fields/string"
14
+ autoload :Text, "madmin/fields/text"
15
+ autoload :Date, "madmin/fields/date"
16
+ autoload :DateTime, "madmin/fields/date_time"
17
+ autoload :Json, "madmin/fields/json"
18
+ autoload :Enum, "madmin/fields/enum"
19
+ autoload :Float, "madmin/fields/float"
20
+ autoload :Time, "madmin/fields/time"
21
+ autoload :BelongsTo, "madmin/fields/belongs_to"
22
+ autoload :Polymorphic, "madmin/fields/polymorphic"
23
+ autoload :HasMany, "madmin/fields/has_many"
24
+ autoload :HasOne, "madmin/fields/has_one"
25
+ autoload :RichText, "madmin/fields/rich_text"
26
+ autoload :Attachment, "madmin/fields/attachment"
27
+ autoload :Attachments, "madmin/fields/attachments"
28
+ end
29
+
30
+ mattr_accessor :resources, default: []
11
31
 
12
- autoload :Field, "madmin/field"
13
- autoload :Resourceable, "madmin/resourceable"
32
+ class << self
33
+ def resource_for(object)
34
+ Rails.application.eager_load!
14
35
 
15
- class Field
16
- autoload :Associatable, "madmin/field/associatable"
17
- autoload :BelongsTo, "madmin/field/belongs_to"
18
- autoload :CheckBox, "madmin/field/check_box"
19
- autoload :DateTime, "madmin/field/date_time"
20
- autoload :Email, "madmin/field/email"
21
- autoload :HasMany, "madmin/field/has_many"
22
- autoload :HasOne, "madmin/field/has_one"
23
- autoload :Number, "madmin/field/number"
24
- autoload :Password, "madmin/field/password"
25
- autoload :Polymorphic, "madmin/field/polymorphic"
26
- autoload :Select, "madmin/field/select"
27
- autoload :TextArea, "madmin/field/text_area"
28
- autoload :Text, "madmin/field/text"
36
+ klass_name = object.class.name
37
+ Madmin.resources.find { |r| r.model_name == klass_name }
38
+ end
29
39
  end
30
40
  end
@@ -1,9 +1,12 @@
1
1
  module Madmin
2
2
  class Engine < ::Rails::Engine
3
- isolate_namespace Madmin
3
+ initializer "madmin.autoload", before: :set_autoload_paths do |app|
4
+ app.config.paths.add "app/madmin/resources", eager_load: true
5
+ app.config.paths.add "app/madmin/fields", eager_load: true
6
+ end
4
7
 
5
8
  config.to_prepare do
6
- Dir.glob("#{Rails.root}/app/madmin/**/*.rb").each { |r| require_dependency(r) }
9
+ Madmin.resources = []
7
10
  end
8
11
  end
9
12
  end
@@ -1,64 +1,35 @@
1
1
  module Madmin
2
2
  class Field
3
- attr_reader :form
4
- attr_reader :index
5
- attr_reader :key
6
- attr_reader :label
7
- attr_reader :model
8
- attr_reader :options
9
- attr_reader :show
10
- attr_reader :type
3
+ attr_reader :attribute_name, :options
11
4
 
12
- def initialize(args)
13
- @key = args[:key]
14
- @options = args
15
- @model = args[:model]
16
- @label = option_or_default(:label, label_from_attribute(key))
17
- @form = option_or_default(:form, false)
18
- @index = option_or_default(:index, false)
19
- @show = option_or_default(:show, true)
5
+ def self.field_type
6
+ to_s.split("::").last.underscore
20
7
  end
21
8
 
22
- ##
23
- # Returns an array of key(s) to use in strong
24
- # params for the resources controller.
25
- def strong_params_keys
26
- [key]
9
+ def initialize(attribute_name:, **options)
10
+ @attribute_name = attribute_name
11
+ @options = options
27
12
  end
28
13
 
29
- ##
30
- # Returns the partial path for the field type
31
- def to_partial_path
32
- "madmin/fields/#{self.class.to_s.split("Madmin::Field::").last.underscore}"
14
+ def value(record)
15
+ record.public_send(attribute_name)
33
16
  end
34
17
 
35
- ##
36
- # Returns the value for a given resource
37
- def value_for(resource)
38
- resource.send(key)
39
- end
40
-
41
- private
18
+ def to_partial_path(name)
19
+ unless %w[index show form].include? name
20
+ raise ArgumentError, "`partial` must be 'index', 'show', or 'form'"
21
+ end
42
22
 
43
- ##
44
- # This method takes an attribute and converts it
45
- # into a human readable format for form labels.
46
- def label_from_attribute(attribute)
47
- attribute.to_s.humanize
23
+ "/madmin/fields/#{self.class.field_type}/#{name}"
48
24
  end
49
25
 
50
- ##
51
- # This method verifies options are present
52
- # (as a hash).
53
- def options?
54
- options.is_a?(Hash)
26
+ def to_param
27
+ attribute_name
55
28
  end
56
29
 
57
- ##
58
- # This method extracts the many option checks
59
- # performed when assigning field options.
60
- def option_or_default(key, default)
61
- options? ? options.fetch(key, default) : default
30
+ # Used for checking visibility of attribute on an view
31
+ def visible?(action, default: true)
32
+ options.fetch(action.to_sym, default)
62
33
  end
63
34
  end
64
35
  end
@@ -0,0 +1,6 @@
1
+ module Madmin
2
+ module Fields
3
+ class Attachment < Field
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,9 @@
1
+ module Madmin
2
+ module Fields
3
+ class Attachments < Field
4
+ def to_param
5
+ {attribute_name => []}
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,18 @@
1
+ module Madmin
2
+ module Fields
3
+ class BelongsTo < Field
4
+ def options_for_select(record)
5
+ association = record.class.reflect_on_association(attribute_name)
6
+
7
+ klass = association.klass
8
+ klass.all.map do |r|
9
+ ["#{klass.name} ##{r.id}", r.id]
10
+ end
11
+ end
12
+
13
+ def to_param
14
+ "#{attribute_name}_id"
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,6 @@
1
+ module Madmin
2
+ module Fields
3
+ class Boolean < Field
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Madmin
2
+ module Fields
3
+ class Date < Field
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Madmin
2
+ module Fields
3
+ class DateTime < Field
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Madmin
2
+ module Fields
3
+ class Enum < Field
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Madmin
2
+ module Fields
3
+ class Float < Field
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,18 @@
1
+ module Madmin
2
+ module Fields
3
+ class HasMany < Field
4
+ def options_for_select(record)
5
+ association = record.class.reflect_on_association(attribute_name)
6
+
7
+ klass = association.klass
8
+ klass.all.map do |r|
9
+ ["#{klass.name} ##{r.id}", r.id]
10
+ end
11
+ end
12
+
13
+ def to_param
14
+ {"#{attribute_name.to_s.singularize}_ids".to_sym => []}
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,6 @@
1
+ module Madmin
2
+ module Fields
3
+ class HasOne < Field
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Madmin
2
+ module Fields
3
+ class Integer < Field
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Madmin
2
+ module Fields
3
+ class Json < Field
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,17 @@
1
+ module Madmin
2
+ module Fields
3
+ class Polymorphic < Field
4
+ def options_for_select(record)
5
+ if (collection = options[:collection])
6
+ collection.call
7
+ else
8
+ []
9
+ end
10
+ end
11
+
12
+ def to_param
13
+ {attribute_name => %i[type value]}
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,6 @@
1
+ module Madmin
2
+ module Fields
3
+ class RichText < Field
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Madmin
2
+ module Fields
3
+ class String < Field
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Madmin
2
+ module Fields
3
+ class Text < Field
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Madmin
2
+ module Fields
3
+ class Time < Field
4
+ end
5
+ end
6
+ end
@@ -4,6 +4,30 @@ module Madmin
4
4
  Rails::Generators.invoke(generator, args, generator_options)
5
5
  end
6
6
 
7
+ def route_namespace_exists?
8
+ File.readlines(Rails.root.join("config/routes.rb")).grep(/namespace :madmin/).size > 0
9
+ end
10
+
11
+ # Method copied from Rails 6.1 master
12
+ def route(routing_code, namespace: nil, sentinel: nil, indentation: 2)
13
+ routing_code = Array(namespace).reverse.reduce(routing_code) { |code, ns|
14
+ "namespace :#{ns} do\n#{indent(code, 2)}\nend"
15
+ }
16
+
17
+ log :route, routing_code
18
+ sentinel ||= /\.routes\.draw do\s*\n/m
19
+
20
+ in_root do
21
+ inject_into_file "config/routes.rb", optimize_indentation(routing_code, indentation), after: sentinel, verbose: false, force: false
22
+ end
23
+ end
24
+
25
+ # Method copied from Rails 6.1 master
26
+ def optimize_indentation(value, amount = 0)
27
+ return "#{value}\n" unless value.is_a?(String)
28
+ "#{value.strip_heredoc.indent(amount).chomp}\n"
29
+ end
30
+
7
31
  private
8
32
 
9
33
  def generator_options
@@ -0,0 +1,125 @@
1
+ module Madmin
2
+ class Resource
3
+ class_attribute :attributes, default: []
4
+ class_attribute :scopes, default: []
5
+
6
+ class << self
7
+ def inherited(base)
8
+ # Remove any old references
9
+ Madmin.resources.delete(base)
10
+ Madmin.resources << base
11
+
12
+ base.attributes = attributes.dup
13
+ base.scopes = scopes.dup
14
+ super
15
+ end
16
+
17
+ def model
18
+ model_name.constantize
19
+ end
20
+
21
+ def model_name
22
+ to_s.chomp("Resource").classify
23
+ end
24
+
25
+ def scope(name)
26
+ scopes << name
27
+ end
28
+
29
+ def attribute(name, type = nil, **options)
30
+ attributes << {
31
+ name: name,
32
+ field: field_for_type(name, type).new(**options.merge(attribute_name: name))
33
+ }
34
+ end
35
+
36
+ def friendly_name
37
+ model_name.gsub("::", " / ")
38
+ end
39
+
40
+ def index_path
41
+ "/madmin/#{model.model_name.collection}"
42
+ end
43
+
44
+ def new_path
45
+ "/madmin/#{model.model_name.collection}/new"
46
+ end
47
+
48
+ def show_path(record)
49
+ "/madmin/#{model.model_name.collection}/#{record.id}"
50
+ end
51
+
52
+ def edit_path(record)
53
+ "/madmin/#{model.model_name.collection}/#{record.id}/edit"
54
+ end
55
+
56
+ def param_key
57
+ model.model_name.param_key
58
+ end
59
+
60
+ def permitted_params
61
+ attributes.map { |a| a[:field].to_param }
62
+ end
63
+
64
+ def display_name(record)
65
+ "#{record.class} ##{record.id}"
66
+ end
67
+
68
+ private
69
+
70
+ def field_for_type(name, type)
71
+ type ||= infer_type(name)
72
+
73
+ {
74
+ date: Fields::Date,
75
+ datetime: Fields::DateTime,
76
+ enum: Fields::Enum,
77
+ float: Fields::Float,
78
+ integer: Fields::Integer,
79
+ json: Fields::Json,
80
+ string: Fields::String,
81
+ text: Fields::Text,
82
+ time: Fields::Time,
83
+ boolean: Fields::Boolean,
84
+
85
+ # Associations
86
+ attachment: Fields::Attachment,
87
+ attachments: Fields::Attachments,
88
+ belongs_to: Fields::BelongsTo,
89
+ polymorphic: Fields::Polymorphic,
90
+ has_many: Fields::HasMany,
91
+ has_one: Fields::HasOne,
92
+ rich_text: Fields::RichText
93
+ }.fetch(type)
94
+ end
95
+
96
+ def infer_type(name)
97
+ name_string = name.to_s
98
+
99
+ if model.attribute_types.include?(name_string)
100
+ model.attribute_types[name_string].type || :string
101
+ elsif (association = model.reflect_on_association(name))
102
+ type_for_association(association)
103
+ elsif model.reflect_on_association(:"rich_text_#{name_string}")
104
+ :rich_text
105
+ elsif model.reflect_on_association(:"#{name_string}_attachment")
106
+ :attachment
107
+ elsif model.reflect_on_association(:"#{name_string}_attachments")
108
+ :attachments
109
+ end
110
+ end
111
+
112
+ def type_for_association(association)
113
+ if association.has_one?
114
+ :has_one
115
+ elsif association.collection?
116
+ :has_many
117
+ elsif association.polymorphic?
118
+ :polymorphic
119
+ else
120
+ :belongs_to
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end