trestle 0.8.3 → 0.8.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.
Files changed (123) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/trestle/_confirmation.js +23 -0
  3. data/app/assets/javascripts/trestle/_datepicker.js +22 -0
  4. data/app/assets/javascripts/trestle/_errors.js +11 -0
  5. data/app/assets/javascripts/trestle/_form.js +6 -0
  6. data/app/assets/javascripts/trestle/_gallery.js +27 -0
  7. data/app/assets/javascripts/trestle/_select.js +11 -0
  8. data/app/assets/javascripts/trestle/_sidebar.js +52 -0
  9. data/app/assets/javascripts/trestle/_table.js +21 -0
  10. data/app/assets/javascripts/trestle/_tabs.js +13 -0
  11. data/app/assets/javascripts/trestle/_tooltips.js +3 -0
  12. data/app/assets/javascripts/trestle/admin.js +23 -0
  13. data/app/assets/javascripts/trestle/custom.js +4 -0
  14. data/app/assets/stylesheets/trestle/components/_table.scss +6 -0
  15. data/app/helpers/trestle/form_helper.rb +1 -1
  16. data/app/helpers/trestle/format_helper.rb +48 -0
  17. data/app/helpers/trestle/url_helper.rb +2 -8
  18. data/app/views/layouts/trestle/admin.html.erb +3 -3
  19. data/app/views/trestle/admin/index.html.erb +1 -1
  20. data/app/views/trestle/dashboard/index.html.erb +2 -2
  21. data/app/views/trestle/resource/_form.html.erb +1 -1
  22. data/app/views/trestle/resource/edit.html.erb +2 -2
  23. data/app/views/trestle/resource/index.html.erb +1 -1
  24. data/app/views/trestle/resource/new.html.erb +1 -1
  25. data/app/views/trestle/resource/show.html.erb +2 -2
  26. data/app/views/trestle/shared/_sidebar.html.erb +4 -2
  27. data/bower.json +1 -1
  28. data/config/locales/en.yml +16 -2
  29. data/lib/generators/trestle/install/install_generator.rb +3 -3
  30. data/lib/generators/trestle/install/templates/custom.js +7 -0
  31. data/lib/generators/trestle/install/templates/trestle.rb.erb +3 -2
  32. data/lib/trestle/adapters.rb +7 -64
  33. data/lib/trestle/adapters/active_record_adapter.rb +46 -20
  34. data/lib/trestle/adapters/adapter.rb +176 -0
  35. data/lib/trestle/adapters/sequel_adapter.rb +85 -0
  36. data/lib/trestle/admin.rb +1 -1
  37. data/lib/trestle/attribute.rb +14 -37
  38. data/lib/trestle/breadcrumb.rb +6 -0
  39. data/lib/trestle/configuration.rb +1 -1
  40. data/lib/trestle/form/automatic.rb +29 -21
  41. data/lib/trestle/form/builder.rb +4 -0
  42. data/lib/trestle/form/field.rb +2 -2
  43. data/lib/trestle/form/fields/check_box.rb +1 -1
  44. data/lib/trestle/form/fields/collection_select.rb +1 -1
  45. data/lib/trestle/form/fields/date_select.rb +1 -1
  46. data/lib/trestle/form/fields/datetime_select.rb +1 -1
  47. data/lib/trestle/form/fields/grouped_collection_select.rb +1 -1
  48. data/lib/trestle/form/fields/select.rb +2 -2
  49. data/lib/trestle/form/fields/tag_select.rb +1 -2
  50. data/lib/trestle/form/fields/time_select.rb +1 -1
  51. data/lib/trestle/form/fields/time_zone_select.rb +1 -1
  52. data/lib/trestle/resource.rb +11 -7
  53. data/lib/trestle/resource/builder.rb +2 -1
  54. data/lib/trestle/resource/controller.rb +61 -17
  55. data/lib/trestle/scope.rb +1 -1
  56. data/lib/trestle/table/automatic.rb +5 -11
  57. data/lib/trestle/table/builder.rb +1 -0
  58. data/lib/trestle/table/column.rb +24 -43
  59. data/lib/trestle/version.rb +1 -1
  60. data/trestle.gemspec +3 -4
  61. data/vendor/assets/bower_components/trestle/flatpickr/dist/flatpickr.css +51 -26
  62. data/vendor/assets/bower_components/trestle/flatpickr/dist/flatpickr.js +349 -299
  63. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/ar.js +5 -5
  64. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/bg.js +5 -5
  65. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/bn.js +5 -5
  66. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/cat.js +7 -7
  67. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/cs.js +7 -7
  68. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/cy.js +7 -7
  69. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/da.js +6 -6
  70. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/de.js +10 -10
  71. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/eo.js +11 -11
  72. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/es.js +7 -7
  73. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/et.js +11 -11
  74. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/fa.js +6 -6
  75. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/fi.js +7 -7
  76. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/fr.js +11 -11
  77. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/gr.js +13 -13
  78. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/he.js +5 -5
  79. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/hi.js +5 -5
  80. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/hr.js +6 -6
  81. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/hu.js +10 -10
  82. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/id.js +7 -7
  83. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/index.js +97 -0
  84. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/it.js +10 -10
  85. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/ja.js +5 -5
  86. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/ko.js +6 -6
  87. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/lt.js +10 -10
  88. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/lv.js +6 -6
  89. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/mk.js +8 -8
  90. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/ms.js +7 -7
  91. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/my.js +7 -7
  92. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/nl.js +11 -11
  93. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/no.js +11 -11
  94. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/pa.js +5 -5
  95. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/pl.js +6 -6
  96. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/pt.js +6 -8
  97. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/ro.js +7 -9
  98. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/ru.js +6 -8
  99. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/si.js +5 -7
  100. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/sk.js +8 -8
  101. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/sl.js +8 -10
  102. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/sq.js +5 -7
  103. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/sr.js +9 -10
  104. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/sv.js +8 -10
  105. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/th.js +10 -11
  106. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/tr.js +6 -8
  107. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/uk.js +6 -7
  108. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/vn.js +6 -8
  109. data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/zh.js +9 -11
  110. metadata +24 -34
  111. data/app/assets/javascripts/trestle/_confirmation.js.coffee +0 -18
  112. data/app/assets/javascripts/trestle/_datepicker.js.coffee +0 -18
  113. data/app/assets/javascripts/trestle/_errors.js.coffee +0 -8
  114. data/app/assets/javascripts/trestle/_form.js.coffee +0 -4
  115. data/app/assets/javascripts/trestle/_gallery.js.coffee +0 -21
  116. data/app/assets/javascripts/trestle/_select.js.coffee +0 -7
  117. data/app/assets/javascripts/trestle/_sidebar.js.coffee +0 -45
  118. data/app/assets/javascripts/trestle/_table.js.coffee +0 -16
  119. data/app/assets/javascripts/trestle/_tabs.js.coffee +0 -9
  120. data/app/assets/javascripts/trestle/_tooltips.js.coffee +0 -2
  121. data/app/assets/javascripts/trestle/admin.js.coffee +0 -22
  122. data/app/assets/javascripts/trestle/custom.js.coffee +0 -4
  123. data/lib/generators/trestle/install/templates/custom.js.coffee +0 -7
data/bower.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "ionicons": "~2.0.1",
9
9
  "magnific-popup": "~1.1.0",
10
10
  "bootstrap-confirmation2": "~2.4.0",
11
- "flatpickr": "~2.6.1",
11
+ "flatpickr": "~3.0.7",
12
12
  "select2": "~4.0.3",
13
13
  "select2-bootstrap-theme": "~0.1.0"
14
14
  }
@@ -28,6 +28,12 @@ en:
28
28
  more_pages:
29
29
  display_entries: "Displaying %{entry_name} <strong>%{first}&nbsp;-&nbsp;%{last}</strong> of <b>%{total}</b>"
30
30
 
31
+ onboarding:
32
+ welcome: Welcome to Trestle
33
+ no_admins: To begin, please create an admin within <code>app/admin</code>.
34
+ no_template: To customize this template, please create <code>%{path}</code>.
35
+ no_form: Please define a form block or create a <code>_form.html</code> partial.
36
+
31
37
  admin:
32
38
  titles:
33
39
  index: Listing %{pluralized_model_name}
@@ -44,10 +50,18 @@ en:
44
50
  headers:
45
51
  id: ID
46
52
 
47
- column:
48
- blank: None
53
+ form:
54
+ select:
55
+ prompt: "- Select %{attribute_name} -"
49
56
 
50
57
  confirmation:
51
58
  title: Are you sure?
52
59
  delete: Delete
53
60
  cancel: Cancel
61
+
62
+ ui:
63
+ toggle_navigation: Toggle navigation
64
+ toggle_sidebar: Toggle sidebar
65
+
66
+ format:
67
+ blank: None
@@ -10,10 +10,10 @@ module Trestle
10
10
  end
11
11
 
12
12
  def create_assets
13
- template "_variables.scss", "app/assets/stylesheets/trestle/_variables.scss"
14
- template "_custom.scss", "app/assets/stylesheets/trestle/_custom.scss"
13
+ template "_variables.scss", "app/assets/stylesheets/trestle/_variables.scss"
14
+ template "_custom.scss", "app/assets/stylesheets/trestle/_custom.scss"
15
15
 
16
- template "custom.js.coffee", "app/assets/javascripts/trestle/custom.js.coffee"
16
+ template "custom.js", "app/assets/javascripts/trestle/custom.js"
17
17
  end
18
18
 
19
19
  def create_directory
@@ -0,0 +1,7 @@
1
+ // This file may be used for providing additional customizations to the Trestle
2
+ // admin. It will be automatically included within all admin pages.
3
+ //
4
+ // For organizational purposes, you may wish to define your customizations
5
+ // within individual partials and `require` them here.
6
+ //
7
+ // e.g. //= require "trestle/custom/my_custom_js"
@@ -70,7 +70,7 @@ Trestle.configure do |config|
70
70
  # config.around_action do |controller, block|
71
71
  # Rails.logger.debug("Around action (before)")
72
72
  # block.call
73
- # Rails.logger.debug("Around ation (after)")
73
+ # Rails.logger.debug("Around action (after)")
74
74
  # end
75
75
 
76
76
  # Specify a custom hook to be injected into the admin.
@@ -93,7 +93,8 @@ Trestle.configure do |config|
93
93
  # See the documentation on Trestle::Adapters::Adapter for details on
94
94
  # the adapter methods that can be customized.
95
95
  #
96
- # config.default_adapter.extend MyAdapterExtensions
96
+ # config.default_adapter = Trestle::Adapters.compose(Trestle::Adapters::SequelAdapter)
97
+ # config.default_adapter.include MyAdapterExtensions
97
98
 
98
99
  # Register a form field type to be made available to the Trestle form builder.
99
100
  # Field types should conform to the following method definition:
@@ -2,73 +2,16 @@ module Trestle
2
2
  module Adapters
3
3
  extend ActiveSupport::Autoload
4
4
 
5
+ autoload :Adapter
6
+
5
7
  autoload :ActiveRecordAdapter
6
8
  autoload :DraperAdapter
9
+ autoload :SequelAdapter
7
10
 
8
- class Adapter
9
- attr_reader :admin
10
-
11
- def initialize(admin)
12
- @admin = admin
13
- end
14
-
15
- def collection(params={})
16
- raise NotImplementedError
17
- end
18
-
19
- def find_instance(params)
20
- raise NotImplementedError
21
- end
22
-
23
- def build_instance(params={})
24
- raise NotImplementedError
25
- end
26
-
27
- def update_instance(instance, params)
28
- raise NotImplementedError
29
- end
30
-
31
- def save_instance(instance)
32
- raise NotImplementedError
33
- end
34
-
35
- def delete_instance(instance)
36
- raise NotImplementedError
37
- end
38
-
39
- def decorate_collection(collection)
40
- collection
41
- end
42
-
43
- def merge_scopes(scope, other)
44
- raise NotImplementedError
45
- end
46
-
47
- def sort(collection, params)
48
- raise NotImplementedError
49
- end
50
-
51
- def paginate(collection, params)
52
- raise NotImplementedError
53
- end
54
-
55
- def count(collection)
56
- raise NotImplementedError
57
- end
58
-
59
- def permitted_params(params)
60
- params.require(admin.admin_name.singularize).permit!
61
- end
62
-
63
- def default_attributes
64
- raise NotImplementedError
65
- end
66
-
67
- # Creates a new Adapter class with the given modules mixed in
68
- def self.compose(*modules)
69
- Class.new(self) do
70
- modules.each { |mod| include(mod) }
71
- end
11
+ # Creates a new Adapter class with the given modules mixed in
12
+ def self.compose(*modules)
13
+ Class.new(Adapter) do
14
+ modules.each { |mod| include(mod) }
72
15
  end
73
16
  end
74
17
  end
@@ -2,19 +2,19 @@ module Trestle
2
2
  module Adapters
3
3
  module ActiveRecordAdapter
4
4
  def collection(params={})
5
- admin.model.all
5
+ model.all
6
6
  end
7
7
 
8
8
  def find_instance(params)
9
- admin.model.find(params[:id])
9
+ model.find(params[:id])
10
10
  end
11
11
 
12
- def build_instance(params={})
13
- admin.model.new(params)
12
+ def build_instance(attrs={}, params={})
13
+ model.new(attrs)
14
14
  end
15
15
 
16
- def update_instance(instance, params)
17
- instance.assign_attributes(params)
16
+ def update_instance(instance, attrs, params={})
17
+ instance.assign_attributes(attrs)
18
18
  end
19
19
 
20
20
  def save_instance(instance)
@@ -25,10 +25,6 @@ module Trestle
25
25
  instance.destroy
26
26
  end
27
27
 
28
- def to_param(instance)
29
- instance
30
- end
31
-
32
28
  def unscope(scope)
33
29
  scope.unscoped
34
30
  end
@@ -37,27 +33,57 @@ module Trestle
37
33
  scope.merge(other)
38
34
  end
39
35
 
36
+ def count(collection)
37
+ collection.count
38
+ end
39
+
40
40
  def sort(collection, field, order)
41
41
  collection.reorder(field => order)
42
42
  end
43
43
 
44
- def paginate(collection, params)
45
- collection = Kaminari.paginate_array(collection) unless collection.respond_to?(:page)
46
- collection.page(params[:page])
44
+ def human_attribute_name(attribute, options={})
45
+ model.human_attribute_name(attribute, options)
47
46
  end
48
47
 
49
- def count(collection)
50
- collection.count
48
+ def default_table_attributes
49
+ default_attributes.reject do |attribute|
50
+ inheritance_column?(attribute) || counter_cache_column?(attribute)
51
+ end
51
52
  end
52
53
 
54
+ def default_form_attributes
55
+ default_attributes.reject do |attribute|
56
+ primary_key?(attribute) || inheritance_column?(attribute) || counter_cache_column?(attribute)
57
+ end
58
+ end
59
+
60
+ protected
53
61
  def default_attributes
54
- admin.model.columns.map do |column|
55
- if column.name.end_with?("_id") && (reflection = admin.model.reflections[column.name.sub(/_id$/, '')])
56
- Attribute::Association.new(admin, column.name, reflection.klass)
62
+ model.columns.map do |column|
63
+ if column.name.end_with?("_id") && (name = column.name.sub(/_id$/, '')) && (reflection = model.reflections[name])
64
+ Attribute::Association.new(column.name, class: -> { reflection.klass }, name: name, polymorphic: reflection.polymorphic?, type_column: reflection.foreign_type)
65
+ elsif column.name.end_with?("_type") && (name = column.name.sub(/_type$/, '')) && (reflection = model.reflections[name])
66
+ # Ignore type columns for polymorphic associations
57
67
  else
58
- Attribute.new(admin, column.name, column.type)
68
+ Attribute.new(column.name, column.type, array_column?(column) ? { array: true } : {})
59
69
  end
60
- end
70
+ end.compact
71
+ end
72
+
73
+ def primary_key?(attribute)
74
+ attribute.name.to_s == model.primary_key
75
+ end
76
+
77
+ def inheritance_column?(attribute)
78
+ attribute.name.to_s == model.inheritance_column
79
+ end
80
+
81
+ def counter_cache_column?(attribute)
82
+ attribute.name.to_s.end_with?("_count")
83
+ end
84
+
85
+ def array_column?(column)
86
+ column.respond_to?(:array?) && column.array?
61
87
  end
62
88
  end
63
89
  end
@@ -0,0 +1,176 @@
1
+ module Trestle
2
+ module Adapters
3
+ class Adapter
4
+ attr_reader :admin
5
+ delegate :model, to: :admin
6
+
7
+ def initialize(admin)
8
+ @admin = admin
9
+ end
10
+
11
+ # Loads the initial collection for use by the index action.
12
+ #
13
+ # params - Unfiltered params hash from the controller
14
+ #
15
+ # Returns a scope object that can be chained with other methods (e.g. sort, paginate, count, etc).
16
+ def collection(params={})
17
+ raise NotImplementedError
18
+ end
19
+
20
+ # Finds (and returns) an individual instance for use by the show, edit, update, destroy actions.
21
+ #
22
+ # params - Unfiltered params hash from the controller
23
+ def find_instance(params)
24
+ raise NotImplementedError
25
+ end
26
+
27
+ # Builds (and returns) a new instance for new/create actions.
28
+ #
29
+ # attrs - Permitted attributes to set on the new instance
30
+ # params - Unfiltered params hash from the controller
31
+ def build_instance(attrs={}, params={})
32
+ raise NotImplementedError
33
+ end
34
+
35
+ # Updates (but does not save) a given resource's attributes.
36
+ #
37
+ # instance - The instance to update
38
+ # attrs - Permitted attributes to update on the instance
39
+ # params - Unfiltered params hash from the controller
40
+ #
41
+ # The return value is ignored.
42
+ def update_instance(instance, attrs, params={})
43
+ raise NotImplementedError
44
+ end
45
+
46
+ # Saves an instance (used by the create and update actions).
47
+ #
48
+ # instance - The instance to save
49
+ #
50
+ # Returns a boolean indicating the success/fail status of the save.
51
+ def save_instance(instance)
52
+ raise NotImplementedError
53
+ end
54
+
55
+ # Deletes an instance (used by the destroy action).
56
+ #
57
+ # instance - The instance to delete
58
+ #
59
+ # Returns a boolean indicating the success/fail status of the deletion.
60
+ def delete_instance(instance)
61
+ raise NotImplementedError
62
+ end
63
+
64
+ # Decorates a collection for rendering by the index view.
65
+ # Decorating is the final step in preparing the collection for the view.
66
+ #
67
+ # collection - The collection to decorate
68
+ #
69
+ # Returns an enumerable collection of instances.
70
+ def decorate_collection(collection)
71
+ collection
72
+ end
73
+
74
+ # Converts an instance to a URL parameter. The result of this method is passed to the #find_instance
75
+ # adapter method as params[:id]. It is recommended to simply use the instance's #id, as other potential options
76
+ # such as a permalink/slug could potentially be changed during editing.
77
+ #
78
+ # instance - The instance to convert
79
+ #
80
+ # Returns the URL representation of the instance.
81
+ def to_param(instance)
82
+ instance.id
83
+ end
84
+
85
+ # Unscopes a collection so that it can be merged with other scopes without duplication or interference.
86
+ #
87
+ # scope - The scope to unscope
88
+ #
89
+ # Returns a scope object.
90
+ def unscope(scope)
91
+ scope
92
+ end
93
+
94
+ # Merges scopes together for Trestle scope application and counting.
95
+ #
96
+ # scope - The first scope
97
+ # other - The second scope
98
+ #
99
+ # Returns a scope object representing the combination of the two given scopes.
100
+ def merge_scopes(scope, other)
101
+ raise NotImplementedError
102
+ end
103
+
104
+ # Counts the number of objects in a collection for use by scope links.
105
+ #
106
+ # collection - The collection to count
107
+ #
108
+ # Returns the total number (integer) of objects in the collection.
109
+ def count(collection)
110
+ raise NotImplementedError
111
+ end
112
+
113
+ # Sorts the collection by the given field and order.
114
+ # This method is called when an explicit sort column for the given field is not defined.
115
+ #
116
+ # collection - The collection to sort
117
+ # field - The field to sort by
118
+ # order - Symbol (:asc or :desc) representing the sort order (ascending or descending)
119
+ #
120
+ # Returns a scope object
121
+ def sort(collection, field, order)
122
+ raise NotImplementedError
123
+ end
124
+
125
+ # Paginates a collection for use by the index action.
126
+ #
127
+ # collection - The collection to paginate
128
+ # params - Unfiltered params hash from the controller:
129
+ # :page - current page number
130
+ #
131
+ # Returns a Kaminari-compatible scope corresponding to a single page.
132
+ def paginate(collection, params)
133
+ collection = Kaminari.paginate_array(collection.to_a) unless collection.respond_to?(:page)
134
+ collection.page(params[:page])
135
+ end
136
+
137
+ # Filters the submitted form parameters and returns a whitelisted attributes 'hash'
138
+ # that can be set or updated on a model instance.
139
+ #
140
+ # IMPORTANT: By default, all params are permitted, which assumes a trusted administrator. If this is not the
141
+ # case, a `params` block should be individually declared for each admin with the set of permitted parameters.
142
+ #
143
+ # params - Unfiltered params hash from the controller
144
+ #
145
+ # Returns the permitted set of parameters as a ActionController::Parameters object.
146
+ def permitted_params(params)
147
+ params.require(admin.admin_name.singularize).permit!
148
+ end
149
+
150
+ # Produces a human-readable name for a given attribute, applying I18n where appropriate.
151
+ # See ActiveModel::Translation for an implementation of this method.
152
+ #
153
+ # attribute - Attribute name (Symbol)
154
+ # options - Hash of options [not currently used]
155
+ #
156
+ # Returns the human-readable name of the given attribute as a String.
157
+ def human_attribute_name(attribute, options={})
158
+ attribute.to_s.titleize
159
+ end
160
+
161
+ # Generates a list of attributes that should be rendered by the index (table) view.
162
+ #
163
+ # Returns an Array of Trestle::Attribute and/or Trestle::Attribute::Association objects.
164
+ def default_table_attributes
165
+ raise NotImplementedError
166
+ end
167
+
168
+ # Generates a list of attributes that should be rendered by the new/show/edit (form) views.
169
+ #
170
+ # Returns an Array of Trestle::Attribute and/or Trestle::Attribute::Association objects.
171
+ def default_form_attributes
172
+ raise NotImplementedError
173
+ end
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,85 @@
1
+ begin
2
+ require "sequel"
3
+ rescue LoadError
4
+ $stderr.puts "You don't have sequel installed in your application. Please add it to your Gemfile and run bundle install"
5
+ raise
6
+ end
7
+
8
+ Sequel::Model.plugin :active_model
9
+
10
+ module Trestle
11
+ module Adapters
12
+ module SequelAdapter
13
+ def collection(params={})
14
+ model.dataset
15
+ end
16
+
17
+ def find_instance(params)
18
+ model[params[:id]]
19
+ end
20
+
21
+ def build_instance(attrs={}, params={})
22
+ model.new(attrs)
23
+ end
24
+
25
+ def update_instance(instance, attrs, params={})
26
+ instance.set(attrs)
27
+ end
28
+
29
+ def save_instance(instance)
30
+ instance.save
31
+ end
32
+
33
+ def delete_instance(instance)
34
+ instance.destroy
35
+ end
36
+
37
+ def unscope(scope)
38
+ scope.unfiltered
39
+ end
40
+
41
+ def merge_scopes(scope, other)
42
+ scope.intersect(other)
43
+ end
44
+
45
+ def count(collection)
46
+ collection.count
47
+ end
48
+
49
+ def sort(collection, field, order)
50
+ collection.order(Sequel.send(order, field))
51
+ end
52
+
53
+ def default_table_attributes
54
+ default_attributes.reject do |attribute|
55
+ inheritance_column?(attribute)
56
+ end
57
+ end
58
+
59
+ def default_form_attributes
60
+ default_attributes.reject do |attribute|
61
+ primary_key?(attribute) || inheritance_column?(attribute)
62
+ end
63
+ end
64
+
65
+ protected
66
+ def default_attributes
67
+ model.db_schema.map do |column_name, column_attrs|
68
+ if column_name.to_s.end_with?("_id") && (name = column_name.to_s.sub(/_id$/, '')) && (reflection = model.association_reflection(name.to_sym))
69
+ Attribute::Association.new(column_name, class: -> { reflection.associated_class }, name: name)
70
+ else
71
+ Attribute.new(column_name, column_attrs[:type])
72
+ end
73
+ end
74
+ end
75
+
76
+ def primary_key?(attribute)
77
+ attribute.name.to_s == model.primary_key.to_s
78
+ end
79
+
80
+ def inheritance_column?(attribute)
81
+ model.respond_to?(:sti_key) && attribute.name.to_s == model.sti_key.to_s
82
+ end
83
+ end
84
+ end
85
+ end