rails_admin 1.3.0 → 1.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 (32) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -4
  3. data/README.md +4 -4
  4. data/app/assets/javascripts/rails_admin/jquery-ui.js.erb +8 -0
  5. data/app/assets/javascripts/rails_admin/ra.filter-box.js +4 -0
  6. data/app/assets/javascripts/rails_admin/ra.widgets.coffee +17 -0
  7. data/app/assets/javascripts/rails_admin/rails_admin.js +1 -3
  8. data/app/views/rails_admin/main/_form_file_upload.html.haml +1 -1
  9. data/app/views/rails_admin/main/_form_multiple_file_upload.html.haml +14 -0
  10. data/lib/rails_admin/adapters/active_record.rb +3 -0
  11. data/lib/rails_admin/adapters/mongoid.rb +2 -2
  12. data/lib/rails_admin/adapters/mongoid/abstract_object.rb +2 -3
  13. data/lib/rails_admin/adapters/mongoid/association.rb +14 -3
  14. data/lib/rails_admin/adapters/mongoid/property.rb +2 -2
  15. data/lib/rails_admin/config.rb +9 -1
  16. data/lib/rails_admin/config/fields.rb +1 -0
  17. data/lib/rails_admin/config/fields/factories/active_storage.rb +30 -0
  18. data/lib/rails_admin/config/fields/factories/carrierwave.rb +3 -1
  19. data/lib/rails_admin/config/fields/types/active_storage.rb +44 -0
  20. data/lib/rails_admin/config/fields/types/all.rb +4 -0
  21. data/lib/rails_admin/config/fields/types/code_mirror.rb +4 -4
  22. data/lib/rails_admin/config/fields/types/file_upload.rb +1 -1
  23. data/lib/rails_admin/config/fields/types/multiple_active_storage.rb +49 -0
  24. data/lib/rails_admin/config/fields/types/multiple_carrierwave.rb +44 -0
  25. data/lib/rails_admin/config/fields/types/multiple_file_upload.rb +110 -0
  26. data/lib/rails_admin/config/has_fields.rb +1 -1
  27. data/lib/rails_admin/engine.rb +16 -0
  28. data/lib/rails_admin/extensions/cancancan.rb +1 -1
  29. data/lib/rails_admin/extensions/cancancan/authorization_adapter.rb +28 -36
  30. data/lib/rails_admin/extensions/pundit/authorization_adapter.rb +2 -2
  31. data/lib/rails_admin/version.rb +1 -1
  32. metadata +17 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 33d3dadad1730dcd25eec2e13d09c6f46e8b580c
4
- data.tar.gz: 2f14072f95732283cf691142d80c65a47335e31e
3
+ metadata.gz: 361208518b5b304581718ddc22d54ee97adcbaad
4
+ data.tar.gz: 807e4d91a69a5377444885331a087e25ab65c891
5
5
  SHA512:
6
- metadata.gz: b820c08a510d01a62f8e6ba65b48ea6c2c37243b5202bb86e51f74303bd1ff370789259623d3b8aaaf41d19c6408fc0d694ed3f4f20c76ae24e034d1f4991724
7
- data.tar.gz: 22557c8d0ab68e47e48be789f7b813a32f50af4e2f194c7710d71557b105c14af9fd6956c4aeecc6aca889ab5d404493dc1a6c8ad0cf7488542cae812ac52070
6
+ metadata.gz: 40e5f564f367ad3c53220737654301ff01df27ef448044d1d933397e3ac28d6fb2559e0dc6cfb4bbfe57cbc71194dcab9ea46ffcc263d3d71949a8935126f30a
7
+ data.tar.gz: b08875e67144b03c5ab98789772067f6e3765c2e93e1d226800b742e68f685cbe5a829c04d35123560e98e80dcb2babbba9b1cb6b1c97a0fd2983968c461b436
data/Gemfile CHANGED
@@ -1,7 +1,7 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gem 'appraisal', '>= 2.0'
4
- gem 'rails', '~> 5.1.0'
4
+ gem 'rails'
5
5
  gem 'haml'
6
6
  gem 'devise'
7
7
 
@@ -9,7 +9,7 @@ group :active_record do
9
9
  gem 'paper_trail'
10
10
 
11
11
  platforms :ruby, :mswin, :mingw do
12
- gem 'mysql2', '~> 0.3.14'
12
+ gem 'mysql2', '>= 0.3.14'
13
13
  gem 'sqlite3', '>= 1.3'
14
14
  end
15
15
  end
@@ -19,8 +19,6 @@ group :development, :test do
19
19
  end
20
20
 
21
21
  group :test do
22
- gem 'cancan', '>= 1.6'
23
- gem 'cancancan', '~> 1.12.0'
24
22
  gem 'carrierwave', '>= 0.8'
25
23
  gem 'coveralls'
26
24
  gem 'database_cleaner', ['>= 1.2', '!= 1.4.0', '!= 1.5.0']
data/README.md CHANGED
@@ -2,17 +2,17 @@
2
2
 
3
3
  [![Gem Version](https://img.shields.io/gem/v/rails_admin.svg)][gem]
4
4
  [![Build Status](https://img.shields.io/travis/sferik/rails_admin.svg)][travis]
5
- [![Dependency Status](https://img.shields.io/gemnasium/sferik/rails_admin.svg)][gemnasium]
6
- [![Code Climate](https://img.shields.io/codeclimate/github/sferik/rails_admin.svg)][codeclimate]
7
5
  [![Coverage Status](https://img.shields.io/coveralls/sferik/rails_admin.svg)][coveralls]
8
6
  [![Inline docs](http://inch-ci.org/github/sferik/rails_admin.svg)][inch]
7
+ [![Code Climate](https://codeclimate.com/github/sferik/rails_admin.svg)][codeclimate]
8
+ [![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=rails_admin&package-manager=bundler&version-scheme=semver)][semver]
9
9
 
10
10
  [gem]: https://rubygems.org/gems/rails_admin
11
11
  [travis]: https://travis-ci.org/sferik/rails_admin
12
- [gemnasium]: https://gemnasium.com/sferik/rails_admin
13
- [codeclimate]: https://codeclimate.com/github/sferik/rails_admin
14
12
  [coveralls]: https://coveralls.io/r/sferik/rails_admin
15
13
  [inch]: http://inch-ci.org/github/sferik/rails_admin
14
+ [codeclimate]: https://codeclimate.com/github/sferik/rails_admin
15
+ [semver]: https://dependabot.com/compatibility-score.html?dependency-name=rails_admin&package-manager=bundler&version-scheme=semver
16
16
 
17
17
  RailsAdmin is a Rails engine that provides an easy-to-use interface for managing your data.
18
18
 
@@ -0,0 +1,8 @@
1
+ <% require_asset "jquery-ui/effect" %>
2
+ <% if Jquery::Ui::Rails::JQUERY_UI_VERSION >= '1.12' %>
3
+ <% require_asset "jquery-ui/widgets/sortable" %>
4
+ <% require_asset "jquery-ui/widgets/autocomplete" %>
5
+ <% else %>
6
+ <% require_asset "jquery-ui/sortable" %>
7
+ <% require_asset "jquery-ui/autocomplete" %>
8
+ <% end %>
@@ -157,7 +157,11 @@
157
157
  break;
158
158
  }
159
159
 
160
+ var filterContainerId = field_name + '-' + index + '-filter-container';
161
+ $('p#' + filterContainerId).remove();
162
+
160
163
  var $content = $('<p>')
164
+ .attr('id', filterContainerId)
161
165
  .addClass('filter form-search')
162
166
  .append(
163
167
  $('<span class="label label-info form-label"></span>')
@@ -70,6 +70,23 @@ $(document).on 'rails_admin.dom_ready', (e, content) ->
70
70
  else
71
71
  image_container.hide()
72
72
 
73
+ # multiple-fileupload-preview
74
+
75
+ content.find('[data-multiple-fileupload]').change ->
76
+ input = this
77
+ $("#" + input.id).parent().children(".preview").remove()
78
+ for file in input.files
79
+ ext = file.name.split('.').pop().toLowerCase()
80
+ if $.inArray(ext, ['gif','png','jpg','jpeg','bmp']) == -1
81
+ continue
82
+ image_container = $('<img />').addClass('preview').addClass('img-thumbnail')
83
+ do (image_container) ->
84
+ reader = new FileReader()
85
+ reader.onload = (e) ->
86
+ image_container.attr "src", e.target.result
87
+ reader.readAsDataURL file
88
+ $("#" + input.id).parent().append($('<div></div>').addClass('preview').append(image_container))
89
+
73
90
  # filtering-multiselect
74
91
 
75
92
  content.find('[data-filteringmultiselect]').each ->
@@ -1,9 +1,7 @@
1
1
  //= require 'jquery'
2
2
  //= require 'jquery_ujs'
3
3
  //= require 'jquery.remotipart'
4
- //= require 'jquery-ui/effect'
5
- //= require 'jquery-ui/sortable'
6
- //= require 'jquery-ui/autocomplete'
4
+ //= require 'rails_admin/jquery-ui'
7
5
  //= require 'rails_admin/moment-with-locales'
8
6
  //= require 'rails_admin/bootstrap-datetimepicker'
9
7
  //= require 'rails_admin/jquery.colorpicker'
@@ -1,4 +1,4 @@
1
- - file = form.object.send(field.method_name).presence
1
+ - file = field.value
2
2
 
3
3
  .toggle{style: ('display:none;' if file && field.delete_method && form.object.send(field.delete_method) == '1')}
4
4
  - if value = field.pretty_value
@@ -0,0 +1,14 @@
1
+ - field.attachments.each_with_index do |attachment, i|
2
+ .toggle
3
+ = attachment.pretty_value
4
+ - if field.delete_method
5
+ %a.btn.btn-info.btn-remove-image{href: '#', :'data-toggle' => 'button', role: 'button', onclick: "$(this).siblings('[type=checkbox]').click(); $(this).parent('.toggle').toggle('slow'); jQuery(this).toggleClass('btn-danger btn-info'); return false;"}
6
+ %i.icon-white.icon-trash
7
+ = I18n.t('admin.actions.delete.menu').capitalize + " #{field.label.downcase} ##{i + 1}"
8
+
9
+ = form.check_box(field.delete_method, {multiple:true, style: 'display:none;'}, attachment.delete_key, nil)
10
+
11
+ = form.file_field(field.name, field.html_attributes.reverse_merge({ data: { :"multiple-fileupload" => true }, multiple: true }))
12
+
13
+ - if field.cache_method
14
+ = form.hidden_field(field.cache_method)
@@ -155,6 +155,8 @@ module RailsAdmin
155
155
  case @type
156
156
  when :boolean
157
157
  boolean_unary_operators
158
+ when :integer, :decimal, :float
159
+ numeric_unary_operators
158
160
  else
159
161
  generic_unary_operators
160
162
  end
@@ -181,6 +183,7 @@ module RailsAdmin
181
183
  '_not_empty' => ["(#{@column} IS NOT NULL)"],
182
184
  )
183
185
  end
186
+ alias_method :numeric_unary_operators, :boolean_unary_operators
184
187
 
185
188
  def range_filter(min, max)
186
189
  if min && max
@@ -83,7 +83,7 @@ module RailsAdmin
83
83
  end
84
84
 
85
85
  def embedded?
86
- model.relations.values.detect { |a| a.macro.to_sym == :embedded_in }
86
+ associations.detect { |a| a.macro == :embedded_in }
87
87
  end
88
88
 
89
89
  def cyclic?
@@ -150,7 +150,7 @@ module RailsAdmin
150
150
 
151
151
  def parse_collection_name(column)
152
152
  collection_name, column_name = column.split('.')
153
- if [:embeds_one, :embeds_many].include?(model.relations[collection_name].try(:macro).try(:to_sym))
153
+ if associations.detect { |a| a.name == collection_name.to_sym }.try(:embeds?)
154
154
  [table_name, column]
155
155
  else
156
156
  [collection_name, column_name]
@@ -7,6 +7,7 @@ module RailsAdmin
7
7
  def initialize(object)
8
8
  super
9
9
  object.associations.each do |name, association|
10
+ association = Association.new(association, object.class)
10
11
  if [:has_many, :references_many].include? association.macro
11
12
  instance_eval <<-RUBY, __FILE__, __LINE__ + 1
12
13
  def #{name.to_s.singularize}_ids
@@ -28,9 +29,7 @@ RUBY
28
29
  def #{name}_id=(item_id)
29
30
  item = (#{association.klass}.find(item_id) rescue nil)
30
31
  return unless item
31
- unless persisted?
32
- item.update_attribute('#{association.foreign_key}', id)
33
- end
32
+ item.update_attribute('#{association.foreign_key}', id) unless persisted?
34
33
  super item.id
35
34
  end
36
35
  RUBY
@@ -45,7 +45,7 @@ module RailsAdmin
45
45
  end
46
46
 
47
47
  def foreign_key
48
- return unless [:embeds_one, :embeds_many].exclude?(macro.to_sym)
48
+ return if embeds?
49
49
  association.foreign_key.to_sym rescue nil
50
50
  end
51
51
 
@@ -82,7 +82,7 @@ module RailsAdmin
82
82
 
83
83
  def nested_options
84
84
  nested = nested_attributes_options.try { |o| o[name] }
85
- if !nested && [:embeds_one, :embeds_many].include?(macro.to_sym) && !association.cyclic
85
+ if !nested && [:embeds_one, :embeds_many].include?(macro.to_sym) && !cyclic?
86
86
  raise <<-MSG.gsub(/^\s+/, '')
87
87
  Embbeded association without accepts_nested_attributes_for can't be handled by RailsAdmin,
88
88
  because embedded model doesn't have top-level access.
@@ -96,13 +96,24 @@ module RailsAdmin
96
96
  true
97
97
  end
98
98
 
99
+ def macro
100
+ association.try(:macro) || association.class.name.split('::').last.underscore.to_sym
101
+ end
102
+
103
+ def embeds?
104
+ [:embeds_one, :embeds_many].include?(macro)
105
+ end
106
+
99
107
  private
100
108
 
101
109
  def inverse_of_field
102
110
  association.respond_to?(:inverse_of_field) && association.inverse_of_field
103
111
  end
104
112
 
105
- delegate :macro, :options, to: :association, prefix: false
113
+ def cyclic?
114
+ association.respond_to?(:cyclic?) ? association.cyclic? : association.cyclic
115
+ end
116
+
106
117
  delegate :nested_attributes_options, to: :model, prefix: false
107
118
  delegate :polymorphic_parents, to: RailsAdmin::AbstractModel
108
119
  end
@@ -70,8 +70,8 @@ module RailsAdmin
70
70
  private
71
71
 
72
72
  def object_field_type
73
- if [:belongs_to, :referenced_in, :embedded_in].
74
- include?(model.relations.values.detect { |r| r.foreign_key.try(:to_sym) == name }.try(:macro).try(:to_sym))
73
+ association = Association.new model.relations.values.detect { |r| r.try(:foreign_key).try(:to_sym) == name }, model
74
+ if [:belongs_to, :referenced_in, :embedded_in].include?(association.macro)
75
75
  :bson_object_id
76
76
  else
77
77
  :string
@@ -207,7 +207,7 @@ module RailsAdmin
207
207
 
208
208
  # pool of all found model names from the whole application
209
209
  def models_pool
210
- excluded = (excluded_models.collect(&:to_s) + %w(RailsAdmin::History PaperTrail::Version PaperTrail::VersionAssociation))
210
+ excluded = (excluded_models.collect(&:to_s) + %w(RailsAdmin::History PaperTrail::Version PaperTrail::VersionAssociation ActiveStorage::Attachment ActiveStorage::Blob))
211
211
 
212
212
  (viable_models - excluded).uniq.sort
213
213
  end
@@ -304,6 +304,14 @@ module RailsAdmin
304
304
  @registry.delete(key)
305
305
  end
306
306
 
307
+ # Reset all models configuration
308
+ # Used to clear all configurations when reloading code in development.
309
+ # @see RailsAdmin::Engine
310
+ # @see RailsAdmin::Config.registry
311
+ def reset_all_models
312
+ @registry = {}
313
+ end
314
+
307
315
  # Get all models that are configured as visible sorted by their weight and label.
308
316
  #
309
317
  # @see RailsAdmin::Config::Hideable
@@ -83,4 +83,5 @@ require 'rails_admin/config/fields/factories/paperclip'
83
83
  require 'rails_admin/config/fields/factories/dragonfly'
84
84
  require 'rails_admin/config/fields/factories/carrierwave'
85
85
  require 'rails_admin/config/fields/factories/refile'
86
+ require 'rails_admin/config/fields/factories/active_storage'
86
87
  require 'rails_admin/config/fields/factories/association'
@@ -0,0 +1,30 @@
1
+ require 'rails_admin/config/fields'
2
+ require 'rails_admin/config/fields/types'
3
+ require 'rails_admin/config/fields/types/file_upload'
4
+
5
+ RailsAdmin::Config::Fields.register_factory do |parent, properties, fields|
6
+ if defined?(::ActiveStorage) && properties.is_a?(RailsAdmin::Adapters::ActiveRecord::Association) && (match = /\A(.+)_attachments?\Z/.match properties.name) && properties.klass.to_s == 'ActiveStorage::Attachment'
7
+ name = match[1]
8
+ field = RailsAdmin::Config::Fields::Types.load(
9
+ properties.type == :has_many ? :multiple_active_storage : :active_storage,
10
+ ).new(parent, name, properties)
11
+ fields << field
12
+ associations =
13
+ if properties.type == :has_many
14
+ ["#{name}_attachments".to_sym, "#{name}_blobs".to_sym]
15
+ else
16
+ ["#{name}_attachment".to_sym, "#{name}_blob".to_sym]
17
+ end
18
+ children_fields = associations.map do |child_name|
19
+ next unless child_association = parent.abstract_model.associations.detect { |p| p.name.to_sym == child_name }
20
+ child_field = fields.detect { |f| f.name == child_name } || RailsAdmin::Config::Fields.default_factory.call(parent, child_association, fields)
21
+ child_field.hide unless field == child_field
22
+ child_field.filterable(false) unless field == child_field
23
+ child_field.name
24
+ end.flatten.compact
25
+ field.children_fields(children_fields)
26
+ true
27
+ else
28
+ false
29
+ end
30
+ end
@@ -6,7 +6,9 @@ RailsAdmin::Config::Fields.register_factory do |parent, properties, fields|
6
6
  model = parent.abstract_model.model
7
7
  if defined?(::CarrierWave) && model.is_a?(CarrierWave::Mount) && model.uploaders.include?(attachment_name = properties.name.to_s.chomp('_file_name').to_sym)
8
8
  columns = [model.uploader_options[attachment_name][:mount_on] || attachment_name, "#{attachment_name}_content_type".to_sym, "#{attachment_name}_file_size".to_sym]
9
- field = RailsAdmin::Config::Fields::Types.load(:carrierwave).new(parent, attachment_name, properties)
9
+ field = RailsAdmin::Config::Fields::Types.load(
10
+ [:serialized, :json].include?(properties.type) ? :multiple_carrierwave : :carrierwave,
11
+ ).new(parent, attachment_name, properties)
10
12
  fields << field
11
13
  children_fields = []
12
14
  columns.each do |children_column_name|
@@ -0,0 +1,44 @@
1
+ require 'rails_admin/config/fields/types/file_upload'
2
+
3
+ module RailsAdmin
4
+ module Config
5
+ module Fields
6
+ module Types
7
+ class ActiveStorage < RailsAdmin::Config::Fields::Types::FileUpload
8
+ RailsAdmin::Config::Fields::Types.register(self)
9
+
10
+ register_instance_option :thumb_method do
11
+ {resize: '100x100>'}
12
+ end
13
+
14
+ register_instance_option :delete_method do
15
+ "remove_#{name}" if bindings[:object].respond_to?("remove_#{name}")
16
+ end
17
+
18
+ register_instance_option :image? do
19
+ if value
20
+ value.filename.to_s.split('.').last =~ /jpg|jpeg|png|gif|svg/i
21
+ end
22
+ end
23
+
24
+ def resource_url(thumb = false)
25
+ return nil unless value
26
+ if thumb && value.variable?
27
+ variant = value.variant(thumb)
28
+ Rails.application.routes.url_helpers.rails_blob_representation_path(
29
+ variant.blob.signed_id, variant.variation.key, variant.blob.filename, only_path: true
30
+ )
31
+ else
32
+ Rails.application.routes.url_helpers.rails_blob_path(value, only_path: true)
33
+ end
34
+ end
35
+
36
+ def value
37
+ attachment = super
38
+ attachment if attachment && attachment.attached?
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,4 +1,5 @@
1
1
  require 'rails_admin/config/fields/types/active_record_enum'
2
+ require 'rails_admin/config/fields/types/active_storage'
2
3
  require 'rails_admin/config/fields/types/belongs_to_association'
3
4
  require 'rails_admin/config/fields/types/boolean'
4
5
  require 'rails_admin/config/fields/types/bson_object_id'
@@ -11,6 +12,9 @@ require 'rails_admin/config/fields/types/file_upload'
11
12
  require 'rails_admin/config/fields/types/paperclip'
12
13
  require 'rails_admin/config/fields/types/carrierwave'
13
14
  require 'rails_admin/config/fields/types/refile'
15
+ require 'rails_admin/config/fields/types/multiple_file_upload'
16
+ require 'rails_admin/config/fields/types/multiple_active_storage'
17
+ require 'rails_admin/config/fields/types/multiple_carrierwave'
14
18
  require 'rails_admin/config/fields/types/float'
15
19
  require 'rails_admin/config/fields/types/has_and_belongs_to_many_association'
16
20
  require 'rails_admin/config/fields/types/has_many_association'
@@ -19,19 +19,19 @@ module RailsAdmin
19
19
  # Pass the location of the theme and mode for Codemirror
20
20
  register_instance_option :assets do
21
21
  {
22
- mode: '/assets/codemirror/modes/css.js',
23
- theme: '/assets/codemirror/themes/night.css',
22
+ mode: ::ActionController::Base.helpers.asset_path('codemirror/modes/css.js'),
23
+ theme: ::ActionController::Base.helpers.asset_path('codemirror/themes/night.css'),
24
24
  }
25
25
  end
26
26
 
27
27
  # Use this if you want to point to a cloud instances of CodeMirror
28
28
  register_instance_option :js_location do
29
- '/assets/codemirror.js'
29
+ ::ActionController::Base.helpers.asset_path('codemirror.js')
30
30
  end
31
31
 
32
32
  # Use this if you want to point to a cloud instances of CodeMirror
33
33
  register_instance_option :css_location do
34
- '/assets/codemirror.css'
34
+ ::ActionController::Base.helpers.asset_path('codemirror.css')
35
35
  end
36
36
 
37
37
  register_instance_option :partial do
@@ -36,7 +36,7 @@ module RailsAdmin
36
36
  image_html = v.image_tag(thumb_url, class: 'img-thumbnail')
37
37
  url != thumb_url ? v.link_to(image_html, url, target: '_blank') : image_html
38
38
  else
39
- v.link_to(nil, url, target: '_blank')
39
+ v.link_to(value, url, target: '_blank')
40
40
  end
41
41
  end
42
42
  end
@@ -0,0 +1,49 @@
1
+ require 'rails_admin/config/fields/types/multiple_file_upload'
2
+
3
+ module RailsAdmin
4
+ module Config
5
+ module Fields
6
+ module Types
7
+ class MultipleActiveStorage < RailsAdmin::Config::Fields::Types::MultipleFileUpload
8
+ RailsAdmin::Config::Fields::Types.register(self)
9
+
10
+ class ActiveStorageAttachment < RailsAdmin::Config::Fields::Types::MultipleFileUpload::AbstractAttachment
11
+ register_instance_option :thumb_method do
12
+ {resize: '100x100>'}
13
+ end
14
+
15
+ register_instance_option :delete_key do
16
+ value.id
17
+ end
18
+
19
+ register_instance_option :image? do
20
+ if value
21
+ value.filename.to_s.split('.').last =~ /jpg|jpeg|png|gif|svg/i
22
+ end
23
+ end
24
+
25
+ def resource_url(thumb = false)
26
+ return nil unless value
27
+ if thumb && value.variable?
28
+ variant = value.variant(thumb_method)
29
+ Rails.application.routes.url_helpers.rails_blob_representation_path(
30
+ variant.blob.signed_id, variant.variation.key, variant.blob.filename, only_path: true
31
+ )
32
+ else
33
+ Rails.application.routes.url_helpers.rails_blob_path(value, only_path: true)
34
+ end
35
+ end
36
+ end
37
+
38
+ register_instance_option :attachment_class do
39
+ ActiveStorageAttachment
40
+ end
41
+
42
+ register_instance_option :delete_method do
43
+ "remove_#{name}" if bindings[:object].respond_to?("remove_#{name}")
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,44 @@
1
+ require 'rails_admin/config/fields/types/multiple_file_upload'
2
+
3
+ module RailsAdmin
4
+ module Config
5
+ module Fields
6
+ module Types
7
+ class MultipleCarrierwave < RailsAdmin::Config::Fields::Types::MultipleFileUpload
8
+ RailsAdmin::Config::Fields::Types.register(self)
9
+
10
+ class CarrierwaveAttachment < RailsAdmin::Config::Fields::Types::MultipleFileUpload::AbstractAttachment
11
+ register_instance_option :thumb_method do
12
+ @thumb_method ||= ((versions = value.versions.keys).detect { |k| k.in?([:thumb, :thumbnail, 'thumb', 'thumbnail']) } || versions.first.to_s)
13
+ end
14
+
15
+ register_instance_option :delete_key do
16
+ value.file.identifier
17
+ end
18
+
19
+ def resource_url(thumb = false)
20
+ return nil unless value
21
+ thumb.present? ? value.send(thumb).url : value.url
22
+ end
23
+ end
24
+
25
+ register_instance_option :attachment_class do
26
+ CarrierwaveAttachment
27
+ end
28
+
29
+ register_instance_option :cache_method do
30
+ "#{name}_cache"
31
+ end
32
+
33
+ register_instance_option :delete_method do
34
+ "delete_#{name}" if bindings[:object].respond_to?("delete_#{name}")
35
+ end
36
+
37
+ def value
38
+ bindings[:object].send(name)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,110 @@
1
+ module RailsAdmin
2
+ module Config
3
+ module Fields
4
+ module Types
5
+ class MultipleFileUpload < RailsAdmin::Config::Fields::Base
6
+ RailsAdmin::Config::Fields::Types.register(self)
7
+
8
+ class AbstractAttachment
9
+ include RailsAdmin::Config::Proxyable
10
+ include RailsAdmin::Config::Configurable
11
+
12
+ attr_reader :value
13
+
14
+ def initialize(value)
15
+ @value = value
16
+ end
17
+
18
+ register_instance_option :thumb_method do
19
+ nil
20
+ end
21
+
22
+ register_instance_option :delete_key do
23
+ nil
24
+ end
25
+
26
+ register_instance_option :pretty_value do
27
+ if value.presence
28
+ v = bindings[:view]
29
+ url = resource_url
30
+ if image
31
+ thumb_url = resource_url(thumb_method)
32
+ image_html = v.image_tag(thumb_url, class: 'img-thumbnail')
33
+ url != thumb_url ? v.link_to(image_html, url, target: '_blank') : image_html
34
+ else
35
+ v.link_to(value, url, target: '_blank')
36
+ end
37
+ end
38
+ end
39
+
40
+ register_instance_option :image? do
41
+ (url = resource_url.to_s) && url.split('.').last =~ /jpg|jpeg|png|gif|svg/i
42
+ end
43
+
44
+ def resource_url(_thumb = false)
45
+ raise('not implemented')
46
+ end
47
+ end
48
+
49
+ def initialize(*args)
50
+ super
51
+ @attachment_configurations = []
52
+ end
53
+
54
+ register_instance_option :attachment_class do
55
+ AbstractAttachment
56
+ end
57
+
58
+ register_instance_option :partial do
59
+ :form_multiple_file_upload
60
+ end
61
+
62
+ register_instance_option :cache_method do
63
+ nil
64
+ end
65
+
66
+ register_instance_option :delete_method do
67
+ nil
68
+ end
69
+
70
+ register_instance_option :export_value do
71
+ attachments.map(&:resource_url).map(&:to_s).join(',')
72
+ end
73
+
74
+ register_instance_option :pretty_value do
75
+ bindings[:view].safe_join attachments.map(&:pretty_value), ' '
76
+ end
77
+
78
+ register_instance_option :allowed_methods do
79
+ [method_name, cache_method, delete_method].compact
80
+ end
81
+
82
+ register_instance_option :html_attributes do
83
+ {
84
+ required: required? && !value.present?,
85
+ }
86
+ end
87
+
88
+ def attachment(&block)
89
+ @attachment_configurations << block
90
+ end
91
+
92
+ def attachments
93
+ Array(value).map do |attached|
94
+ attachment = attachment_class.new(attached)
95
+ @attachment_configurations.each do |config|
96
+ attachment.instance_eval(&config)
97
+ end
98
+ attachment.with(bindings)
99
+ end
100
+ end
101
+
102
+ # virtual class
103
+ def virtual?
104
+ true
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
@@ -130,7 +130,7 @@ module RailsAdmin
130
130
  @_ro_fields = @_fields = RailsAdmin::Config::Fields.factory(self)
131
131
  else
132
132
  # parent is RailsAdmin::Config::Model, recursion is on Section's classes
133
- @_ro_fields ||= parent.send(self.class.superclass.to_s.underscore.split('/').last)._fields(true).freeze
133
+ @_ro_fields ||= parent.send(self.class.superclass.to_s.underscore.split('/').last)._fields(true).clone.freeze
134
134
  end
135
135
  readonly ? @_ro_fields : (@_fields ||= @_ro_fields.collect(&:clone))
136
136
  end
@@ -24,10 +24,26 @@ module RailsAdmin
24
24
  end
25
25
 
26
26
  initializer 'RailsAdmin setup middlewares' do |app|
27
+ app.config.session_store :cookie_store
28
+ app.config.middleware.use ActionDispatch::Cookies
27
29
  app.config.middleware.use ActionDispatch::Flash
30
+ app.config.middleware.use ActionDispatch::Session::CookieStore, app.config.session_options
31
+ app.config.middleware.use Rack::MethodOverride
28
32
  app.config.middleware.use Rack::Pjax
29
33
  end
30
34
 
35
+ initializer 'RailsAdmin reload config in development' do
36
+ if Rails.application.config.cache_classes
37
+ if defined?(ActiveSupport::Reloader)
38
+ ActiveSupport::Reloader.before_class_unload do
39
+ RailsAdmin::Config.reset_all_models
40
+ end
41
+ # else
42
+ # For Rails 4 not implemented
43
+ end
44
+ end
45
+ end
46
+
31
47
  rake_tasks do
32
48
  Dir[File.join(File.dirname(__FILE__), '../tasks/*.rake')].each { |f| load f }
33
49
  end
@@ -1,3 +1,3 @@
1
1
  require 'rails_admin/extensions/cancancan/authorization_adapter'
2
2
 
3
- RailsAdmin.add_extension(:cancan, RailsAdmin::Extensions::CanCanCan, authorization: true)
3
+ RailsAdmin.add_extension(:cancancan, RailsAdmin::Extensions::CanCanCan, authorization: true)
@@ -2,51 +2,43 @@ module RailsAdmin
2
2
  module Extensions
3
3
  module CanCanCan
4
4
  # This adapter is for the CanCanCan[https://github.com/CanCanCommunity/cancancan] authorization library.
5
- class AuthorizationAdapter
6
- # See the +authorize_with+ config method for where the initialization happens.
7
- def initialize(controller, ability = ::Ability)
8
- @controller = controller
9
- @controller.instance_variable_set '@ability', ability
10
- @controller.extend ControllerExtension
11
- @controller.current_ability.authorize! :access, :rails_admin
12
- end
13
-
14
- # This method is called in every controller action and should raise an exception
15
- # when the authorization fails. The first argument is the name of the controller
16
- # action as a symbol (:create, :bulk_delete, etc.). The second argument is the
17
- # AbstractModel instance that applies. The third argument is the actual model
18
- # instance if it is available.
5
+ class AuthorizationAdapter < RailsAdmin::Extensions::CanCan::AuthorizationAdapter
19
6
  def authorize(action, abstract_model = nil, model_object = nil)
20
- @controller.current_ability.authorize!(action, model_object || abstract_model && abstract_model.model) if action
7
+ return unless action
8
+ subject = model_object || abstract_model && abstract_model.model
9
+ if authorized_for_dashboard_in_legacy_way?(action)
10
+ subject
11
+ else
12
+ @controller.current_ability.authorize!(*resolve_with_compatibility(action, subject))
13
+ end
21
14
  end
22
15
 
23
- # This method is called primarily from the view to determine whether the given user
24
- # has access to perform the action on a given model. It should return true when authorized.
25
- # This takes the same arguments as +authorize+. The difference is that this will
26
- # return a boolean whereas +authorize+ will raise an exception when not authorized.
27
16
  def authorized?(action, abstract_model = nil, model_object = nil)
28
- @controller.current_ability.can?(action, model_object || abstract_model && abstract_model.model) if action
17
+ return unless action
18
+ subject = model_object || abstract_model && abstract_model.model
19
+ authorized_for_dashboard_in_legacy_way?(action, true) ||
20
+ @controller.current_ability.can?(*resolve_with_compatibility(action, subject))
29
21
  end
30
22
 
31
- # This is called when needing to scope a database query. It is called within the list
32
- # and bulk_delete/destroy actions and should return a scope which limits the records
33
- # to those which the user can perform the given action on.
34
- def query(action, abstract_model)
35
- abstract_model.model.accessible_by(@controller.current_ability, action)
36
- end
23
+ private
37
24
 
38
- # This is called in the new/create actions to determine the initial attributes for new
39
- # records. It should return a hash of attributes which match what the user
40
- # is authorized to create.
41
- def attributes_for(action, abstract_model)
42
- @controller.current_ability.attributes_for(action, abstract_model && abstract_model.model)
25
+ def authorized_for_dashboard_in_legacy_way?(action, silent = false)
26
+ return false unless action == :dashboard
27
+ legacy_ability = @controller.current_ability.permissions[:can][:dashboard]
28
+ if legacy_ability && (legacy_ability.empty? || legacy_ability.all?(&:empty?))
29
+ ActiveSupport::Deprecation.warn('RailsAdmin CanCanCan Ability with `can :dashboard` is old and support will be removed in the next major release, use `can :read, :dashboard` instead. See https://github.com/sferik/rails_admin/issues/2901') unless silent
30
+ true
31
+ else
32
+ false
33
+ end
43
34
  end
44
35
 
45
- module ControllerExtension
46
- def current_ability
47
- # use _current_user instead of default current_user so it works with
48
- # whatever current user method is defined with RailsAdmin
49
- @current_ability ||= @ability.new(_current_user)
36
+ def resolve_with_compatibility(action, subject)
37
+ if subject
38
+ [action, subject]
39
+ else
40
+ # For :dashboard compatibility
41
+ [:read, action]
50
42
  end
51
43
  end
52
44
  end
@@ -43,7 +43,7 @@ module RailsAdmin
43
43
  # and bulk_delete/destroy actions and should return a scope which limits the records
44
44
  # to those which the user can perform the given action on.
45
45
  def query(_action, abstract_model)
46
- @controller.policy_scope(abstract_model.model.all)
46
+ @controller.send(:policy_scope, abstract_model.model.all)
47
47
  rescue ::Pundit::NotDefinedError
48
48
  abstract_model.model.all
49
49
  end
@@ -59,7 +59,7 @@ module RailsAdmin
59
59
  private
60
60
 
61
61
  def policy(record)
62
- @controller.policy(record)
62
+ @controller.send(:policy, record)
63
63
  rescue ::Pundit::NotDefinedError
64
64
  ::ApplicationPolicy.new(@controller.send(:pundit_user), record)
65
65
  end
@@ -1,7 +1,7 @@
1
1
  module RailsAdmin
2
2
  class Version
3
3
  MAJOR = 1
4
- MINOR = 3
4
+ MINOR = 4
5
5
  PATCH = 0
6
6
  PRE = nil
7
7
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_admin
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Erik Michaels-Ober
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2018-02-18 00:00:00.000000000 Z
15
+ date: 2018-07-22 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: builder
@@ -106,16 +106,22 @@ dependencies:
106
106
  name: jquery-ui-rails
107
107
  requirement: !ruby/object:Gem::Requirement
108
108
  requirements:
109
- - - "~>"
109
+ - - ">="
110
110
  - !ruby/object:Gem::Version
111
111
  version: '5.0'
112
+ - - "<"
113
+ - !ruby/object:Gem::Version
114
+ version: '7'
112
115
  type: :runtime
113
116
  prerelease: false
114
117
  version_requirements: !ruby/object:Gem::Requirement
115
118
  requirements:
116
- - - "~>"
119
+ - - ">="
117
120
  - !ruby/object:Gem::Version
118
121
  version: '5.0'
122
+ - - "<"
123
+ - !ruby/object:Gem::Version
124
+ version: '7'
119
125
  - !ruby/object:Gem::Dependency
120
126
  name: kaminari
121
127
  requirement: !ruby/object:Gem::Requirement
@@ -305,6 +311,7 @@ files:
305
311
  - app/assets/javascripts/rails_admin/bootstrap/bootstrap-typeahead.js
306
312
  - app/assets/javascripts/rails_admin/bootstrap/bootstrap.js
307
313
  - app/assets/javascripts/rails_admin/custom/ui.coffee
314
+ - app/assets/javascripts/rails_admin/jquery-ui.js.erb
308
315
  - app/assets/javascripts/rails_admin/jquery.colorpicker.js
309
316
  - app/assets/javascripts/rails_admin/jquery.pjax.js
310
317
  - app/assets/javascripts/rails_admin/ra.filter-box.js
@@ -442,6 +449,7 @@ files:
442
449
  - app/views/rails_admin/main/_form_filtering_multiselect.html.haml
443
450
  - app/views/rails_admin/main/_form_filtering_select.html.haml
444
451
  - app/views/rails_admin/main/_form_froala.html.haml
452
+ - app/views/rails_admin/main/_form_multiple_file_upload.html.haml
445
453
  - app/views/rails_admin/main/_form_nested_many.html.haml
446
454
  - app/views/rails_admin/main/_form_nested_one.html.haml
447
455
  - app/views/rails_admin/main/_form_polymorphic_association.html.haml
@@ -500,6 +508,7 @@ files:
500
508
  - lib/rails_admin/config/fields.rb
501
509
  - lib/rails_admin/config/fields/association.rb
502
510
  - lib/rails_admin/config/fields/base.rb
511
+ - lib/rails_admin/config/fields/factories/active_storage.rb
503
512
  - lib/rails_admin/config/fields/factories/association.rb
504
513
  - lib/rails_admin/config/fields/factories/carrierwave.rb
505
514
  - lib/rails_admin/config/fields/factories/devise.rb
@@ -511,6 +520,7 @@ files:
511
520
  - lib/rails_admin/config/fields/group.rb
512
521
  - lib/rails_admin/config/fields/types.rb
513
522
  - lib/rails_admin/config/fields/types/active_record_enum.rb
523
+ - lib/rails_admin/config/fields/types/active_storage.rb
514
524
  - lib/rails_admin/config/fields/types/all.rb
515
525
  - lib/rails_admin/config/fields/types/belongs_to_association.rb
516
526
  - lib/rails_admin/config/fields/types/boolean.rb
@@ -534,6 +544,9 @@ files:
534
544
  - lib/rails_admin/config/fields/types/inet.rb
535
545
  - lib/rails_admin/config/fields/types/integer.rb
536
546
  - lib/rails_admin/config/fields/types/json.rb
547
+ - lib/rails_admin/config/fields/types/multiple_active_storage.rb
548
+ - lib/rails_admin/config/fields/types/multiple_carrierwave.rb
549
+ - lib/rails_admin/config/fields/types/multiple_file_upload.rb
537
550
  - lib/rails_admin/config/fields/types/paperclip.rb
538
551
  - lib/rails_admin/config/fields/types/password.rb
539
552
  - lib/rails_admin/config/fields/types/polymorphic_association.rb