rails_admin 0.0.3 → 0.0.4

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.

Potentially problematic release.


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

Files changed (44) hide show
  1. data/Gemfile +3 -1
  2. data/README.md +8 -1
  3. data/app/assets/javascripts/rails_admin/ra.filtering-multiselect.js +4 -0
  4. data/app/assets/javascripts/rails_admin/ra.filtering-select.js +9 -0
  5. data/app/assets/javascripts/rails_admin/ra.widgets.coffee +13 -1
  6. data/app/assets/javascripts/rails_admin/ui.js.coffee +4 -2
  7. data/app/assets/stylesheets/rails_admin/imports.css.scss.erb +0 -1
  8. data/app/controllers/rails_admin/application_controller.rb +2 -0
  9. data/app/controllers/rails_admin/main_controller.rb +1 -1
  10. data/app/helpers/rails_admin/application_helper.rb +1 -1
  11. data/app/views/layouts/rails_admin/_secondary_navigation.html.haml +2 -2
  12. data/app/views/rails_admin/main/_form_text.html.haml +10 -1
  13. data/app/views/rails_admin/main/index.html.haml +1 -1
  14. data/config/initializers/mongoid_extensions.rb +0 -1
  15. data/lib/rails_admin/adapters/active_record.rb +9 -3
  16. data/lib/rails_admin/adapters/mongoid.rb +23 -7
  17. data/lib/rails_admin/adapters/mongoid/abstract_object.rb +0 -5
  18. data/lib/rails_admin/adapters/mongoid/extension.rb +17 -20
  19. data/lib/rails_admin/config/actions/delete.rb +1 -1
  20. data/lib/rails_admin/config/actions/show.rb +4 -2
  21. data/lib/rails_admin/config/fields/association.rb +6 -6
  22. data/lib/rails_admin/config/fields/types/bson_object_id.rb +5 -2
  23. data/lib/rails_admin/config/fields/types/text.rb +41 -0
  24. data/lib/rails_admin/engine.rb +1 -1
  25. data/lib/rails_admin/extensions/history/history.rb +4 -10
  26. data/lib/rails_admin/version.rb +1 -1
  27. data/spec/controllers/main_controller_spec.rb +8 -1
  28. data/spec/dummy_app/Gemfile +3 -3
  29. data/spec/dummy_app/app/active_record/player.rb +4 -0
  30. data/spec/dummy_app/app/mongoid/player.rb +4 -0
  31. data/spec/dummy_app/app/mongoid/team.rb +1 -1
  32. data/spec/dummy_app/app/mongoid/user.rb +2 -2
  33. data/spec/dummy_app/config/initializers/devise.rb +2 -9
  34. data/spec/dummy_app/config/initializers/dragonfly.rb +1 -4
  35. data/spec/dummy_app/config/mongoid.yml +11 -0
  36. data/spec/integration/basic/destroy/rails_admin_basic_destroy_spec.rb +11 -3
  37. data/spec/integration/config/edit/rails_admin_config_edit_spec.rb +20 -0
  38. data/spec/integration/config/show/rails_admin_config_show_spec.rb +18 -0
  39. data/spec/integration/history/rails_admin_history_spec.rb +6 -0
  40. data/spec/integration/rails_admin_spec.rb +18 -0
  41. data/spec/orm/mongoid.rb +2 -0
  42. data/spec/unit/adapters/active_record_spec.rb +3 -3
  43. data/spec/unit/adapters/mongoid_spec.rb +65 -4
  44. metadata +8 -2
data/Gemfile CHANGED
@@ -36,13 +36,15 @@ group :mongoid do
36
36
  case ENV['CI_ORM_VERSION']
37
37
  when 'head'
38
38
  gem 'mongoid', :git => 'git://github.com/mongoid/mongoid.git'
39
+ gem 'mongoid-paperclip', :require => 'mongoid_paperclip', :git => 'git://github.com/mshibuya/mongoid-paperclip.git', :branch => 'fix-stop-patching-logger'
39
40
  # For now, carrierwave-mongoid's mongoid dependency is restricted to '~> 2.1'
40
41
  gem 'carrierwave-mongoid', :require => 'carrierwave/mongoid', :git => 'git://github.com/tanordheim/carrierwave-mongoid.git', :branch => 'mongoid_3_0'
42
+ gem 'database_cleaner', :git => 'git://github.com/potatosalad/database_cleaner.git'
41
43
  else
42
44
  gem 'mongoid'
45
+ gem 'mongoid-paperclip', :require => 'mongoid_paperclip'
43
46
  gem 'carrierwave-mongoid', :require => 'carrierwave/mongoid'
44
47
  end
45
- gem 'mongoid-paperclip', :require => 'mongoid_paperclip'
46
48
  end
47
49
 
48
50
  group :debug do
data/README.md CHANGED
@@ -58,7 +58,10 @@ And then run:
58
58
 
59
59
  This generator will install RailsAdmin and [Devise](https://github.com/plataformatec/devise) if you
60
60
  don't already have it installed. [Devise](https://github.com/plataformatec/devise) is strongly
61
- recommended to protect your data from anonymous users.
61
+ recommended to protect your data from anonymous users. Note: If you do not already have [Devise](https://github.com/plataformatec/devise)
62
+ installed, make sure you remove the registerable module from the generated user model.
63
+
64
+
62
65
  It will modify your `config/routes.rb`, adding:
63
66
 
64
67
  ```ruby
@@ -67,6 +70,10 @@ mount RailsAdmin::Engine => '/admin', :as => 'rails_admin' # Feel free to change
67
70
 
68
71
  It will also add an intializer that will help you getting started. (head for config/initializers/rails_admin.rb)
69
72
 
73
+ Finally run:
74
+
75
+ $ bundle exec rake db:migrate
76
+
70
77
  Optionally, you may wish to set up [Cancan](https://github.com/ryanb/cancan),
71
78
  [PaperTrail](https://github.com/airblade/paper_trail), [CKeditor](https://github.com/galetahub/ckeditor)
72
79
 
@@ -103,24 +103,28 @@
103
103
  this.addAll.click(function(e){
104
104
  widget._select($('option', widget.collection));
105
105
  e.preventDefault();
106
+ widget.selection.trigger('change');
106
107
  });
107
108
 
108
109
  /* Add to selection */
109
110
  this.add.click(function(e){
110
111
  widget._select($(':selected', widget.collection));
111
112
  e.preventDefault();
113
+ widget.selection.trigger('change');
112
114
  });
113
115
 
114
116
  /* Remove all from selection */
115
117
  this.removeAll.click(function(e){
116
118
  widget._deSelect($('option', widget.selection));
117
119
  e.preventDefault();
120
+ widget.selection.trigger('change');
118
121
  });
119
122
 
120
123
  /* Remove from selection */
121
124
  this.remove.click(function(e){
122
125
  widget._deSelect($(':selected', widget.selection));
123
126
  e.preventDefault();
127
+ widget.selection.trigger('change');
124
128
  });
125
129
 
126
130
  var timeout = null;
@@ -52,6 +52,7 @@
52
52
  select: function(event, ui) {
53
53
  var option = $('<option value="' + ui.item.id + '" selected="selected">' + ui.item.value + '</option>');
54
54
  select.html(option);
55
+ select.trigger("change", ui.item.id);
55
56
  self._trigger("selected", event, {
56
57
  item: option
57
58
  });
@@ -79,6 +80,14 @@
79
80
  }
80
81
  }
81
82
  })
83
+ .keyup(function() {
84
+ /* Clear select options and trigger change if selected item is deleted */
85
+ if ($(this).val().length == 0) {
86
+ select.empty();
87
+ select.trigger("change");
88
+ }
89
+ })
90
+
82
91
  if(select.attr('placeholder'))
83
92
  input.attr('placeholder', select.attr('placeholder'))
84
93
 
@@ -125,11 +125,23 @@ $(document).live 'rails_admin.dom_ready', ->
125
125
  # ckeditor
126
126
 
127
127
  $('form [data-richtext=ckeditor]').not('.ckeditored').each ->
128
- window.CKEDITOR_BASEPATH = '/assets/ckeditor/'
129
128
  options = $(this).data('options')
129
+ window.CKEDITOR_BASEPATH = options['base_location']
130
130
  if not window.CKEDITOR
131
131
  $(window.document).append('<script src="' + options['jspath'] + '"><\/script>')
132
132
  if instance = window.CKEDITOR.instances[this.id]
133
133
  instance.destroy(true)
134
134
  window.CKEDITOR.replace(this, options['options'])
135
135
  $(this).addClass('ckeditored')
136
+
137
+ #codemirror
138
+
139
+ $('form [data-richtext=codemirror]').not('.codemirrored').each ->
140
+ options = $(this).data('options')
141
+ if not window.CodeMirror
142
+ $(window.document).append('<script src="' + options['jspath'] + '" type="text\/javascript"><\/script>')
143
+ $('head').append('<script src="' + options['locations']['mode'] + '" type="text\/javascript"><\/script>')
144
+ $('head').append('<link href="' + options['csspath'] + '" rel="stylesheet" media="all" type="text\/css">')
145
+ $('head').append('<link href="' + options['locations']['theme'] + '" rel="stylesheet" media="all" type="text\/css">')
146
+ CodeMirror.fromTextArea(this,{mode:options['options']['mode'],theme:options['options']['theme']})
147
+ $(this).addClass('codemirrored')
@@ -4,7 +4,9 @@ $("#list input.toggle").live "click", ->
4
4
  $("#list [name='bulk_ids[]']").attr "checked", $(this).is(":checked")
5
5
 
6
6
  $('.pjax').live 'click', (event) ->
7
- if $.support.pjax
7
+ if event.which > 1 || event.metaKey || event.ctrlKey
8
+ return
9
+ else if $.support.pjax
8
10
  event.preventDefault()
9
11
  $.pjax
10
12
  container: $(this).data('pjax-container') || '[data-pjax-container]'
@@ -24,7 +26,7 @@ $('.pjax-form').live 'submit', (event) ->
24
26
  $(document)
25
27
  .on 'pjax:start', ->
26
28
  $('#loading').show()
27
- .on 'pjax:end', ->
29
+ .on 'pjax:end', ->
28
30
  $('#loading').hide()
29
31
 
30
32
  $('[data-target]').live 'click', ->
@@ -34,7 +34,6 @@
34
34
  @import "bootstrap/grid";
35
35
  @import "bootstrap/layouts";
36
36
  @import "bootstrap/type";
37
- @import "bootstrap/code";
38
37
  @import "bootstrap/forms";
39
38
  @import "bootstrap/tables";
40
39
  @import "bootstrap/sprites";
@@ -55,6 +55,8 @@ module RailsAdmin
55
55
  instance_eval &RailsAdmin::Config.current_user_method
56
56
  end
57
57
 
58
+ alias_method :user_for_paper_trail, :_current_user
59
+
58
60
  def _attr_accessible_role
59
61
  instance_eval &RailsAdmin::Config.attr_accessible_role
60
62
  end
@@ -123,7 +123,7 @@ module RailsAdmin
123
123
  options = {}
124
124
  options = options.merge(:page => (params[:page] || 1).to_i, :per => (params[:per] || model_config.list.items_per_page)) if pagination
125
125
  options = options.merge(:include => associations) unless associations.blank?
126
- options = options.merge(get_sort_hash(model_config)) unless params[:associated_collection]
126
+ options = options.merge(get_sort_hash(model_config))
127
127
  options = options.merge(:query => params[:query]) if params[:query].present?
128
128
  options = options.merge(:filters => params[:f]) if params[:f].present?
129
129
  options = options.merge(:bulk_ids => params[:bulk_ids]) if params[:bulk_ids]
@@ -114,7 +114,7 @@ module RailsAdmin
114
114
  content_tag(:ul, :class => 'dropdown-menu', :style => 'left:auto; right:0;') do
115
115
  actions.map do |action|
116
116
  content_tag :li do
117
- link_to_function wording_for(:bulk_link, action), "jQuery('#bulk_action').val('#{action.action_name}'); jQuery('#bulk_form').submit()"
117
+ link_to wording_for(:bulk_link, action), '#', :onclick => "jQuery('#bulk_action').val('#{action.action_name}'); jQuery('#bulk_form').submit(); return false;"
118
118
  end
119
119
  end.join.html_safe
120
120
  end
@@ -2,11 +2,11 @@
2
2
  - actions(:root).each do |action|
3
3
  %li= link_to wording_for(:menu, action), { :action => action.action_name, :controller => 'rails_admin/main' }, :class => 'pjax'
4
4
  - if main_app_root_path = (main_app.root_path rescue false)
5
- %li= link_to t('home.name').capitalize, main_app_root_path, :class => 'pjax'
5
+ %li= link_to t('home.name').capitalize, main_app_root_path
6
6
  - if _current_user
7
7
  - if user_link = edit_user_link
8
8
  %li= user_link
9
9
  - if defined?(Devise) && (devise_scope = request.env["warden"].config[:default_scope] rescue false) && (logout_path = main_app.send("destroy_#{devise_scope}_session_path") rescue false)
10
10
  %li= link_to content_tag('span', t('admin.misc.log_out'), :class => 'label label-important'), logout_path, :method => Devise.sign_out_via
11
- - if _current_user.respond_to?(:email)
11
+ - if _current_user.respond_to?(:email) && _current_user.email.present?
12
12
  %li= image_tag "#{(request.ssl? ? 'https://secure' : 'http://www')}.gravatar.com/avatar/#{Digest::MD5.hexdigest _current_user.email}?s=30", :style => 'padding-top:5px'
@@ -2,11 +2,20 @@
2
2
  if field.ckeditor
3
3
  richtext = 'ckeditor'
4
4
  js_data = {
5
- :jspath => '/assets/ckeditor/ckeditor.js',
5
+ :jspath => field.ckeditor_location,
6
+ :base_location => field.ckeditor_base_location,
6
7
  :options => {
7
8
  :customConfig => field.ckeditor_config_js
8
9
  }
9
10
  }
11
+ elsif field.codemirror
12
+ richtext = 'codemirror'
13
+ js_data = {
14
+ :csspath => field.codemirror_css_location,
15
+ :jspath => field.codemirror_js_location,
16
+ :options => field.codemirror_config,
17
+ :locations => field.codemirror_assets
18
+ }
10
19
  else
11
20
  richtext = false
12
21
  js_data = {}
@@ -132,7 +132,7 @@
132
132
  %td.last.links
133
133
  %ul.inline= menu_for :member, @abstract_model, object, true
134
134
  - if @objects.respond_to?(:total_count)
135
- - total_count = @objects.total_count
135
+ - total_count = @objects.total_count.to_i
136
136
  = paginate(@objects, :theme => 'twitter-bootstrap', :remote => true)
137
137
  = link_to(t("admin.misc.show_all"), index_path(params.merge(:all => true)), :class => "show-all btn clearfix pjax") unless total_count > 100 || total_count <= @objects.to_a.size
138
138
  .clearfix.total-count= "#{total_count} #{@model_config.label_plural.downcase}"
@@ -1,5 +1,4 @@
1
1
  if defined?(::Mongoid::Document)
2
2
  require 'rails_admin/adapters/mongoid/extension'
3
3
  Mongoid::Document.send(:include, RailsAdmin::Adapters::Mongoid::Extension)
4
- Mongoid::NestedAttributes::ClassMethods.send(:include, RailsAdmin::Adapters::Mongoid::NestedAttributesExtension)
5
4
  end
@@ -5,8 +5,14 @@ module RailsAdmin
5
5
  module Adapters
6
6
  module ActiveRecord
7
7
  DISABLED_COLUMN_TYPES = [:tsvector, :blob, :binary, :spatial, :hstore]
8
- AR_ADAPTER = ::ActiveRecord::Base.configurations[Rails.env]['adapter']
9
- LIKE_OPERATOR = AR_ADAPTER == "postgresql" ? 'ILIKE' : 'LIKE'
8
+
9
+ def ar_adapter
10
+ Rails.configuration.database_configuration[Rails.env]['adapter']
11
+ end
12
+
13
+ def like_operator
14
+ ar_adapter == "postgresql" ? 'ILIKE' : 'LIKE'
15
+ end
10
16
 
11
17
  def new(params = {})
12
18
  AbstractObject.new(model.new(params))
@@ -184,7 +190,7 @@ module RailsAdmin
184
190
  else
185
191
  return
186
192
  end
187
- ["(#{column} #{LIKE_OPERATOR} ?)", value]
193
+ ["(#{column} #{like_operator} ?)", value]
188
194
  when :date
189
195
  start_date, end_date = get_filtering_duration(operator, value)
190
196
 
@@ -15,8 +15,13 @@ module RailsAdmin
15
15
  def get(id)
16
16
  begin
17
17
  AbstractObject.new(model.find(id))
18
- rescue BSON::InvalidObjectId, ::Mongoid::Errors::DocumentNotFound
19
- nil
18
+ rescue => e
19
+ if ['BSON::InvalidObjectId', 'Mongoid::Errors::DocumentNotFound',
20
+ 'Mongoid::Errors::InvalidFind', 'Moped::Errors::InvalidObjectId'].include? e.class.to_s
21
+ nil
22
+ else
23
+ raise e
24
+ end
20
25
  end
21
26
  end
22
27
 
@@ -82,6 +87,7 @@ module RailsAdmin
82
87
  "BigDecimal" => { :type => :decimal },
83
88
  "Boolean" => { :type => :boolean },
84
89
  "BSON::ObjectId" => { :type => :bson_object_id, :serial? => (name == primary_key) },
90
+ "Moped::BSON::ObjectId" => { :type => :bson_object_id, :serial? => (name == primary_key) },
85
91
  "Date" => { :type => :date },
86
92
  "DateTime" => { :type => :datetime },
87
93
  "Float" => { :type => :float },
@@ -118,7 +124,7 @@ module RailsAdmin
118
124
  end
119
125
 
120
126
  def table_name
121
- model.collection.name
127
+ model.collection_name.to_s
122
128
  end
123
129
 
124
130
  def serialized_attributes
@@ -143,7 +149,7 @@ module RailsAdmin
143
149
  fields.each do |field|
144
150
  conditions_per_collection = {}
145
151
  field.searchable_columns.flatten.each do |column_infos|
146
- collection_name, column_name = column_infos[:column].split('.')
152
+ collection_name, column_name = parse_collection_name(column_infos[:column])
147
153
  statement = build_statement(column_name, column_infos[:type], query, field.search_operator)
148
154
  if statement
149
155
  conditions_per_collection[collection_name] ||= []
@@ -171,7 +177,7 @@ module RailsAdmin
171
177
  field = fields.find{|f| f.name.to_s == field_name}
172
178
  next unless field
173
179
  field.searchable_columns.each do |column_infos|
174
- collection_name, column_name = column_infos[:column].split('.')
180
+ collection_name, column_name = parse_collection_name(column_infos[:column])
175
181
  statement = build_statement(column_name, column_infos[:type], filter_dump[:v], (filter_dump[:o] || 'default'))
176
182
  if statement
177
183
  conditions_per_collection[collection_name] ||= []
@@ -261,7 +267,7 @@ module RailsAdmin
261
267
  return if value.blank?
262
268
  { column => { "$in" => Array.wrap(value) } }
263
269
  when :belongs_to_association, :bson_object_id
264
- object_id = (BSON::ObjectId(value) rescue nil)
270
+ object_id = (BSON::ObjectId.from_string(value) rescue nil)
265
271
  { column => object_id } if object_id
266
272
  end
267
273
  end
@@ -337,7 +343,8 @@ module RailsAdmin
337
343
 
338
344
  def length_validation_lookup(name)
339
345
  shortest = model.validators.select do |validator|
340
- validator.attributes.include?(name.to_sym) &&
346
+ validator.respond_to?(:attributes) &&
347
+ validator.attributes.include?(name.to_sym) &&
341
348
  validator.kind == :length &&
342
349
  validator.options[:maximum]
343
350
  end.min{|a, b| a.options[:maximum] <=> b.options[:maximum] }
@@ -348,6 +355,15 @@ module RailsAdmin
348
355
  end
349
356
  end
350
357
 
358
+ def parse_collection_name(column)
359
+ collection_name, column_name = column.split('.')
360
+ if [:embeds_one, :embeds_many].include?(model.associations[collection_name].try(:macro).try(:to_sym))
361
+ [table_name, column]
362
+ else
363
+ [collection_name, column_name]
364
+ end
365
+ end
366
+
351
367
  def make_condition_for_current_collection(target_field, conditions_per_collection)
352
368
  result =[]
353
369
  conditions_per_collection.each do |collection_name, conditions|
@@ -37,11 +37,6 @@ RUBY
37
37
  end
38
38
  end
39
39
  end
40
-
41
- def destroy
42
- object.destroy
43
- object
44
- end
45
40
  end
46
41
  end
47
42
  end
@@ -5,8 +5,13 @@ module RailsAdmin
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
- def self.rails_admin(&block)
9
- RailsAdmin::Config.model(self, &block)
8
+ class_attribute :nested_attributes_options
9
+ self.nested_attributes_options = {}
10
+ class << self
11
+ def rails_admin(&block)
12
+ RailsAdmin::Config.model(self, &block)
13
+ end
14
+ alias_method_chain :accepts_nested_attributes_for, :rails_admin
10
15
  end
11
16
  end
12
17
 
@@ -21,26 +26,18 @@ module RailsAdmin
21
26
  self.send(value)
22
27
  end
23
28
  end
24
- end
25
-
26
- module NestedAttributesExtension
27
- extend ActiveSupport::Concern
28
-
29
- included do
30
- attr_reader :nested_attributes_options
31
- alias_method_chain :accepts_nested_attributes_for, :rails_admin
32
- end
33
29
 
34
- # Mongoid accepts_nested_attributes_for does not store options in accessible scope,
35
- # so we intercept the call and store it in instance variable which can be accessed from outside
36
- def accepts_nested_attributes_for_with_rails_admin(*args)
37
- @nested_attributes_options ||= {}
38
- options = args.extract_options!
39
- args.each do |arg|
40
- @nested_attributes_options[arg.to_sym] = options.reverse_merge(:allow_destroy=>false, :update_only=>false)
30
+ module ClassMethods
31
+ # Mongoid accepts_nested_attributes_for does not store options in accessible scope,
32
+ # so we intercept the call and store it in instance variable which can be accessed from outside
33
+ def accepts_nested_attributes_for_with_rails_admin(*args)
34
+ options = args.extract_options!
35
+ args.each do |arg|
36
+ self.nested_attributes_options[arg.to_sym] = options.reverse_merge(:allow_destroy=>false, :update_only=>false)
37
+ end
38
+ args << options
39
+ accepts_nested_attributes_for_without_rails_admin(*args)
41
40
  end
42
- args << options
43
- accepts_nested_attributes_for_without_rails_admin(*args)
44
41
  end
45
42
  end
46
43
  end
@@ -32,7 +32,7 @@ module RailsAdmin
32
32
  elsif request.delete? # DESTROY
33
33
 
34
34
  @auditing_adapter && @auditing_adapter.delete_object("Destroyed #{@model_config.with(:object => @object).object_label}", @object, @abstract_model, _current_user)
35
- if @abstract_model.destroy(@object)
35
+ if @object.destroy
36
36
  flash[:success] = t("admin.flash.successful", :name => @model_config.label, :action => t("admin.actions.delete.done"))
37
37
  else
38
38
  flash[:error] = t("admin.flash.error", :name => @model_config.label, :action => t("admin.actions.delete.done"))
@@ -18,11 +18,13 @@ module RailsAdmin
18
18
 
19
19
  register_instance_option :controller do
20
20
  Proc.new do
21
- render @action.template_name
21
+ respond_to do |format|
22
+ format.json { render :json => @object }
23
+ format.html { render @action.template_name }
24
+ end
22
25
  end
23
26
  end
24
27
 
25
-
26
28
  register_instance_option :link_icon do
27
29
  'icon-info-sign'
28
30
  end
@@ -47,7 +47,12 @@ module RailsAdmin
47
47
  scope.limit(associated_collection_scope_limit)
48
48
  end
49
49
  end
50
-
50
+
51
+ # inverse relationship
52
+ register_instance_option :inverse_of do
53
+ association[:inverse_of]
54
+ end
55
+
51
56
  # preload entire associated collection (per associated_collection_scope) on load
52
57
  # Be sure to set limit in associated_collection_scope if set is large
53
58
  register_instance_option :associated_collection_cache_all do
@@ -73,11 +78,6 @@ module RailsAdmin
73
78
  def foreign_key
74
79
  association[:foreign_key]
75
80
  end
76
-
77
- # Reader for the inverse relationship
78
- def inverse_of
79
- association[:inverse_of]
80
- end
81
81
 
82
82
  # Reader whether this is a polymorphic association
83
83
  def polymorphic?
@@ -28,8 +28,11 @@ module RailsAdmin
28
28
 
29
29
  def parse_input(params)
30
30
  begin
31
- params[name] = (params[name].blank? ? nil : BSON::ObjectId(params[name])) if params[name].is_a?(::String)
32
- rescue BSON::InvalidObjectId
31
+ params[name] = (params[name].blank? ? nil : BSON::ObjectId.from_string(params[name])) if params[name].is_a?(::String)
32
+ rescue => e
33
+ unless ['BSON::InvalidObjectId', 'Moped::Errors::InvalidObjectId'].include? e.class.to_s
34
+ raise e
35
+ end
33
36
  end
34
37
  end
35
38
  end
@@ -19,6 +19,47 @@ module RailsAdmin
19
19
  "/assets/ckeditor/config.js"
20
20
  end
21
21
 
22
+ #Use this if you want to point to a cloud instances of CKeditor
23
+ register_instance_option(:ckeditor_location) do
24
+ '/assets/ckeditor/ckeditor.js'
25
+ end
26
+
27
+ #Use this if you want to point to a cloud instances of the base CKeditor
28
+ register_instance_option(:ckeditor_base_location) do
29
+ '/assets/ckeditor/'
30
+ end
31
+
32
+ # Codemirror is disabled by default and CKEditor takes precedence
33
+ register_instance_option(:codemirror) do
34
+ false
35
+ end
36
+
37
+ #Pass the theme and mode for Codemirror
38
+ register_instance_option(:codemirror_config) do
39
+ {
40
+ :mode => 'css',
41
+ :theme => 'night'
42
+ }
43
+ end
44
+
45
+ #Pass the location of the theme and mode for Codemirror
46
+ register_instance_option(:codemirror_assets) do
47
+ {
48
+ :mode => '/assets/codemirror/modes/css.js',
49
+ :theme => '/assets/codemirror/themes/night.css'
50
+ }
51
+ end
52
+
53
+ #Use this if you want to point to a cloud instances of CodeMirror
54
+ register_instance_option(:codemirror_js_location) do
55
+ '/assets/codemirror.js'
56
+ end
57
+
58
+ #Use this if you want to point to a cloud instances of CodeMirror
59
+ register_instance_option(:codemirror_css_location) do
60
+ '/assets/codemirror.css'
61
+ end
62
+
22
63
  register_instance_option(:html_attributes) do
23
64
  {
24
65
  :cols => "48",
@@ -11,7 +11,7 @@ require 'rails_admin'
11
11
  module RailsAdmin
12
12
  class Engine < Rails::Engine
13
13
  isolate_namespace RailsAdmin
14
- initializer "RailsAdmin precompile hook" do |app|
14
+ initializer "RailsAdmin precompile hook", :group => :assets do |app|
15
15
  app.config.assets.precompile += ['rails_admin/rails_admin.js', 'rails_admin/rails_admin.css', 'rails_admin/jquery.colorpicker.js', 'rails_admin/jquery.colorpicker.css']
16
16
  end
17
17
 
@@ -5,6 +5,8 @@ class RailsAdmin::History < ActiveRecord::Base
5
5
 
6
6
  attr_accessible :message, :item, :table, :username
7
7
 
8
+ default_scope order('id DESC')
9
+
8
10
  def self.latest
9
11
  self.limit(100)
10
12
  end
@@ -49,22 +51,14 @@ class RailsAdmin::History < ActiveRecord::Base
49
51
  def self.history_for_model(model, query, sort, sort_reverse, all, page, per_page = (RailsAdmin::Config.default_items_per_page || 20))
50
52
  history = where(:table => model.pretty_name)
51
53
  history = history.where("message LIKE ? OR username LIKE ?", "%#{query}%", "%#{query}%") if query
52
- if sort
53
- history = history.order(sort_reverse == "true" ? "#{sort} DESC" : sort)
54
- else
55
- history = history.order('created_at DESC')
56
- end
54
+ history = history.order(sort_reverse == "true" ? "#{sort} DESC" : sort) if sort
57
55
  all ? history : history.send(Kaminari.config.page_method_name, page.presence || "1").per(per_page)
58
56
  end
59
57
 
60
58
  def self.history_for_object(model, object, query, sort, sort_reverse, all, page, per_page = (RailsAdmin::Config.default_items_per_page || 20))
61
59
  history = where(:table => model.pretty_name, :item => object.id)
62
60
  history = history.where("message LIKE ? OR username LIKE ?", "%#{query}%", "%#{query}%") if query
63
- if sort
64
- history = history.order(sort_reverse == "true" ? "#{sort} DESC" : sort)
65
- else
66
- history = history.order('created_at DESC')
67
- end
61
+ history = history.order(sort_reverse == "true" ? "#{sort} DESC" : sort) if sort
68
62
  all ? history : history.send(Kaminari.config.page_method_name, page.presence || "1").per(per_page)
69
63
  end
70
64
  end
@@ -1,3 +1,3 @@
1
1
  module RailsAdmin
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -67,7 +67,7 @@ describe RailsAdmin::MainController do
67
67
  end
68
68
 
69
69
  it "scopes associated collection records according to bindings" do
70
- @team.revenue = 3
70
+ @team.revenue = BigDecimal.new('3')
71
71
  @team.save
72
72
 
73
73
  @players = 5.times.map do
@@ -107,7 +107,14 @@ describe RailsAdmin::MainController do
107
107
  end
108
108
  end
109
109
  controller.list_entries.length.should == @players.size
110
+ end
111
+
112
+ it "orders associated collection records by desc" do
113
+ @players = 3.times.map do
114
+ FactoryGirl.create :player
115
+ end
110
116
 
117
+ controller.list_entries.to_a.first.should == @players.last
111
118
  end
112
119
  end
113
120
 
@@ -28,7 +28,7 @@ group :active_record do
28
28
  gem 'sqlite3', '~> 1.3'
29
29
  end
30
30
  end
31
- gem 'paperclip', '~> 2.4'
31
+ gem 'paperclip', '~> 2.7'
32
32
  gem 'carrierwave'
33
33
  gem 'dragonfly'
34
34
  end
@@ -44,8 +44,8 @@ group :mongoid do
44
44
  gem 'mongoid'
45
45
  gem 'carrierwave-mongoid', :require => 'carrierwave/mongoid'
46
46
  end
47
- gem 'mongoid-paperclip', :require => 'mongoid_paperclip'
48
- gem 'paperclip', '~> 2.4'
47
+ gem 'mongoid-paperclip', :require => 'mongoid_paperclip', :git => 'git://github.com/mshibuya/mongoid-paperclip.git', :branch => 'fix-stop-patching-logger'
48
+ gem 'paperclip', '~> 2.7'
49
49
  gem 'dragonfly'
50
50
  end
51
51
 
@@ -13,6 +13,10 @@ class Player < ActiveRecord::Base
13
13
  record.errors.add(:base, "Player is cheating") if value.to_s =~ /on steroids/
14
14
  end
15
15
 
16
+ before_destroy :destroy_hook
17
+
18
+ def destroy_hook; end
19
+
16
20
  def draft_id
17
21
  self.draft.try :id
18
22
  end
@@ -27,6 +27,10 @@ class Player
27
27
  has_one :draft, :dependent => :destroy
28
28
  has_many :comments, :as => :commentable
29
29
 
30
+ before_destroy :destroy_hook
31
+
32
+ def destroy_hook; end
33
+
30
34
  def draft_id
31
35
  self.draft.try :id
32
36
  end
@@ -20,7 +20,7 @@ class Team
20
20
 
21
21
  attr_accessible :name, :division_id, :logo_url, :manager, :ballpark, :mascot, :founded, :wins, :losses, :win_percentage, :revenue, :color, :custom_field, :fan_ids, :player_ids, :comment_ids
22
22
 
23
- has_many :players, :inverse_of => :team, :order => :_id
23
+ has_many :players, :inverse_of => :team, :order => :_id.asc
24
24
  has_and_belongs_to_many :fans
25
25
  has_many :comments, :as => :commentable
26
26
 
@@ -6,8 +6,8 @@ class User
6
6
  devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable
7
7
 
8
8
  ## Database authenticatable
9
- field :email, :type => String, :null => false
10
- field :encrypted_password, :type => String, :null => false
9
+ field :email, :type => String
10
+ field :encrypted_password, :type => String
11
11
 
12
12
  ## Recoverable
13
13
  field :reset_password_token, :type => String
@@ -9,9 +9,6 @@ Devise.setup do |config|
9
9
  # Configure the class responsible to send e-mails.
10
10
  # config.mailer = "Devise::Mailer"
11
11
 
12
- # Automatically apply schema changes in tableless databases
13
- config.apply_schema = false
14
-
15
12
  # ==> ORM configuration
16
13
  # Load and configure the ORM. Supports :active_record (default) and
17
14
  # :mongoid (bson_ext recommended) by default. Other ORMs may be
@@ -95,7 +92,7 @@ Devise.setup do |config|
95
92
  # the user cannot access the website without confirming his account.
96
93
  # config.allow_unconfirmed_access_for = 2.days
97
94
 
98
- # If true, requires any email changes to be confirmed (exctly the same way as
95
+ # If true, requires any email changes to be confirmed (exactly the same way as
99
96
  # initial account confirmation) to be applied. Requires additional unconfirmed_email
100
97
  # db field (see migrations). Until confirmed new email is stored in
101
98
  # unconfirmed email column, and copied to email column on successful confirmation.
@@ -111,13 +108,9 @@ Devise.setup do |config|
111
108
  # If true, extends the user's remember period when remembered via cookie.
112
109
  # config.extend_remember_period = false
113
110
 
114
- # If true, uses the password salt as remember token. This should be turned
115
- # to false if you are not using database authenticatable.
116
- config.use_salt_as_remember_token = true
117
-
118
111
  # Options to be passed to the created cookie. For instance, you can set
119
112
  # :secure => true in order to force SSL only cookies.
120
- # config.cookie_options = {}
113
+ # config.rememberable_options = {}
121
114
 
122
115
  # ==> Configuration for :validatable
123
116
  # Range for password length. Default is 6..128.
@@ -3,11 +3,8 @@ if defined?(Mongoid::Document)
3
3
 
4
4
  app = Dragonfly[:images]
5
5
 
6
- # Configure to use ImageMagick, Rails defaults, and the Mongo data store
6
+ # Configure to use ImageMagick, Rails defaults
7
7
  app.configure_with(:imagemagick)
8
- app.configure_with(:rails) do |c|
9
- c.datastore = Dragonfly::DataStorage::MongoDataStore.new :db => Mongoid.database
10
- end
11
8
 
12
9
  # Allow all mongoid models to use the macro 'image_accessor'
13
10
  app.define_macro_on_include(Mongoid::Document, :image_accessor)
@@ -5,7 +5,18 @@ defaults: &defaults
5
5
  development:
6
6
  <<: *defaults
7
7
  database: dummy_app_development
8
+ sessions:
9
+ default:
10
+ database: dummy_app_development
11
+ hosts:
12
+ - localhost:27017
13
+
8
14
 
9
15
  test:
10
16
  <<: *defaults
11
17
  database: dummy_app_test
18
+ sessions:
19
+ default:
20
+ database: dummy_app_test
21
+ hosts:
22
+ - localhost:27017
@@ -15,19 +15,27 @@ describe "RailsAdmin Basic Destroy" do
15
15
  it "should destroy an object" do
16
16
  @player.should be_nil
17
17
  end
18
+
19
+ it "should show success message" do
20
+ should have_content('Player successfully deleted')
21
+ end
18
22
  end
19
23
 
20
- describe "destroy with errors" do
24
+ describe "handle destroy errors" do
21
25
  before(:each) do
22
- Player.any_instance.stub(:destroy).and_return false
26
+ Player.any_instance.stub(:destroy_hook).and_return false
23
27
  @player = FactoryGirl.create :player
24
28
  visit delete_path(:model_name => "player", :id => @player.id)
25
29
  click_button "Yes, I'm sure"
26
30
  end
27
31
 
28
- it "should destroy an object" do
32
+ it "should not destroy an object" do
29
33
  @player.reload.should be
30
34
  end
35
+
36
+ it "should show error message" do
37
+ should have_content('Player failed to be deleted')
38
+ end
31
39
  end
32
40
 
33
41
  describe "destroy" do
@@ -918,6 +918,26 @@ describe "RailsAdmin Config DSL Edit Section" do
918
918
  end
919
919
  end
920
920
 
921
+ describe "CodeMirror Support" do
922
+
923
+ it "should start with CodeMirror disabled" do
924
+ field = RailsAdmin::config("Draft").edit.fields.find{|f| f.name == :notes}
925
+ field.codemirror.should be false
926
+ end
927
+
928
+ it "should add Javascript to enable CodeMirror" do
929
+ RailsAdmin.config Draft do
930
+ edit do
931
+ field :notes do
932
+ codemirror true
933
+ end
934
+ end
935
+ end
936
+ visit new_path(:model_name => "draft")
937
+ should have_selector('textarea#draft_notes[data-richtext="codemirror"]')
938
+ end
939
+ end
940
+
921
941
  describe "Paperclip Support" do
922
942
 
923
943
  it "should show a file upload field" do
@@ -13,6 +13,24 @@ describe "RailsAdmin Config DSL Show Section" do
13
13
  visit show_path(:model_name => "team", :id => team.id)
14
14
  end
15
15
 
16
+ describe "JSON show view" do
17
+ before do
18
+ @player = FactoryGirl.create :player
19
+ visit uri
20
+ end
21
+
22
+ let(:uri) { show_path(:model_name => 'player', :id => @player.id, :format => :json) }
23
+ let(:body) { page.body }
24
+
25
+ it 'should create a JSON uri' do
26
+ uri.should == "/admin/player/#{@player.id}.json"
27
+ end
28
+
29
+ it 'should contain the JSONified object' do
30
+ body.should include(@player.to_json)
31
+ end
32
+ end
33
+
16
34
  describe "compact_show_view" do
17
35
 
18
36
  it 'should hide empty fields in show view by default' do
@@ -72,6 +72,12 @@ describe "RailsAdmin History", :active_record => true do
72
72
  RailsAdmin::History.latest.count.should == 100
73
73
  end
74
74
 
75
+ it 'should get latest ones orderly' do
76
+ latest = RailsAdmin::History.latest
77
+ latest.first.message.should == "change 100"
78
+ latest.last.message.should == "change 1"
79
+ end
80
+
75
81
  it "should render a XHR request successfully" do
76
82
  xhr :get, history_index_path(@model, :page => 2)
77
83
  end
@@ -121,4 +121,22 @@ describe "RailsAdmin" do
121
121
  end
122
122
  end
123
123
 
124
+ describe "secondary navigation" do
125
+ it "should have Gravatar image" do
126
+ visit dashboard_path
127
+ should have_selector("ul.nav.pull-right li img")
128
+ end
129
+
130
+ it "should not show Gravatar when user doesn't have email method" do
131
+ User.any_instance.stub(:respond_to?).with(:email).and_return(false)
132
+ visit dashboard_path
133
+ should_not have_selector("ul.nav.pull-right li img")
134
+ end
135
+
136
+ it "should not cause error when email is nil" do
137
+ User.any_instance.stub(:email).and_return(nil)
138
+ visit dashboard_path
139
+ should have_selector("body.rails_admin")
140
+ end
141
+ end
124
142
  end
data/spec/orm/mongoid.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require 'rails_admin/adapters/mongoid'
2
2
 
3
+ Paperclip.logger = Logger.new(nil)
4
+
3
5
  class Tableless
4
6
  include Mongoid::Document
5
7
 
@@ -179,8 +179,8 @@ describe 'RailsAdmin::Adapters::ActiveRecord', :active_record => true do
179
179
  @abstract_model.get('abc').should be_nil
180
180
  end
181
181
 
182
- it "#first returns first item" do
183
- @abstract_model.first.should == @players.first
182
+ it "#first returns a player" do
183
+ @players.should include @abstract_model.first
184
184
  end
185
185
 
186
186
  it "#count returns count of items" do
@@ -206,7 +206,7 @@ describe 'RailsAdmin::Adapters::ActiveRecord', :active_record => true do
206
206
  end
207
207
 
208
208
  it "supports limiting" do
209
- @abstract_model.all(:limit => 2).count.should == 2
209
+ @abstract_model.all(:limit => 2).should have(2).items
210
210
  end
211
211
 
212
212
  it "supports retrieval by bulk_ids" do
@@ -238,7 +238,24 @@ describe 'RailsAdmin::Adapters::Mongoid', :mongoid => true do
238
238
  lambda{ RailsAdmin::AbstractModel.new(MongoEmbedsMany).associations }.should raise_error(RuntimeError,
239
239
  "Embbeded association without accepts_nested_attributes_for can't be handled by RailsAdmin,\nbecause embedded model doesn't have top-level access.\nPlease add `accepts_nested_attributes_for :mongo_embeddeds' line to `MongoEmbedsMany' model.\n"
240
240
  )
241
- end
241
+ end
242
+
243
+ it "should work with inherited embeds_many model" do
244
+ class MongoEmbedsParent
245
+ include Mongoid::Document
246
+ embeds_many :mongo_embeddeds
247
+ accepts_nested_attributes_for :mongo_embeddeds
248
+ end
249
+
250
+ class MongoEmbedded
251
+ include Mongoid::Document
252
+ embedded_in :mongo_embeds_many
253
+ end
254
+
255
+ class MongoEmbedsChild < MongoEmbedsParent; end
256
+
257
+ lambda{ RailsAdmin::AbstractModel.new(MongoEmbedsChild).associations }.should_not raise_error
258
+ end
242
259
  end
243
260
 
244
261
  describe "#properties" do
@@ -380,6 +397,27 @@ describe 'RailsAdmin::Adapters::Mongoid', :mongoid => true do
380
397
  :length => 255 }
381
398
  ]
382
399
  end
400
+
401
+ it "detects validation length properly" do
402
+ class LengthValiated
403
+ include Mongoid::Document
404
+ field :text, :type => String
405
+ validates :text, :length => {:maximum => 50}
406
+ end
407
+ RailsAdmin::AbstractModel.new('LengthValiated').send(:length_validation_lookup, :text).should == 50
408
+ end
409
+
410
+ it "should not cause problem with custom validators" do
411
+ class MyCustomValidator < ActiveModel::Validator
412
+ def validate(r); end
413
+ end
414
+ class CustomValiated
415
+ include Mongoid::Document
416
+ field :text, :type => String
417
+ validates_with MyCustomValidator
418
+ end
419
+ lambda{ RailsAdmin::AbstractModel.new('CustomValiated').send(:length_validation_lookup, :text) }.should_not raise_error
420
+ end
383
421
  end
384
422
 
385
423
  describe "data access method" do
@@ -400,8 +438,8 @@ describe 'RailsAdmin::Adapters::Mongoid', :mongoid => true do
400
438
  @abstract_model.get('4f4f0824dcf2315093000000').should be_nil
401
439
  end
402
440
 
403
- it "#first returns first item" do
404
- @abstract_model.first.should == @players.first
441
+ it "#first returns a player" do
442
+ @players.should include @abstract_model.first
405
443
  end
406
444
 
407
445
  it "#count returns count of items" do
@@ -427,7 +465,7 @@ describe 'RailsAdmin::Adapters::Mongoid', :mongoid => true do
427
465
  end
428
466
 
429
467
  it "supports limiting" do
430
- @abstract_model.all(:limit => 2).to_a.count.should == 2
468
+ @abstract_model.all(:limit => 2).to_a.should have(2).items
431
469
  end
432
470
 
433
471
  it "supports retrieval by bulk_ids" do
@@ -530,6 +568,29 @@ describe 'RailsAdmin::Adapters::Mongoid', :mongoid => true do
530
568
  @abstract_model.all(:filters => {"fans" => {"0000" => {:o=>"is", :v=>'foobar'}}}).to_a.should == @teams[1..1]
531
569
  end
532
570
  end
571
+
572
+ describe "whose type is embedded has_many" do
573
+ before do
574
+ RailsAdmin.config FieldTest do
575
+ field :embeds do
576
+ queryable true
577
+ searchable :all
578
+ end
579
+ end
580
+ @field_tests = FactoryGirl.create_list(:field_test, 3)
581
+ @field_tests[0].embeds.create :name => 'foo'
582
+ @field_tests[1].embeds.create :name => 'bar'
583
+ @abstract_model = RailsAdmin::AbstractModel.new('FieldTest')
584
+ end
585
+
586
+ it "supports querying" do
587
+ @abstract_model.all(:query => 'bar').to_a.should == @field_tests[1..1]
588
+ end
589
+
590
+ it "supports filtering" do
591
+ @abstract_model.all(:filters => {"embeds" => {"0000" => {:o=>"is", :v=>'bar'}}}).to_a.should == @field_tests[1..1]
592
+ end
593
+ end
533
594
  end
534
595
 
535
596
  describe "#query_conditions" do
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: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2012-05-15 00:00:00.000000000 Z
15
+ date: 2012-06-06 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: bbenezech-nested_form
@@ -54,6 +54,9 @@ dependencies:
54
54
  - - ~>
55
55
  - !ruby/object:Gem::Version
56
56
  version: '2.0'
57
+ - - ! '>='
58
+ - !ruby/object:Gem::Version
59
+ version: 2.0.3
57
60
  type: :runtime
58
61
  prerelease: false
59
62
  version_requirements: !ruby/object:Gem::Requirement
@@ -62,6 +65,9 @@ dependencies:
62
65
  - - ~>
63
66
  - !ruby/object:Gem::Version
64
67
  version: '2.0'
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: 2.0.3
65
71
  - !ruby/object:Gem::Dependency
66
72
  name: jquery-ui-rails
67
73
  requirement: !ruby/object:Gem::Requirement