cm-admin 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/CODE_OF_CONDUCT.md +74 -0
  3. data/Gemfile +1 -0
  4. data/Gemfile.lock +21 -20
  5. data/README.md +24 -1
  6. data/app/assets/stylesheets/cm_admin/base/auth.scss +0 -12
  7. data/app/assets/stylesheets/cm_admin/base/filters.scss +8 -7
  8. data/app/assets/stylesheets/cm_admin/base/form.scss +7 -72
  9. data/app/assets/stylesheets/cm_admin/base/navbar.scss +1 -3
  10. data/app/assets/stylesheets/cm_admin/base/quicksearch.scss +7 -0
  11. data/app/assets/stylesheets/cm_admin/base/scaffold.scss +38 -3
  12. data/app/assets/stylesheets/cm_admin/base/show.scss +24 -2
  13. data/app/assets/stylesheets/cm_admin/base/table.scss +270 -253
  14. data/app/assets/stylesheets/cm_admin/components/_dropdown-popup.scss +22 -10
  15. data/app/assets/stylesheets/cm_admin/components/_range.scss +13 -2
  16. data/app/assets/stylesheets/cm_admin/components/_status-tag.scss +2 -1
  17. data/app/assets/stylesheets/cm_admin/helpers/_variable.scss +1 -0
  18. data/app/controllers/cm_admin/application_controller.rb +5 -0
  19. data/app/controllers/cm_admin/exports_controller.rb +1 -1
  20. data/app/controllers/cm_admin/static_controller.rb +12 -0
  21. data/app/helpers/cm_admin/custom_helper.rb +4 -0
  22. data/app/javascript/packs/cm_admin/application.js +14 -1
  23. data/app/javascript/packs/cm_admin/filters.js +331 -16
  24. data/app/javascript/packs/cm_admin/quick_search.js +67 -0
  25. data/app/javascript/packs/cm_admin/scaffolds.js +30 -1
  26. data/app/javascript/stylesheets/cm_admin/application.scss +3 -0
  27. data/app/views/cm_admin/main/_associated_table.html.slim +60 -0
  28. data/app/views/cm_admin/main/_cm_pagy_nav.html.slim +6 -6
  29. data/app/views/cm_admin/main/_filters.html.slim +1 -10
  30. data/app/views/cm_admin/main/_nested_fields.html.slim +7 -0
  31. data/app/views/cm_admin/main/_nested_table_form.html.slim +6 -0
  32. data/app/views/cm_admin/main/_table.html.slim +5 -4
  33. data/app/views/cm_admin/main/_tabs.html.slim +5 -0
  34. data/app/views/cm_admin/main/_top_navbar.html.slim +4 -4
  35. data/app/views/cm_admin/main/associated_index.html.slim +6 -0
  36. data/app/views/cm_admin/main/associated_show.html.slim +6 -0
  37. data/app/views/cm_admin/main/index.html.slim +11 -8
  38. data/app/views/cm_admin/main/show.html.slim +12 -13
  39. data/app/views/cm_admin/static/error_401.html.slim +4 -0
  40. data/app/views/layouts/_left_sidebar_nav.html.slim +7 -3
  41. data/app/views/layouts/_quick_links.html.slim +25 -0
  42. data/app/views/layouts/cm_admin.html.slim +24 -1
  43. data/app/views/layouts/static.html.slim +18 -0
  44. data/bin/console +0 -1
  45. data/cm_admin.gemspec +1 -0
  46. data/config/routes.rb +2 -1
  47. data/config/webpack/environment.js +3 -2
  48. data/lib/.DS_Store +0 -0
  49. data/lib/cm_admin/model.rb +57 -167
  50. data/lib/cm_admin/models/action.rb +15 -1
  51. data/lib/cm_admin/models/cm_show_section.rb +20 -0
  52. data/lib/cm_admin/models/column.rb +49 -4
  53. data/lib/cm_admin/models/controller_method.rb +75 -0
  54. data/lib/cm_admin/models/dsl_method.rb +122 -0
  55. data/lib/cm_admin/models/export.rb +16 -5
  56. data/lib/cm_admin/models/field.rb +2 -1
  57. data/lib/cm_admin/models/filter.rb +67 -2
  58. data/lib/cm_admin/models/form_field.rb +21 -0
  59. data/lib/cm_admin/models/tab.rb +13 -0
  60. data/lib/cm_admin/version.rb +1 -1
  61. data/lib/cm_admin/view_helpers/column_field_helper.rb +29 -0
  62. data/lib/cm_admin/view_helpers/field_display_helper.rb +65 -0
  63. data/lib/cm_admin/view_helpers/filter_helper.rb +190 -0
  64. data/lib/cm_admin/view_helpers/form_field_helper.rb +21 -4
  65. data/lib/cm_admin/view_helpers/form_helper.rb +22 -12
  66. data/lib/cm_admin/view_helpers/manage_column_popup_helper.rb +75 -0
  67. data/lib/cm_admin/view_helpers/navigation_helper.rb +22 -6
  68. data/lib/cm_admin/view_helpers/page_info_helper.rb +36 -0
  69. data/lib/cm_admin/view_helpers.rb +3 -1
  70. data/lib/cm_admin.rb +3 -1
  71. data/lib/generators/cm_admin/install_generator.rb +20 -8
  72. data/package.json +6 -1
  73. data/tmp/cache/webpacker/last-compilation-digest-development +1 -0
  74. data/yarn.lock +35 -5
  75. metadata +41 -7
  76. data/app/controllers/cm_admin/main_controller.rb +0 -8
  77. data/lib/c.png +0 -0
  78. data/lib/cm_admin/view_helpers/field_column_helper.rb +0 -23
  79. data/lib/generators/cm_admin/templates/cm_admin_initializer.rb +0 -4
  80. data/yarn-error.log +0 -44
@@ -0,0 +1,75 @@
1
+ module CmAdmin
2
+ module Models
3
+ module ControllerMethod
4
+ extend ActiveSupport::Concern
5
+
6
+ def show(params)
7
+ @current_action = CmAdmin::Models::Action.find_by(self, name: 'show')
8
+ @ar_object = @ar_model.find(params[:id])
9
+ end
10
+
11
+ def index(params)
12
+ @current_action = CmAdmin::Models::Action.find_by(self, name: 'index')
13
+ # Based on the params the filter and pagination object to be set
14
+ @ar_object = filter_by(params, nil, filter_params(params))
15
+ end
16
+
17
+ def new(params)
18
+ @current_action = CmAdmin::Models::Action.find_by(self, name: 'new')
19
+ @ar_object = @ar_model.new
20
+ end
21
+
22
+ def edit(params)
23
+ @current_action = CmAdmin::Models::Action.find_by(self, name: 'edit')
24
+ @ar_object = @ar_model.find(params[:id])
25
+ end
26
+
27
+ def update(params)
28
+ @ar_object = @ar_model.find(params[:id])
29
+ @ar_object.assign_attributes(resource_params(params))
30
+ @ar_object
31
+ end
32
+
33
+ def create(params)
34
+ @ar_object = @ar_model.new(resource_params(params))
35
+ end
36
+
37
+ def filter_by(params, records, filter_params={}, sort_params={})
38
+ filtered_result = OpenStruct.new
39
+ sort_column = "created_at"
40
+ sort_direction = %w[asc desc].include?(sort_params[:sort_direction]) ? sort_params[:sort_direction] : "asc"
41
+ sort_params = {sort_column: sort_column, sort_direction: sort_direction}
42
+ records = self.name.constantize.where(nil) if records.nil?
43
+ final_data = CmAdmin::Models::Filter.filtered_data(filter_params, records, @filters)
44
+ pagy, records = pagy(final_data)
45
+ filtered_result.data = records
46
+ filtered_result.pagy = pagy
47
+ # filtered_result.facets = paginate(page, raw_data.size)
48
+ # filtered_result.sort = sort_params
49
+ # filtered_result.facets.sort = sort_params
50
+ return filtered_result
51
+ end
52
+
53
+ def resource_params(params)
54
+ permittable_fields = @permitted_fields || @ar_model.columns.map(&:name).reject { |i| CmAdmin::REJECTABLE_FIELDS.include?(i) }.map(&:to_sym)
55
+ permittable_fields += @ar_model.reflect_on_all_attachments.map {|x|
56
+ if x.class.name.include?('HasOne')
57
+ x.name
58
+ elsif x.class.name.include?('HasMany')
59
+ Hash[x.name.to_s, []]
60
+ end
61
+ }.compact
62
+ nested_tables = self.available_fields[:new].except(:fields).keys
63
+ nested_tables += self.available_fields[:edit].except(:fields).keys
64
+ nested_fields = nested_tables.map {|table|
65
+ Hash[
66
+ table.to_s + '_attributes',
67
+ table.to_s.singularize.titleize.constantize.columns.map(&:name).reject { |i| CmAdmin::REJECTABLE_FIELDS.include?(i) }.map(&:to_sym) + [:id, :_destroy]
68
+ ]
69
+ }
70
+ permittable_fields += nested_fields
71
+ params.require(self.name.underscore.to_sym).permit(*permittable_fields)
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,122 @@
1
+ module CmAdmin
2
+ module Models
3
+ module DslMethod
4
+ extend ActiveSupport::Concern
5
+
6
+ def cm_index(page_title: nil ,page_description: nil, &block)
7
+ @current_action = CmAdmin::Models::Action.find_by(self, name: 'index')
8
+ @current_action.page_title = page_title
9
+ @current_action.page_description = page_description
10
+ yield
11
+ # action.instance_eval(&block)
12
+ end
13
+
14
+ def cm_show(page_title: nil,page_description: nil,&block)
15
+ @current_action = CmAdmin::Models::Action.find_by(self, name: 'show')
16
+ @current_action.page_title = page_title
17
+ @current_action.page_description = page_description
18
+ yield
19
+ end
20
+
21
+ def cm_edit(page_title: nil,page_description: nil, &block)
22
+ @current_action = CmAdmin::Models::Action.find_by(self, name: 'edit')
23
+ @current_action.page_title = page_title
24
+ @current_action.page_description = page_description
25
+ yield
26
+ end
27
+
28
+ def cm_new(page_title: nil,page_description: nil,&block)
29
+ @current_action = CmAdmin::Models::Action.find_by(self, name: 'new')
30
+ @current_action.page_title = page_title
31
+ @current_action.page_description = page_description
32
+ yield
33
+ end
34
+
35
+ def page_title(title)
36
+ if @current_action
37
+ @current_action.page_title = title
38
+ end
39
+ end
40
+
41
+ def page_description(description)
42
+ if @current_action
43
+ @current_action.page_description = description
44
+ end
45
+ end
46
+
47
+ def tab(tab_name, custom_action, associated_model: nil, layout_type: nil, layout: nil, partial: nil, &block)
48
+ if custom_action.to_s == ''
49
+ @current_action = CmAdmin::Models::Action.find_by(self, name: 'show')
50
+ @available_tabs << CmAdmin::Models::Tab.new(tab_name, '', &block)
51
+ else
52
+ action = CmAdmin::Models::Action.new(name: custom_action.to_s, verb: :get, path: ':id/'+custom_action, layout_type: layout_type, layout: layout, partial: partial, child_records: associated_model)
53
+ @available_actions << action
54
+ @current_action = action
55
+ @available_tabs << CmAdmin::Models::Tab.new(tab_name, custom_action, &block)
56
+ end
57
+ yield if block
58
+ end
59
+
60
+ def cm_show_section(section_name, &block)
61
+ @available_fields[@current_action.name.to_sym] ||= []
62
+ @available_fields[@current_action.name.to_sym] << CmAdmin::Models::CmShowSection.new(section_name, &block)
63
+ end
64
+
65
+ def form_field(field_name, options={}, arg=nil)
66
+ unless @current_action.is_nested_field
67
+ @available_fields[@current_action.name.to_sym][:fields] << CmAdmin::Models::FormField.new(field_name, options[:input_type], options)
68
+ else
69
+ @available_fields[@current_action.name.to_sym][@current_action.nested_table_name] ||= []
70
+ @available_fields[@current_action.name.to_sym][@current_action.nested_table_name] << CmAdmin::Models::FormField.new(field_name, options[:input_type], options)
71
+ end
72
+ end
73
+
74
+ def nested_form_field(field_name, &block)
75
+ @current_action.is_nested_field = true
76
+ @current_action.nested_table_name = field_name
77
+ yield
78
+ end
79
+
80
+ def column(field_name, options={})
81
+ @available_fields[@current_action.name.to_sym] ||= []
82
+ if @available_fields[@current_action.name.to_sym].select{|x| x.lockable}.size > 0 && options[:lockable]
83
+ raise "Only one column can be locked in a table."
84
+ end
85
+ unless @available_fields[@current_action.name.to_sym].map{|x| x.field_name.to_sym}.include?(field_name)
86
+ @available_fields[@current_action.name.to_sym] << CmAdmin::Models::Column.new(field_name, options)
87
+ end
88
+ end
89
+
90
+ def all_db_columns(options={})
91
+ field_names = self.instance_variable_get(:@ar_model)&.columns&.map{|x| x.name.to_sym}
92
+ if options.include?(:exclude) && field_names
93
+ excluded_fields = (Array.new << options[:exclude]).flatten.map(&:to_sym)
94
+ field_names -= excluded_fields
95
+ end
96
+ field_names.each do |field_name|
97
+ column field_name
98
+ end
99
+ end
100
+
101
+ # Custom actions
102
+ # eg
103
+ # class User < ApplicationRecord
104
+ # cm_admin do
105
+ # custom_action name: 'submit', verb: 'post', path: ':id/submit' do
106
+ # def user_submit
107
+ # Code for action here...
108
+ # end
109
+ # end
110
+ # end
111
+ # end
112
+ def custom_action(name: nil, verb: nil, layout: nil, partial: nil, path: nil, &block)
113
+ @available_actions << CmAdmin::Models::Action.new(name: name, verb: verb, layout: layout, partial: partial, path: path)
114
+ self.class.class_eval(&block)
115
+ end
116
+
117
+ def filter(db_column_name, filter_type, options={})
118
+ @filters << CmAdmin::Models::Filter.new(db_column_name: db_column_name, filter_type: filter_type, options: options)
119
+ end
120
+ end
121
+ end
122
+ end
@@ -2,19 +2,30 @@ module CmAdmin
2
2
  module Models
3
3
  class Export
4
4
  class << self
5
- def generate_excel(klass_name, columns = [])
5
+ def generate_excel(klass_name, columns = [], helpers)
6
6
  klass = klass_name.constantize
7
- records = get_records(klass, columns)
7
+ model = CmAdmin::Model.find_by({name: klass_name})
8
+ records = get_records(klass, model, columns, helpers)
8
9
  file_path = "#{Rails.root}/tmp/#{klass}_data_#{DateTime.now.strftime("%Y-%m-%d_%H-%M-%S")}.xlsx"
9
10
  create_workbook(records, columns, file_path)
10
11
  return file_path
11
12
  end
12
13
 
13
- def get_records(klass, columns)
14
+ def get_records(klass, model, columns, helpers)
14
15
  records = klass
16
+ custom_fields = model.available_fields[:index].map{|field| field if field.field_type == :custom}.compact
17
+ normal_fields = model.available_fields[:index].map{|field| field unless field.field_type == :custom}.compact
15
18
  deserialized_columns = CmAdmin::Utils.deserialize_csv_columns(columns, :as_json_params)
16
19
  # This includes isn't recursve, a full solution should be recursive
17
- records.includes(deserialized_columns[:include].keys).find_each.as_json(deserialized_columns)
20
+ records_arr = []
21
+ records.includes(deserialized_columns[:include].keys).find_each do |record|
22
+ record_hash = record.as_json({only: normal_fields.map(&:field_name)})
23
+ custom_fields.each do |field|
24
+ record_hash[field.field_name.to_sym] = helpers.send(field.helper_method, record, field.field_name)
25
+ end
26
+ records_arr << record_hash
27
+ end
28
+ records_arr
18
29
  end
19
30
 
20
31
  def create_workbook(records, class_name, file_path)
@@ -34,7 +45,7 @@ module CmAdmin
34
45
  end
35
46
 
36
47
  def exportable_columns(klass)
37
- klass.available_fields[:index].map{|x| x.exportable ? x.db_column_name : ""}.reject { |c| c.empty? }
48
+ klass.available_fields[:index].map{|x| x.exportable ? x.field_name : ""}.reject { |c| c.empty? }
38
49
  end
39
50
 
40
51
  end
@@ -1,7 +1,8 @@
1
1
  module CmAdmin
2
2
  module Models
3
3
  class Field
4
- attr_accessor :field_name, :label, :header
4
+
5
+ attr_accessor :field_name, :label, :header, :field_type, :format, :precision, :helper_method, :preview, :custom_link, :precision
5
6
 
6
7
  def initialize(field_name, attributes = {})
7
8
  @field_name = field_name
@@ -1,9 +1,9 @@
1
1
  module CmAdmin
2
2
  module Models
3
3
  class Filter
4
- attr_accessor :db_column_name, :filter_type, :placeholder, :collection, :multiselect, :checked
4
+ attr_accessor :db_column_name, :filter_type, :placeholder, :collection
5
5
 
6
- VALID_FILTER_TYPES = Set[:checkbox, :date, :dropdown, :range, :search].freeze
6
+ VALID_FILTER_TYPES = Set[:date, :multi_select, :range, :search, :single_select].freeze
7
7
 
8
8
  def initialize(db_column_name:, filter_type:, options: {})
9
9
  raise TypeError, "Can't have array of multiple columns for #{filter_type} filter" if db_column_name.is_a?(Array) && db_column_name.size > 1 && !filter_type.to_sym.eql?(:search)
@@ -25,6 +25,71 @@ module CmAdmin
25
25
  end
26
26
  [db_column_name, filter_type]
27
27
  end
28
+
29
+ # Methods to filter the records based on the filter type.
30
+ class << self
31
+ def filtered_data(filter_params, records, filters)
32
+ if filter_params
33
+ filter_params.each do |scope_type, scope_value|
34
+ scope_name = if scope_type.eql?('date') || scope_type.eql?('range')
35
+ 'date_and_range'
36
+ elsif scope_type.eql?('single_select') || scope_type.eql?('multi_select')
37
+ 'dropdown'
38
+ else
39
+ scope_type
40
+ end
41
+ records = self.send("cm_#{scope_name}_filter", scope_value, records, filters) if scope_value.present?
42
+ end
43
+ end
44
+ records
45
+ end
46
+
47
+ def cm_search_filter(scope_value, records, filters)
48
+ return nil if scope_value.blank?
49
+ table_name = records.table_name
50
+
51
+ filters.select{|x| x if x.filter_type.eql?(:search)}.each do |filter|
52
+ terms = scope_value.downcase.split(/\s+/)
53
+ terms = terms.map { |e|
54
+ (e.gsub('*', '%').prepend('%') + '%').gsub(/%+/, '%')
55
+ }
56
+ sql = ""
57
+ filter.db_column_name.each.with_index do |column, i|
58
+ sql.concat("#{table_name}.#{column} ILIKE ?")
59
+ sql.concat(' OR ') unless filter.db_column_name.size.eql?(i+1)
60
+ end
61
+
62
+ records = records.where(
63
+ terms.map { |term|
64
+ sql
65
+ }.join(' AND '),
66
+ *terms.map { |e| [e] * filter.db_column_name.size }.flatten
67
+ )
68
+ end
69
+ records
70
+ end
71
+
72
+ def cm_date_and_range_filter(scope_value, records, filters)
73
+ return nil if scope_value.nil?
74
+ scope_value.each do |key, value|
75
+ if value.present?
76
+ value = value.split(' to ')
77
+ from = value[0].presence
78
+ to = value[1].presence
79
+ records = records.where(key => from..to)
80
+ end
81
+ end
82
+ records
83
+ end
84
+
85
+ def cm_dropdown_filter(scope_value, records, filters)
86
+ return nil if scope_value.nil?
87
+ scope_value.each do |key, value|
88
+ records = records.where(key => value) if value.present?
89
+ end
90
+ records
91
+ end
92
+ end
28
93
  end
29
94
  end
30
95
  end
@@ -0,0 +1,21 @@
1
+ module CmAdmin
2
+ module Models
3
+ class FormField
4
+ attr_accessor :field_name, :label, :header, :input_type, :collection, :custom_value, :disabled
5
+ VALID_INPUT_TYPES = [:integer, :decimal, :string, :single_select, :multi_select, :date, :date_time, :text, :single_file_upload, :multi_file_upload, :hidden].freeze
6
+
7
+ def initialize(field_name, input_type, attributes = {})
8
+ raise ArgumentError, "Kindly select a valid filter type like #{VALID_INPUT_TYPES.sort.to_sentence(last_word_connector: ', or ')} instead of #{input_type} for column #{field_name}" unless VALID_INPUT_TYPES.include?(input_type.to_sym)
9
+ @field_name = field_name
10
+ set_default_values
11
+ attributes.each do |key, value|
12
+ self.send("#{key.to_s}=", value)
13
+ end
14
+ end
15
+
16
+ def set_default_values
17
+ self.disabled = false
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,13 @@
1
+ module CmAdmin
2
+ module Models
3
+ class Tab
4
+
5
+ attr_accessor :nav_item_name, :custom_action
6
+
7
+ def initialize(nav_item_name, custom_action)
8
+ @nav_item_name = nav_item_name
9
+ @custom_action = custom_action
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,3 +1,3 @@
1
1
  module CmAdmin
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -0,0 +1,29 @@
1
+ module CmAdmin
2
+ module ViewHelpers
3
+ module ColumnFieldHelper
4
+
5
+ #adds prefix and suffix to a value
6
+ def add_prefix_and_suffix_helper(value, prefix, suffix)
7
+ "#{prefix} #{value} #{suffix}"
8
+ end
9
+
10
+ #formats the column value a field
11
+ def column_for_field_helper(ar_object, column)
12
+ value = ar_object.send(column.db_column_name)
13
+ formatted_value = CmAdmin::Models::Column.format_data_type(column, value)
14
+ formatted_value = add_prefix_and_suffix_helper(formatted_value, column.prefix, column.suffix)
15
+ formatted_value = link_url_value_helper(column, value, formatted_value)
16
+ return formatted_value
17
+ end
18
+
19
+ #column's value is either linked with 'url' attribute's value or its own value
20
+ def link_url_value_helper(column, value, formatted_value)
21
+ return formatted_value unless column.column_type.to_s == 'link'
22
+ link_url_value = column.url.present? ? column.url : value
23
+ final_value = "<a href=#{link_url_value}>#{formatted_value}</a>".html_safe
24
+ return final_value
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,65 @@
1
+ module CmAdmin
2
+ module ViewHelpers
3
+ module FieldDisplayHelper
4
+
5
+ def show_field(ar_object, field)
6
+ content_tag(:div, class: "info-split") do
7
+ concat show_field_label(ar_object, field)
8
+ concat show_field_value(ar_object, field)
9
+ end
10
+ end
11
+
12
+ def show_field_label(ar_object, field)
13
+ content_tag(:div, class: "info-split__lhs") do
14
+ p = field.label.present? ? field.label.to_s : field.field_name.to_s.titleize
15
+ end
16
+ end
17
+
18
+ def show_field_value(ar_object, field)
19
+ content_tag(:div, class: "info-split__rhs") do
20
+ case field.field_type || :string
21
+ when :integer
22
+ ar_object.send(field.field_name).to_s
23
+ when :decimal
24
+ ar_object.send(field.field_name).to_f.round(field.precision).to_s if ar_object.send(field.field_name)
25
+ when :string
26
+ ar_object.send(field.field_name).to_s
27
+ when :datetime
28
+ ar_object.send(field.field_name).strftime(field.format || "%d/%m/%Y").to_s if ar_object.send(field.field_name)
29
+ when :text
30
+ ar_object.send(field.field_name)
31
+ when :custom
32
+ send(field.helper_method, ar_object, field.field_name)
33
+ when :link
34
+ if field.custom_link
35
+ link = field.custom_link
36
+ else
37
+ link = ar_object.send(field.field_name)
38
+ end
39
+ content_tag :a, href: link do
40
+ ar_object.send(field.field_name).to_s
41
+ end
42
+ when :attachment
43
+ concat show_attachment_value(ar_object, field)
44
+ end
45
+ end
46
+ end
47
+
48
+ def show_attachment_value(ar_object, field)
49
+ if ar_object.send(field.field_name).attached?
50
+ if ar_object.send(field.field_name).class.name.include?('One')
51
+ content_tag :a, href: rails_blob_path(ar_object.send(field.field_name), disposition: "attachment") do
52
+ ar_object.send(field.field_name).filename.to_s
53
+ end
54
+ elsif ar_object.send(field.field_name).class.name.include?('Many')
55
+ ar_object.send(field.field_name).map do |asset|
56
+ content_tag :a, href: rails_blob_path(asset, disposition: "attachment") do
57
+ asset.filename.to_s
58
+ end
59
+ end.join("\n").html_safe
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end