administrate 0.12.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/administrate/components/date_time_picker.js +6 -2
  3. data/app/assets/javascripts/administrate/components/table.js +1 -1
  4. data/app/assets/stylesheets/administrate/components/_attributes.scss +1 -1
  5. data/app/assets/stylesheets/administrate/components/_buttons.scss +8 -0
  6. data/app/assets/stylesheets/administrate/components/_cells.scss +2 -0
  7. data/app/assets/stylesheets/administrate/components/_field-unit.scss +13 -4
  8. data/app/assets/stylesheets/administrate/components/_navigation.scss +2 -3
  9. data/app/helpers/administrate/application_helper.rb +19 -0
  10. data/app/views/administrate/application/_form.html.erb +1 -1
  11. data/app/views/administrate/application/_navigation.html.erb +3 -1
  12. data/app/views/fields/date/_form.html.erb +24 -0
  13. data/app/views/fields/date/_index.html.erb +21 -0
  14. data/app/views/fields/date/_show.html.erb +21 -0
  15. data/app/views/fields/string/_show.html.erb +2 -2
  16. data/app/views/fields/text/_show.html.erb +2 -3
  17. data/docs/adding_custom_field_types.md +3 -1
  18. data/docs/authentication.md +3 -1
  19. data/docs/authorization.md +5 -3
  20. data/docs/contributing.md +1 -0
  21. data/docs/customizing_attribute_partials.md +4 -1
  22. data/docs/customizing_controller_actions.md +16 -1
  23. data/docs/customizing_dashboards.md +9 -14
  24. data/docs/customizing_page_views.md +3 -1
  25. data/docs/getting_started.md +8 -6
  26. data/docs/rails_api.md +5 -3
  27. data/lib/administrate/base_dashboard.rb +1 -0
  28. data/lib/administrate/field/base.rb +9 -13
  29. data/lib/administrate/field/date.rb +20 -0
  30. data/lib/administrate/field/has_one.rb +7 -7
  31. data/lib/administrate/field/polymorphic.rb +4 -4
  32. data/lib/administrate/order.rb +15 -7
  33. data/lib/administrate/page/base.rb +0 -2
  34. data/lib/administrate/version.rb +1 -1
  35. data/lib/administrate/view_generator.rb +2 -2
  36. data/lib/generators/administrate/dashboard/dashboard_generator.rb +1 -1
  37. data/lib/generators/administrate/dashboard/templates/controller.rb.erb +20 -8
  38. data/lib/generators/administrate/dashboard/templates/dashboard.rb.erb +1 -1
  39. data/lib/generators/administrate/install/templates/application_controller.rb.erb +3 -3
  40. data/lib/generators/administrate/routes/routes_generator.rb +12 -12
  41. metadata +7 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 901108f5715bed268b4395d6edadf3738b127425910dc365390847710f19c98f
4
- data.tar.gz: 6b61113c5c116250f2e46eaa5dbf77972473b16a6aae8042a6bcaef74f45308e
3
+ metadata.gz: a347d47197b8258a2233e4bed126e17faf34cedf8b87ca21ad61283c7f5b8dcf
4
+ data.tar.gz: 2a63e64339323c68e2daae8df8c48a50c2a85aa25cfded6a14899a275e523573
5
5
  SHA512:
6
- metadata.gz: ac4790d3bca102b4a27cc73f154e7167620f4589088b1207008f0915521735cfed483fbf085d24e7844e7b092f9f1a7d198ec6113cbc4be877758886c192f097
7
- data.tar.gz: da2c64204adee3b43a566c67cf2aa42f37a0a38ea5f35b9988f704491f2b15dcd76210fb2f56f57de1576e77da71f429fe6572493e65933877b29f9eb9e5920f
6
+ metadata.gz: e8e751c67ebafc99997f82646120be75a79f021e6a78ea207b1a393e38438abd2c9fe00596a9772514d86e9b079984b6dd110eaef6541517dbf369b27acce590
7
+ data.tar.gz: ad12aac58cee58d0eb620c0b60627f07bfddaa7853e6c518b0a2cbe4d219c61d64a41b761d7a958bf8b65c4003ecca74b572245ae1db54e2616aafe4420e494c
@@ -1,10 +1,14 @@
1
1
  $(function () {
2
2
  $('[data-type="time"]').datetimepicker({
3
3
  debug: false,
4
- format: "HH:mm:ss",
4
+ format: 'HH:mm:ss',
5
5
  });
6
6
  $('[data-type="datetime"]').datetimepicker({
7
7
  debug: false,
8
- format: "YYYY-MM-DD HH:mm:ss",
8
+ format: 'YYYY-MM-DD HH:mm:ss',
9
+ });
10
+ $('[data-type="date"]').datetimepicker({
11
+ debug: false,
12
+ format: 'YYYY-MM-DD',
9
13
  });
10
14
  });
@@ -13,7 +13,7 @@ $(function() {
13
13
  var dataUrl = $(event.target).closest("tr").data("url");
14
14
  var selection = window.getSelection().toString();
15
15
  if (selection.length === 0 && dataUrl) {
16
- window.location = dataUrl;
16
+ window.location = window.location.protocol + '//' + window.location.host + dataUrl;
17
17
  }
18
18
  }
19
19
  };
@@ -3,7 +3,7 @@
3
3
  clear: left;
4
4
  float: left;
5
5
  margin-bottom: $base-spacing;
6
- margin-top: 0;
6
+ margin-top: 0.25em;
7
7
  text-align: right;
8
8
  width: calc(15% - 1rem);
9
9
  }
@@ -41,3 +41,11 @@ input[type="submit"],
41
41
  }
42
42
  }
43
43
  }
44
+
45
+ .button--alt {
46
+ background-color: transparent;
47
+ border: $base-border;
48
+ border-color: $blue;
49
+ color: $blue;
50
+ margin-bottom: $base-spacing;
51
+ }
@@ -1,4 +1,6 @@
1
1
  .cell-label {
2
+ padding-top: 0.15em;
3
+
2
4
  &:hover {
3
5
  a {
4
6
  color: $action-color;
@@ -17,20 +17,29 @@
17
17
  .field-unit__field {
18
18
  float: left;
19
19
  margin-left: 2rem;
20
- width: 45%;
20
+ max-width: 50rem;
21
+ width: 100%;
21
22
  }
22
23
 
23
24
  .field-unit--nested {
24
25
  border: $base-border;
25
26
  margin-left: 7.5%;
27
+ max-width: 60rem;
26
28
  padding: $small-spacing;
27
- width: 50%;
29
+ width: 100%;
28
30
 
29
31
  .field-unit__field {
30
- width: calc(75% - 1rem);
32
+ width: 100%;
31
33
  }
32
34
 
33
35
  .field-unit__label {
34
- width: calc(25% - 1rem);
36
+ width: 10rem;
37
+ }
38
+ }
39
+
40
+ .field-unit--required {
41
+ label::after {
42
+ color: $red;
43
+ content: " *";
35
44
  }
36
45
  }
@@ -2,9 +2,8 @@ $_navigation-link-padding: 0.6em;
2
2
 
3
3
  .navigation {
4
4
  flex: 1 0 10rem;
5
- padding-bottom: $base-spacing;
6
- padding-right: calc(#{$base-spacing} - #{$_navigation-link-padding});
7
- padding-top: $base-spacing;
5
+ padding: $base-spacing;
6
+ padding-left: 0;
8
7
  }
9
8
 
10
9
  .navigation__link {
@@ -15,6 +15,25 @@ module Administrate
15
15
  render locals: locals, partial: field.to_partial_path
16
16
  end
17
17
 
18
+ def requireness(field)
19
+ required_field?(field) ? "required" : "optional"
20
+ end
21
+
22
+ def required_field?(field)
23
+ has_presence_validator?(field.resource.class, field.attribute)
24
+ end
25
+
26
+ def has_presence_validator?(resource_class, field_name)
27
+ validators_on(resource_class, field_name).
28
+ any? { |v| v.class == ActiveRecord::Validations::PresenceValidator }
29
+ end
30
+
31
+ def validators_on(resource_class, field_name)
32
+ return [] unless resource_class.respond_to?(:validators_on)
33
+
34
+ resource_class.validators_on(field_name)
35
+ end
36
+
18
37
  def class_from_resource(resource_name)
19
38
  resource_name.to_s.classify.constantize
20
39
  end
@@ -34,7 +34,7 @@ and renders all form fields for a resource's editable attributes.
34
34
  <% end %>
35
35
 
36
36
  <% page.attributes.each do |attribute| -%>
37
- <div class="field-unit field-unit--<%= attribute.html_class %>">
37
+ <div class="field-unit field-unit--<%= attribute.html_class %> field-unit--<%= requireness(attribute) %>">
38
38
  <%= render_field attribute, f: f %>
39
39
  </div>
40
40
  <% end -%>
@@ -8,11 +8,13 @@ as defined by the routes in the `admin/` namespace
8
8
  %>
9
9
 
10
10
  <nav class="navigation" role="navigation">
11
+ <%= link_to "Back to app", root_url, class: "button button--alt" %>
12
+
11
13
  <% Administrate::Namespace.new(namespace).resources.each do |resource| %>
12
14
  <%= link_to(
13
15
  display_resource_name(resource),
14
16
  [namespace, resource_index_route_key(resource)],
15
17
  class: "navigation__link navigation__link--#{nav_link_state(resource)}"
16
- ) %>
18
+ ) if valid_action? :index, resource %>
17
19
  <% end %>
18
20
  </nav>
@@ -0,0 +1,24 @@
1
+ <%#
2
+ # Date Form Partial
3
+
4
+ This partial renders an input element for a date attribute.
5
+ By default, the input is a text field that is augmented with [DateTimePicker].
6
+
7
+ ## Local variables:
8
+
9
+ - `f`:
10
+ A Rails form generator, used to help create the appropriate input fields.
11
+ - `field`:
12
+ An instance of [Administrate::Field::Date][1].
13
+ A wrapper around the Date value pulled from the database.
14
+
15
+ [1]: http://www.rubydoc.info/gems/administrate/Administrate/Field/Date
16
+ [DateTimePicker]: https://github.com/Eonasdan/bootstrap-datetimepicker
17
+ %>
18
+
19
+ <div class="field-unit__label">
20
+ <%= f.label field.attribute %>
21
+ </div>
22
+ <div class="field-unit__field">
23
+ <%= f.text_field field.attribute, data: { type: 'date' } %>
24
+ </div>
@@ -0,0 +1,21 @@
1
+ <%#
2
+ # Date Index Partial
3
+
4
+ This partial renders a date attribute,
5
+ to be displayed on a resource's index page.
6
+
7
+ By default, the attribute is rendered
8
+ as a localized date string.
9
+
10
+ ## Local variables:
11
+
12
+ - `field`:
13
+ An instance of [Administrate::Field::Date][1].
14
+ A wrapper around the Date value pulled from the database.
15
+
16
+ [1]: http://www.rubydoc.info/gems/administrate/Administrate/Field/Date
17
+ %>
18
+
19
+ <% if field.data %>
20
+ <%= field.date %>
21
+ <% end %>
@@ -0,0 +1,21 @@
1
+ <%#
2
+ # Date Show Partial
3
+
4
+ This partial renders a date attribute,
5
+ to be displayed on a resource's show page.
6
+
7
+ By default, the attribute is rendered
8
+ as a localized date string.
9
+
10
+ ## Local variables:
11
+
12
+ - `field`:
13
+ An instance of [Administrate::Field::Date][1].
14
+ A wrapper around the Date value pulled from the database.
15
+
16
+ [1]: http://www.rubydoc.info/gems/administrate/Administrate/Field/Date
17
+ %>
18
+
19
+ <% if field.data %>
20
+ <%= field.date %>
21
+ <% end %>
@@ -4,7 +4,7 @@
4
4
  This partial renders a string attribute,
5
5
  to be displayed on a resource's show page.
6
6
 
7
- By default, the attribute is rendered as an unformatted string.
7
+ By default, the attribute is rendered as text with whitespace preserved.
8
8
 
9
9
  ## Local variables:
10
10
 
@@ -15,4 +15,4 @@ By default, the attribute is rendered as an unformatted string.
15
15
  [1]: http://www.rubydoc.info/gems/administrate/Administrate/Field/String
16
16
  %>
17
17
 
18
- <%= field.data %>
18
+ <div class="preserve-whitespace"><%= field.data %></div>
@@ -4,8 +4,7 @@
4
4
  This partial renders a text attribute,
5
5
  to be displayed on a resource's show page.
6
6
 
7
- By default, the attribute is rendered as text with
8
- whitespace preserved.
7
+ By default, the attribute is rendered as text with whitespace preserved.
9
8
 
10
9
  ## Local variables:
11
10
 
@@ -16,4 +15,4 @@ whitespace preserved.
16
15
  [1]: http://www.rubydoc.info/gems/administrate/Administrate/Field/Text
17
16
  %>
18
17
 
19
- <span class="preserve-whitespace"><%= field.data %></span>
18
+ <div class="preserve-whitespace"><%= field.data %></div>
@@ -1,4 +1,6 @@
1
- # Adding Custom Field Types
1
+ ---
2
+ title: Adding Custom Field Types
3
+ ---
2
4
 
3
5
  If your application deals with a nonstandard data type,
4
6
  you can create an `Administrate::Field` object to help display
@@ -1,4 +1,6 @@
1
- # Authenticating admin users
1
+ ---
2
+ title: Authenticating admin users
3
+ ---
2
4
 
3
5
  Authentication is left for you to implement after you install Administrate into
4
6
  your app. It's expected that you can plugin your existing authentication
@@ -1,4 +1,6 @@
1
- # Authorization
1
+ ---
2
+ title: Authorization
3
+ ---
2
4
 
3
5
  The default configuration of Administrate is "authenticate-only" - once a
4
6
  user is authenticated, that user has access to every action of every object.
@@ -37,7 +39,7 @@ class PostPolicy < ApplicationPolicy
37
39
  def resolve
38
40
  scope.all
39
41
  end
40
-
42
+
41
43
  def resolve_admin
42
44
  scope.where(owner: user)
43
45
  end
@@ -62,7 +64,7 @@ def authorize_resource(resource)
62
64
  raise "Erg!" unless show_action?(params[:action], resource)
63
65
  end
64
66
 
65
- # Hide links to actions if the user is not allowed to do them
67
+ # Hide links to actions if the user is not allowed to do them
66
68
  def show_action?(action, resource)
67
69
  current_user.can? action, resource
68
70
  end
@@ -0,0 +1 @@
1
+ ../CONTRIBUTING.md
@@ -1,4 +1,6 @@
1
- # Customizing attribute partials
1
+ ---
2
+ title: Customizing attribute partials
3
+ ---
2
4
 
3
5
  Occasionally you might want to change how specific types of attributes appear
4
6
  across all dashboards. You can customize the following built in field types:
@@ -6,6 +8,7 @@ across all dashboards. You can customize the following built in field types:
6
8
  - `belongs_to`
7
9
  - `boolean`
8
10
  - `date_time`
11
+ - `date`
9
12
  - `email`
10
13
  - `has_many`
11
14
  - `has_one`
@@ -1,4 +1,6 @@
1
- # Customizing controller actions
1
+ ---
2
+ title: Customizing controller actions
3
+ ---
2
4
 
3
5
  When you install Administrate into your app,
4
6
  we generate empty controllers for each of your resources.
@@ -41,3 +43,16 @@ class Admin::FoosController < Admin::ApplicationController
41
43
  # end
42
44
  end
43
45
  ```
46
+
47
+ ## Customizing Actions
48
+
49
+ To enable or disable certain actions you could override `valid_action?` method in your dashboard controller like this:
50
+
51
+ ```ruby
52
+ # disable 'edit' and 'destroy' links
53
+ def valid_action?(name, resource = resource_class)
54
+ %w[edit destroy].exclude?(name.to_s) && super
55
+ end
56
+ ```
57
+
58
+ Action is one of `new`, `edit`, `show`, `destroy`.
@@ -1,4 +1,6 @@
1
- # Customizing Dashboards
1
+ ---
2
+ title: Customizing Dashboards
3
+ ---
2
4
 
3
5
  In order to customize which attributes get displayed for each resource,
4
6
  edit the dashboard file generated by the installation generator.
@@ -54,6 +56,7 @@ specify, including:
54
56
  - `Field::BelongsTo`
55
57
  - `Field::Boolean`
56
58
  - `Field::DateTime`
59
+ - `Field::Date`
57
60
  - `Field::Email`
58
61
  - `Field::HasMany`
59
62
  - `Field::HasOne`
@@ -190,6 +193,11 @@ objects to display as.
190
193
  `:timezone` - Specify which timezone `Date` and `DateTime` objects are based
191
194
  in.
192
195
 
196
+ **Field::Date**
197
+
198
+ `:format` - Specify what format, using `strftime` you would like `Date`
199
+ objects to display as.
200
+
193
201
  **Field::Select**
194
202
 
195
203
  `:collection` - Specify the array or range to select from. Defaults to `[]`.
@@ -265,19 +273,6 @@ en:
265
273
  other: Happy Customers
266
274
  ```
267
275
 
268
- ## Customizing Actions
269
-
270
- To enable or disable certain actions you could override `valid_action?` method in your dashboard controller like this:
271
-
272
- ```ruby
273
- # disable 'edit' and 'destroy' links
274
- def valid_action?(name, resource = resource_class)
275
- %w[edit destroy].exclude?(name.to_s) && super
276
- end
277
- ```
278
-
279
- Action is one of `new`, `edit`, `show`, `destroy`.
280
-
281
276
  ## Collection Filters
282
277
 
283
278
  Resources can be filtered with pre-set filters. For example if we added:
@@ -1,4 +1,6 @@
1
- # Customizing page views
1
+ ---
2
+ title: Customizing page views
3
+ ---
2
4
 
3
5
  In order to change the appearance of any page,
4
6
  you can write custom Rails views.
@@ -1,4 +1,6 @@
1
- # Getting Started
1
+ ---
2
+ title: Getting Started
3
+ ---
2
4
 
3
5
  Administrate is released as a Ruby gem, and can be installed on Rails
4
6
  applications version 4.2 or greater.
@@ -84,8 +86,8 @@ rails generate administrate:install --namespace=supervisor
84
86
 
85
87
  ## Keep Dashboards Updated as Model Attributes Change
86
88
 
87
- If you've installed Administrate and generated dashboards and _then_
88
- subsequently added attributes to your models you'll need to manually add
89
+ If you've installed Administrate and generated dashboards and _then_
90
+ subsequently added attributes to your models you'll need to manually add
89
91
  these additions (or removals) to your dashboards.
90
92
 
91
93
  Example:
@@ -98,7 +100,7 @@ Example:
98
100
  the_new_attribute: Field::String,
99
101
  # ...
100
102
  }.freeze
101
-
103
+
102
104
  SHOW_PAGE_ATTRIBUTES = [
103
105
  # ...
104
106
  :the_new_attribute,
@@ -110,7 +112,7 @@ Example:
110
112
  :the_new_attribute,
111
113
  # ...
112
114
  ].freeze
113
-
115
+
114
116
  COLLECTION_ATTRIBUTES = [
115
117
  # ...
116
118
  :the_new_attribute, # if you want it on the index, also.
@@ -118,7 +120,7 @@ Example:
118
120
  ].freeze
119
121
  ```
120
122
 
121
- It's recommended that you make this change at the same time as you add the
123
+ It's recommended that you make this change at the same time as you add the
122
124
  attribute to the model.
123
125
 
124
126
  The alternative way to handle this is to re-run `rails g administrate:install`
@@ -1,7 +1,9 @@
1
- ## Rails API
1
+ ---
2
+ title: Rails API
3
+ ---
2
4
 
3
5
  Since Rails 5.0, we've been able to have API only applications. Yet, sometimes
4
- we still want to have an admin.
6
+ we still want to have an admin.
5
7
 
6
8
  To get this working, we recommend updating this config:
7
9
 
@@ -29,7 +31,7 @@ config.middleware.use ::Rack::MethodOverride
29
31
  ```
30
32
 
31
33
  You must also ensure that all the required controller actions are available
32
- and accessible as routes since generators in API-only applications only
34
+ and accessible as routes since generators in API-only applications only
33
35
  generate some of the required actions. Here is an example:
34
36
 
35
37
  ```ruby
@@ -1,6 +1,7 @@
1
1
  require "administrate/field/belongs_to"
2
2
  require "administrate/field/boolean"
3
3
  require "administrate/field/date_time"
4
+ require "administrate/field/date"
4
5
  require "administrate/field/email"
5
6
  require "administrate/field/has_many"
6
7
  require "administrate/field/has_one"
@@ -16,6 +16,14 @@ module Administrate
16
16
  false
17
17
  end
18
18
 
19
+ def self.field_type
20
+ to_s.split("::").last.underscore
21
+ end
22
+
23
+ def self.permitted_attribute(attr, _options = nil)
24
+ attr
25
+ end
26
+
19
27
  def initialize(attribute, data, page, options = {})
20
28
  @attribute = attribute
21
29
  @data = data
@@ -24,10 +32,6 @@ module Administrate
24
32
  @options = options
25
33
  end
26
34
 
27
- def self.permitted_attribute(attr, _options = nil)
28
- attr
29
- end
30
-
31
35
  def html_class
32
36
  self.class.html_class
33
37
  end
@@ -40,15 +44,7 @@ module Administrate
40
44
  "/fields/#{self.class.field_type}/#{page}"
41
45
  end
42
46
 
43
- attr_reader :attribute, :data, :page, :resource
44
-
45
- protected
46
-
47
- attr_reader :options
48
-
49
- def self.field_type
50
- to_s.split("::").last.underscore
51
- end
47
+ attr_reader :attribute, :data, :options, :page, :resource
52
48
  end
53
49
  end
54
50
  end
@@ -0,0 +1,20 @@
1
+ require_relative "base"
2
+
3
+ module Administrate
4
+ module Field
5
+ class Date < Base
6
+ def date
7
+ I18n.localize(
8
+ data.to_date,
9
+ format: format,
10
+ )
11
+ end
12
+
13
+ private
14
+
15
+ def format
16
+ options.fetch(:format, :default)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -3,13 +3,6 @@ require_relative "associative"
3
3
  module Administrate
4
4
  module Field
5
5
  class HasOne < Associative
6
- def nested_form
7
- @nested_form ||= Administrate::Page::Form.new(
8
- resolver.dashboard_class.new,
9
- data || resolver.resource_class.new,
10
- )
11
- end
12
-
13
6
  def self.permitted_attribute(attr, options = nil)
14
7
  associated_class_name =
15
8
  if options
@@ -24,6 +17,13 @@ module Administrate
24
17
  { "#{attr}_attributes": related_dashboard_attributes }
25
18
  end
26
19
 
20
+ def nested_form
21
+ @nested_form ||= Administrate::Page::Form.new(
22
+ resolver.dashboard_class.new,
23
+ data || resolver.resource_class.new,
24
+ )
25
+ end
26
+
27
27
  private
28
28
 
29
29
  def resolver
@@ -3,6 +3,10 @@ require_relative "associative"
3
3
  module Administrate
4
4
  module Field
5
5
  class Polymorphic < BelongsTo
6
+ def self.permitted_attribute(attr, _options = nil)
7
+ { attr => %i{type value} }
8
+ end
9
+
6
10
  def associated_resource_grouped_options
7
11
  classes.map do |klass|
8
12
  [klass.to_s, candidate_resources_for(klass).map do |resource|
@@ -11,10 +15,6 @@ module Administrate
11
15
  end
12
16
  end
13
17
 
14
- def self.permitted_attribute(attr, _options = nil)
15
- { attr => %i{type value} }
16
- end
17
-
18
18
  def permitted_attribute
19
19
  { attribute => %i{type value} }
20
20
  end
@@ -2,7 +2,7 @@ module Administrate
2
2
  class Order
3
3
  def initialize(attribute = nil, direction = nil)
4
4
  @attribute = attribute
5
- @direction = direction || :asc
5
+ @direction = sanitize_direction(direction)
6
6
  end
7
7
 
8
8
  def apply(relation)
@@ -11,7 +11,7 @@ module Administrate
11
11
 
12
12
  order = "#{relation.table_name}.#{attribute} #{direction}"
13
13
 
14
- return relation.reorder(order) if
14
+ return relation.reorder(Arel.sql(order)) if
15
15
  relation.columns_hash.keys.include?(attribute.to_s)
16
16
 
17
17
  relation
@@ -34,6 +34,10 @@ module Administrate
34
34
 
35
35
  attr_reader :attribute
36
36
 
37
+ def sanitize_direction(direction)
38
+ %w[asc desc].include?(direction.to_s) ? direction.to_sym : :asc
39
+ end
40
+
37
41
  def reversed_direction_param_for(attr)
38
42
  if ordered_by?(attr)
39
43
  opposite_direction
@@ -43,7 +47,7 @@ module Administrate
43
47
  end
44
48
 
45
49
  def opposite_direction
46
- direction.to_sym == :asc ? :desc : :asc
50
+ direction == :asc ? :desc : :asc
47
51
  end
48
52
 
49
53
  def order_by_association(relation)
@@ -56,13 +60,13 @@ module Administrate
56
60
 
57
61
  def order_by_count(relation)
58
62
  relation.
59
- left_joins(attribute.to_sym).
60
- group(:id).
61
- reorder("COUNT(#{attribute}.id) #{direction}")
63
+ left_joins(attribute.to_sym).
64
+ group(:id).
65
+ reorder("COUNT(#{attribute}.id) #{direction}")
62
66
  end
63
67
 
64
68
  def order_by_id(relation)
65
- relation.reorder("#{attribute}_id #{direction}")
69
+ relation.reorder("#{foreign_key(relation)} #{direction}")
66
70
  end
67
71
 
68
72
  def has_many_attribute?(relation)
@@ -76,5 +80,9 @@ module Administrate
76
80
  def reflect_association(relation)
77
81
  relation.klass.reflect_on_association(attribute.to_s)
78
82
  end
83
+
84
+ def foreign_key(relation)
85
+ reflect_association(relation).foreign_key
86
+ end
79
87
  end
80
88
  end
@@ -33,8 +33,6 @@ module Administrate
33
33
 
34
34
  def get_attribute_value(resource, attribute_name)
35
35
  resource.public_send(attribute_name)
36
- rescue NameError
37
- nil
38
36
  end
39
37
 
40
38
  attr_reader :dashboard, :options
@@ -1,3 +1,3 @@
1
1
  module Administrate
2
- VERSION = "0.12.0".freeze
2
+ VERSION = "0.13.0".freeze
3
3
  end
@@ -5,8 +5,6 @@ module Administrate
5
5
  class ViewGenerator < Rails::Generators::Base
6
6
  include Administrate::GeneratorHelpers
7
7
 
8
- private
9
-
10
8
  def self.template_source_path
11
9
  File.expand_path(
12
10
  "../../../app/views/administrate/application",
@@ -14,6 +12,8 @@ module Administrate
14
12
  )
15
13
  end
16
14
 
15
+ private
16
+
17
17
  def copy_resource_template(template_name)
18
18
  template_file = "#{template_name}.html.erb"
19
19
 
@@ -5,7 +5,7 @@ module Administrate
5
5
  class DashboardGenerator < Rails::Generators::NamedBase
6
6
  ATTRIBUTE_TYPE_MAPPING = {
7
7
  boolean: "Field::Boolean",
8
- date: "Field::DateTime",
8
+ date: "Field::Date",
9
9
  datetime: "Field::DateTime",
10
10
  enum: "Field::String",
11
11
  float: "Field::Number",
@@ -4,9 +4,8 @@ module <%= namespace.classify %>
4
4
  # For example, you may want to send an email after a foo is updated.
5
5
  #
6
6
  # def update
7
- # foo = Foo.find(params[:id])
8
- # foo.update(params[:foo])
9
- # send_foo_updated_email
7
+ # super
8
+ # send_foo_updated_email(requested_resource)
10
9
  # end
11
10
 
12
11
  # Override this method to specify custom lookup behavior.
@@ -17,15 +16,28 @@ module <%= namespace.classify %>
17
16
  # Foo.find_by!(slug: param)
18
17
  # end
19
18
 
19
+ # The result of this lookup will be available as `requested_resource`
20
+
20
21
  # Override this if you have certain roles that require a subset
21
22
  # this will be used to set the records shown on the `index` action.
22
23
  #
23
24
  # def scoped_resource
24
- # if current_user.super_admin?
25
- # resource_class
26
- # else
27
- # resource_class.with_less_stuff
28
- # end
25
+ # if current_user.super_admin?
26
+ # resource_class
27
+ # else
28
+ # resource_class.with_less_stuff
29
+ # end
30
+ # end
31
+
32
+ # Override `resource_params` if you want to transform the submitted
33
+ # data before it's persisted. For example, the following would turn all
34
+ # empty values into nil values. It uses other APIs such as `resource_class`
35
+ # and `dashboard`:
36
+ #
37
+ # def resource_params
38
+ # params.require(resource_class.model_name.param_key).
39
+ # permit(dashboard.permitted_attributes).
40
+ # transform_values { |value| value == "" ? nil : value }
29
41
  # end
30
42
 
31
43
  # See https://administrate-prototype.herokuapp.com/customizing_controller_actions
@@ -55,7 +55,7 @@ class <%= class_name %>Dashboard < Administrate::BaseDashboard
55
55
  # in the search field:
56
56
  #
57
57
  # COLLECTION_FILTERS = {
58
- # open: ->(resources) { where(open: true) }
58
+ # open: ->(resources) { resources.where(open: true) }
59
59
  # }.freeze
60
60
  COLLECTION_FILTERS = {}.freeze
61
61
 
@@ -1,6 +1,6 @@
1
- # All Administrate controllers inherit from this `Admin::ApplicationController`,
2
- # making it the ideal place to put authentication logic or other
3
- # before_actions.
1
+ # All Administrate controllers inherit from this
2
+ # `Administrate::ApplicationController`, making it the ideal place to put
3
+ # authentication logic or other before_actions.
4
4
  #
5
5
  # If you want to add pagination or other controller-level concerns,
6
6
  # you're free to overwrite the RESTful controller actions.
@@ -20,15 +20,15 @@ module Administrate
20
20
  end
21
21
 
22
22
  def warn_about_invalid_models
23
- namespaced_models.each do |invalid_model|
24
- puts "WARNING: Unable to generate a dashboard for #{invalid_model}."
25
- puts " Administrate does not yet support namespaced models."
26
- end
27
-
28
- models_without_tables.each do |invalid_model|
29
- puts "WARNING: Unable to generate a dashboard for #{invalid_model}."
30
- puts " It is not connected to a database table."
31
- puts " Make sure your database migrations are up to date."
23
+ invalid_dashboard_models.each do |model|
24
+ puts "WARNING: Unable to generate a dashboard for #{model}."
25
+ if namespaced_models.include?(model)
26
+ puts " - Administrate does not yet support namespaced models."
27
+ end
28
+ if models_without_tables.include?(model)
29
+ puts " - It is not connected to a database table."
30
+ puts " Make sure your database migrations are up to date."
31
+ end
32
32
  end
33
33
 
34
34
  unnamed_constants.each do |invalid_model|
@@ -49,15 +49,15 @@ module Administrate
49
49
  end
50
50
 
51
51
  def valid_dashboard_models
52
- database_models - invalid_database_models
52
+ database_models - invalid_dashboard_models
53
53
  end
54
54
 
55
55
  def database_models
56
56
  ActiveRecord::Base.descendants.reject(&:abstract_class?)
57
57
  end
58
58
 
59
- def invalid_database_models
60
- models_without_tables + namespaced_models + unnamed_constants
59
+ def invalid_dashboard_models
60
+ (models_without_tables + namespaced_models + unnamed_constants).uniq
61
61
  end
62
62
 
63
63
  def models_without_tables
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: administrate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Charlton
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-09-10 00:00:00.000000000 Z
12
+ date: 2020-03-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionpack
@@ -234,6 +234,9 @@ files:
234
234
  - app/views/fields/boolean/_form.html.erb
235
235
  - app/views/fields/boolean/_index.html.erb
236
236
  - app/views/fields/boolean/_show.html.erb
237
+ - app/views/fields/date/_form.html.erb
238
+ - app/views/fields/date/_index.html.erb
239
+ - app/views/fields/date/_show.html.erb
237
240
  - app/views/fields/date_time/_form.html.erb
238
241
  - app/views/fields/date_time/_index.html.erb
239
242
  - app/views/fields/date_time/_show.html.erb
@@ -300,6 +303,7 @@ files:
300
303
  - docs/adding_custom_field_types.md
301
304
  - docs/authentication.md
302
305
  - docs/authorization.md
306
+ - docs/contributing.md
303
307
  - docs/customizing_attribute_partials.md
304
308
  - docs/customizing_controller_actions.md
305
309
  - docs/customizing_dashboards.md
@@ -313,6 +317,7 @@ files:
313
317
  - lib/administrate/field/base.rb
314
318
  - lib/administrate/field/belongs_to.rb
315
319
  - lib/administrate/field/boolean.rb
320
+ - lib/administrate/field/date.rb
316
321
  - lib/administrate/field/date_time.rb
317
322
  - lib/administrate/field/deferred.rb
318
323
  - lib/administrate/field/email.rb