rails_admin 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rails_admin might be problematic. Click here for more details.

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