trestle 0.8.3 → 0.8.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/trestle/_confirmation.js +23 -0
- data/app/assets/javascripts/trestle/_datepicker.js +22 -0
- data/app/assets/javascripts/trestle/_errors.js +11 -0
- data/app/assets/javascripts/trestle/_form.js +6 -0
- data/app/assets/javascripts/trestle/_gallery.js +27 -0
- data/app/assets/javascripts/trestle/_select.js +11 -0
- data/app/assets/javascripts/trestle/_sidebar.js +52 -0
- data/app/assets/javascripts/trestle/_table.js +21 -0
- data/app/assets/javascripts/trestle/_tabs.js +13 -0
- data/app/assets/javascripts/trestle/_tooltips.js +3 -0
- data/app/assets/javascripts/trestle/admin.js +23 -0
- data/app/assets/javascripts/trestle/custom.js +4 -0
- data/app/assets/stylesheets/trestle/components/_table.scss +6 -0
- data/app/helpers/trestle/form_helper.rb +1 -1
- data/app/helpers/trestle/format_helper.rb +48 -0
- data/app/helpers/trestle/url_helper.rb +2 -8
- data/app/views/layouts/trestle/admin.html.erb +3 -3
- data/app/views/trestle/admin/index.html.erb +1 -1
- data/app/views/trestle/dashboard/index.html.erb +2 -2
- data/app/views/trestle/resource/_form.html.erb +1 -1
- data/app/views/trestle/resource/edit.html.erb +2 -2
- data/app/views/trestle/resource/index.html.erb +1 -1
- data/app/views/trestle/resource/new.html.erb +1 -1
- data/app/views/trestle/resource/show.html.erb +2 -2
- data/app/views/trestle/shared/_sidebar.html.erb +4 -2
- data/bower.json +1 -1
- data/config/locales/en.yml +16 -2
- data/lib/generators/trestle/install/install_generator.rb +3 -3
- data/lib/generators/trestle/install/templates/custom.js +7 -0
- data/lib/generators/trestle/install/templates/trestle.rb.erb +3 -2
- data/lib/trestle/adapters.rb +7 -64
- data/lib/trestle/adapters/active_record_adapter.rb +46 -20
- data/lib/trestle/adapters/adapter.rb +176 -0
- data/lib/trestle/adapters/sequel_adapter.rb +85 -0
- data/lib/trestle/admin.rb +1 -1
- data/lib/trestle/attribute.rb +14 -37
- data/lib/trestle/breadcrumb.rb +6 -0
- data/lib/trestle/configuration.rb +1 -1
- data/lib/trestle/form/automatic.rb +29 -21
- data/lib/trestle/form/builder.rb +4 -0
- data/lib/trestle/form/field.rb +2 -2
- data/lib/trestle/form/fields/check_box.rb +1 -1
- data/lib/trestle/form/fields/collection_select.rb +1 -1
- data/lib/trestle/form/fields/date_select.rb +1 -1
- data/lib/trestle/form/fields/datetime_select.rb +1 -1
- data/lib/trestle/form/fields/grouped_collection_select.rb +1 -1
- data/lib/trestle/form/fields/select.rb +2 -2
- data/lib/trestle/form/fields/tag_select.rb +1 -2
- data/lib/trestle/form/fields/time_select.rb +1 -1
- data/lib/trestle/form/fields/time_zone_select.rb +1 -1
- data/lib/trestle/resource.rb +11 -7
- data/lib/trestle/resource/builder.rb +2 -1
- data/lib/trestle/resource/controller.rb +61 -17
- data/lib/trestle/scope.rb +1 -1
- data/lib/trestle/table/automatic.rb +5 -11
- data/lib/trestle/table/builder.rb +1 -0
- data/lib/trestle/table/column.rb +24 -43
- data/lib/trestle/version.rb +1 -1
- data/trestle.gemspec +3 -4
- data/vendor/assets/bower_components/trestle/flatpickr/dist/flatpickr.css +51 -26
- data/vendor/assets/bower_components/trestle/flatpickr/dist/flatpickr.js +349 -299
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/ar.js +5 -5
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/bg.js +5 -5
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/bn.js +5 -5
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/cat.js +7 -7
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/cs.js +7 -7
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/cy.js +7 -7
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/da.js +6 -6
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/de.js +10 -10
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/eo.js +11 -11
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/es.js +7 -7
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/et.js +11 -11
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/fa.js +6 -6
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/fi.js +7 -7
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/fr.js +11 -11
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/gr.js +13 -13
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/he.js +5 -5
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/hi.js +5 -5
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/hr.js +6 -6
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/hu.js +10 -10
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/id.js +7 -7
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/index.js +97 -0
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/it.js +10 -10
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/ja.js +5 -5
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/ko.js +6 -6
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/lt.js +10 -10
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/lv.js +6 -6
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/mk.js +8 -8
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/ms.js +7 -7
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/my.js +7 -7
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/nl.js +11 -11
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/no.js +11 -11
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/pa.js +5 -5
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/pl.js +6 -6
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/pt.js +6 -8
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/ro.js +7 -9
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/ru.js +6 -8
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/si.js +5 -7
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/sk.js +8 -8
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/sl.js +8 -10
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/sq.js +5 -7
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/sr.js +9 -10
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/sv.js +8 -10
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/th.js +10 -11
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/tr.js +6 -8
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/uk.js +6 -7
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/vn.js +6 -8
- data/vendor/assets/bower_components/trestle/flatpickr/dist/l10n/zh.js +9 -11
- metadata +24 -34
- data/app/assets/javascripts/trestle/_confirmation.js.coffee +0 -18
- data/app/assets/javascripts/trestle/_datepicker.js.coffee +0 -18
- data/app/assets/javascripts/trestle/_errors.js.coffee +0 -8
- data/app/assets/javascripts/trestle/_form.js.coffee +0 -4
- data/app/assets/javascripts/trestle/_gallery.js.coffee +0 -21
- data/app/assets/javascripts/trestle/_select.js.coffee +0 -7
- data/app/assets/javascripts/trestle/_sidebar.js.coffee +0 -45
- data/app/assets/javascripts/trestle/_table.js.coffee +0 -16
- data/app/assets/javascripts/trestle/_tabs.js.coffee +0 -9
- data/app/assets/javascripts/trestle/_tooltips.js.coffee +0 -2
- data/app/assets/javascripts/trestle/admin.js.coffee +0 -22
- data/app/assets/javascripts/trestle/custom.js.coffee +0 -4
- data/lib/generators/trestle/install/templates/custom.js.coffee +0 -7
data/bower.json
CHANGED
data/config/locales/en.yml
CHANGED
@@ -28,6 +28,12 @@ en:
|
|
28
28
|
more_pages:
|
29
29
|
display_entries: "Displaying %{entry_name} <strong>%{first} - %{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
|
-
|
48
|
-
|
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",
|
14
|
-
template "_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
|
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
|
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.
|
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:
|
data/lib/trestle/adapters.rb
CHANGED
@@ -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
|
9
|
-
|
10
|
-
|
11
|
-
|
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
|
-
|
5
|
+
model.all
|
6
6
|
end
|
7
7
|
|
8
8
|
def find_instance(params)
|
9
|
-
|
9
|
+
model.find(params[:id])
|
10
10
|
end
|
11
11
|
|
12
|
-
def build_instance(params={})
|
13
|
-
|
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(
|
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
|
45
|
-
|
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
|
50
|
-
|
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
|
-
|
55
|
-
if column.name.end_with?("_id") && (
|
56
|
-
Attribute::Association.new(
|
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(
|
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
|