upmin-admin 0.0.39 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +25 -14
- data/Rakefile +24 -15
- data/app/assets/javascripts/upmin/application.js +0 -1
- data/app/assets/stylesheets/upmin/base.css.scss +4 -0
- data/app/assets/stylesheets/upmin/instances.css.scss +11 -1
- data/app/controllers/upmin/models_controller.rb +52 -42
- data/app/views/layouts/upmin/_navbar.html.haml +3 -3
- data/app/views/layouts/upmin/application.html.haml +2 -1
- data/app/views/upmin/models/new.html.haml +3 -3
- data/app/views/upmin/models/search.html.haml +5 -4
- data/app/views/upmin/models/show.html.haml +3 -3
- data/app/views/upmin/partials/actions/_action.html.haml +6 -21
- data/app/views/upmin/partials/associations/_associations.html.haml +8 -10
- data/app/views/upmin/partials/attributes/_boolean.html.haml +8 -6
- data/app/views/upmin/partials/attributes/_datetime.html.haml +38 -36
- data/app/views/upmin/partials/attributes/_decimal.html.haml +10 -0
- data/app/views/upmin/partials/attributes/_float.html.haml +10 -6
- data/app/views/upmin/partials/attributes/_integer.html.haml +10 -6
- data/app/views/upmin/partials/attributes/_progress_bar.html.haml +1 -0
- data/app/views/upmin/partials/attributes/_string.html.haml +17 -6
- data/app/views/upmin/partials/attributes/_text.html.haml +8 -6
- data/app/views/upmin/partials/attributes/_unknown.html.haml +5 -3
- data/app/views/upmin/partials/models/_model.html.haml +18 -46
- data/app/views/upmin/partials/models/_new_model.html.haml +9 -31
- data/app/views/upmin/partials/parameters/_block_parameter.haml +0 -0
- data/app/views/upmin/partials/parameters/_opt_parameter.html.haml +14 -0
- data/app/views/upmin/partials/parameters/_req_parameter.html.haml +4 -0
- data/app/views/upmin/partials/search_boxes/_ransack_search_box.html.haml +2 -3
- data/app/views/upmin/partials/search_results/_results.html.haml +9 -2
- data/lib/upmin/action.rb +50 -0
- data/lib/upmin/active_record/association.rb +47 -0
- data/lib/upmin/active_record/model.rb +54 -0
- data/lib/upmin/active_record/query.rb +12 -0
- data/lib/upmin/admin.rb +24 -2
- data/lib/upmin/association.rb +73 -0
- data/lib/upmin/attribute.rb +87 -0
- data/lib/upmin/automatic_delegation.rb +76 -0
- data/lib/upmin/configuration.rb +103 -0
- data/lib/upmin/data_mapper/association.rb +57 -0
- data/lib/upmin/data_mapper/model.rb +62 -0
- data/lib/upmin/data_mapper/query.rb +57 -0
- data/lib/upmin/engine.rb +2 -0
- data/lib/upmin/errors.rb +43 -0
- data/lib/upmin/model.rb +267 -98
- data/lib/upmin/parameter.rb +43 -0
- data/lib/upmin/query.rb +51 -0
- data/lib/upmin/railtie.rb +11 -1
- data/lib/upmin/railties/active_record.rb +5 -50
- data/lib/upmin/railties/data_mapper.rb +18 -0
- data/lib/upmin/railties/render.rb +34 -98
- data/lib/upmin/railties/render_helpers.rb +119 -53
- data/lib/upmin/version.rb +1 -1
- data/spec/factories/factories.rb +6 -0
- data/spec/features/action_spec.rb +39 -46
- data/spec/features/edit_model_spec.rb +4 -2
- data/spec/features/navbar_spec.rb +48 -0
- data/spec/features/new_model_spec.rb +1 -0
- data/spec/features/search_spec.rb +7 -4
- data/spec/lib/configuration_spec.rb +60 -0
- data/spec/spec_helper.rb +14 -8
- metadata +25 -7
- data/app/assets/javascripts/upmin/moment.js +0 -2856
- data/app/helpers/upmin/instances_helper.rb +0 -13
- data/app/views/upmin/partials/attributes/_nilable.html.haml +0 -14
- data/app/views/upmin/partials/search_results/_result.html.haml +0 -8
- data/lib/upmin/klass.rb +0 -170
@@ -0,0 +1,103 @@
|
|
1
|
+
module Upmin
|
2
|
+
# Add Config Stuff to Upmin
|
3
|
+
class << self
|
4
|
+
attr_accessor :configuration
|
5
|
+
|
6
|
+
def configuration
|
7
|
+
@configuration ||= Configuration.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def configure
|
11
|
+
yield(configuration) if block_given?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Configuration
|
16
|
+
attr_writer :colors
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
::Rails.application.eager_load!
|
20
|
+
end
|
21
|
+
|
22
|
+
def colors=(colors)
|
23
|
+
@custom_colors = true
|
24
|
+
@colors = colors
|
25
|
+
end
|
26
|
+
|
27
|
+
def colors
|
28
|
+
if defined?(@custom_colors)
|
29
|
+
return @colors
|
30
|
+
else
|
31
|
+
return default_colors
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def models=(models)
|
36
|
+
@custom_models = true
|
37
|
+
@models = models
|
38
|
+
end
|
39
|
+
|
40
|
+
def models
|
41
|
+
if defined?(@custom_models)
|
42
|
+
return @models
|
43
|
+
else
|
44
|
+
return default_models
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def default_models
|
51
|
+
def_models = []
|
52
|
+
orm_found = false
|
53
|
+
|
54
|
+
if defined?(Rails) && Rails.application
|
55
|
+
::Rails.application.eager_load!
|
56
|
+
else
|
57
|
+
raise "We kinda need rails for a rails engine :("
|
58
|
+
end
|
59
|
+
|
60
|
+
if defined?(ActiveRecord)
|
61
|
+
orm_found = true
|
62
|
+
::Rails.application.eager_load!
|
63
|
+
def_models += ::ActiveRecord::Base.descendants
|
64
|
+
.map(&:to_s)
|
65
|
+
.select{ |m| m != "ActiveRecord::SchemaMigration" }
|
66
|
+
.sort
|
67
|
+
.map(&:underscore)
|
68
|
+
.map(&:to_sym)
|
69
|
+
end
|
70
|
+
|
71
|
+
if defined?(DataMapper)
|
72
|
+
orm_found = true
|
73
|
+
::Rails.application.eager_load!
|
74
|
+
def_models += ::DataMapper::Model.descendants.entries
|
75
|
+
.map(&:to_s)
|
76
|
+
.sort
|
77
|
+
.map(&:underscore)
|
78
|
+
.map(&:to_sym)
|
79
|
+
end
|
80
|
+
|
81
|
+
unless orm_found
|
82
|
+
raise UnsupportedObjectMapper.new
|
83
|
+
end
|
84
|
+
|
85
|
+
return def_models
|
86
|
+
end
|
87
|
+
|
88
|
+
def default_colors
|
89
|
+
return [
|
90
|
+
:light_blue,
|
91
|
+
:blue_green,
|
92
|
+
:red,
|
93
|
+
:yellow,
|
94
|
+
:orange,
|
95
|
+
:purple,
|
96
|
+
:dark_blue,
|
97
|
+
:dark_red,
|
98
|
+
:green
|
99
|
+
]
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Upmin::DataMapper
|
2
|
+
module Association
|
3
|
+
|
4
|
+
def type
|
5
|
+
return @type if defined?(@type)
|
6
|
+
|
7
|
+
if relationship
|
8
|
+
# NOTE(jon): I believe many to one is the only type where child_model_name is incorrect, but I could be wrong.
|
9
|
+
if relationship.is_a?(DataMapper::Associations::ManyToOne::Relationship)
|
10
|
+
@type = relationship.parent_model_name
|
11
|
+
else
|
12
|
+
@type = relationship.child_model_name
|
13
|
+
end
|
14
|
+
|
15
|
+
@type = @type.underscore
|
16
|
+
|
17
|
+
if collection?
|
18
|
+
@type = @type.pluralize.to_sym
|
19
|
+
else
|
20
|
+
@type = @type.to_sym
|
21
|
+
end
|
22
|
+
else
|
23
|
+
@type = :unknown
|
24
|
+
end
|
25
|
+
|
26
|
+
if @type == :unknown
|
27
|
+
@type = infer_type_from_value
|
28
|
+
end
|
29
|
+
|
30
|
+
return @type
|
31
|
+
end
|
32
|
+
|
33
|
+
def collection?
|
34
|
+
if relationship
|
35
|
+
return relationship.max > 1
|
36
|
+
elsif value
|
37
|
+
return value.responts_to?(:each)
|
38
|
+
else
|
39
|
+
return false
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def relationship
|
47
|
+
return @relationship if defined?(@relationship)
|
48
|
+
|
49
|
+
@relationship = model.model_class.relationships.select do |r|
|
50
|
+
r.name == name
|
51
|
+
end.first
|
52
|
+
|
53
|
+
return @relationship
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Upmin::DataMapper
|
2
|
+
module Model
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def new_record?
|
6
|
+
return model.new?
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_key
|
10
|
+
return [model.id]
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
# NOTE - ANY method added here must be added to the bottom of
|
16
|
+
# Upmin::Model. This ensures that an instance of the class was
|
17
|
+
# created, which in turn ensures that the correct module was
|
18
|
+
# included in the class.
|
19
|
+
|
20
|
+
def find(*args)
|
21
|
+
return model_class.get(*args)
|
22
|
+
end
|
23
|
+
|
24
|
+
def default_attributes
|
25
|
+
return model_class.properties.map(&:name)
|
26
|
+
end
|
27
|
+
|
28
|
+
def attribute_type(attribute)
|
29
|
+
property = model_class.properties.select{ |p| p.name == attribute }.first
|
30
|
+
type = property.class.to_s.demodulize.underscore.to_sym
|
31
|
+
|
32
|
+
case type
|
33
|
+
when :serial
|
34
|
+
return :integer
|
35
|
+
when :date_time
|
36
|
+
return :datetime
|
37
|
+
else
|
38
|
+
return type
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def associations
|
43
|
+
return @associations if defined?(@associations)
|
44
|
+
|
45
|
+
all = []
|
46
|
+
ignored = []
|
47
|
+
model_class.relationships.each do |relationship|
|
48
|
+
all << relationship.name
|
49
|
+
|
50
|
+
# This may need dropped later if we find that it is more useful to show these.
|
51
|
+
if relationship.is_a?(DataMapper::Associations::ManyToMany::Relationship)
|
52
|
+
ignored << relationship.options[:through]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
return @associations = (all - ignored).uniq
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Upmin::DataMapper
|
2
|
+
module Query
|
3
|
+
|
4
|
+
def results
|
5
|
+
return klass.model_class.all(prepared_search)
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def prepared_search
|
11
|
+
return @prepared_search if defined?(@prepared_search)
|
12
|
+
@prepared_search = {}
|
13
|
+
if search_options
|
14
|
+
search_options.each do |key, value|
|
15
|
+
next if value.empty?
|
16
|
+
|
17
|
+
if op = create_operator(key)
|
18
|
+
@prepared_search[op] = value
|
19
|
+
else
|
20
|
+
raise InvalidSearchSuffix.new(key)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
return @prepared_search
|
25
|
+
end
|
26
|
+
|
27
|
+
def create_operator(key)
|
28
|
+
if m = key.to_s.match(/(.*)_(#{valid_suffixes.join("|")})/)
|
29
|
+
target = m.captures.first
|
30
|
+
operator = operator_for(m.captures.second)
|
31
|
+
return DataMapper::Query::Operator.new(target, operator)
|
32
|
+
else
|
33
|
+
return nil
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def valid_suffixes
|
38
|
+
return [
|
39
|
+
:gteq,
|
40
|
+
:lteq,
|
41
|
+
:cont
|
42
|
+
]
|
43
|
+
end
|
44
|
+
|
45
|
+
def operator_for(suffix)
|
46
|
+
op_map = {
|
47
|
+
gteq: :gte,
|
48
|
+
lteq: :lte,
|
49
|
+
cont: :like
|
50
|
+
}
|
51
|
+
return op_map[suffix.to_sym]
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
data/lib/upmin/engine.rb
CHANGED
data/lib/upmin/errors.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
module Upmin
|
2
|
+
class InvalidAction < ArgumentError
|
3
|
+
def initialize(action)
|
4
|
+
super("Invalid action: #{action}")
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class MissingArgument < ArgumentError
|
9
|
+
def initialize(arg)
|
10
|
+
super("Missing argument: #{arg}")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class ArgumentError < ArgumentError
|
15
|
+
def initialize(arg)
|
16
|
+
super("Invalid argument: #{arg}")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class MissingPartial < ::StandardError
|
21
|
+
def initialize(data)
|
22
|
+
super("Could not find a matching partial with the following data: #{data.as_json}")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class UnsupportedObjectMapper < ::StandardError
|
27
|
+
def initialize
|
28
|
+
super("The ORM or ODM you are using is not supported. Please create an issue on github if one doesn't exist - https://github.com/upmin/upmin-admin-ruby/issues")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class UninferrableAdminError < NameError
|
33
|
+
def initialize(klass)
|
34
|
+
super("Could not infer an Admin class for #{klass}.")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class UninferrableSourceError < NameError
|
39
|
+
def initialize(klass)
|
40
|
+
super("Could not infer a source for #{klass}.")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/upmin/model.rb
CHANGED
@@ -1,137 +1,306 @@
|
|
1
1
|
module Upmin
|
2
2
|
class Model
|
3
|
+
include Upmin::Engine.routes.url_helpers
|
4
|
+
include Upmin::AutomaticDelegation
|
3
5
|
|
4
|
-
|
5
|
-
|
6
|
+
attr_reader :model
|
7
|
+
alias_method :object, :model
|
6
8
|
|
7
|
-
def initialize(
|
8
|
-
self.
|
9
|
-
|
9
|
+
def initialize(model = nil, options = {})
|
10
|
+
if self.class.active_record?
|
11
|
+
self.class.send(:include, Upmin::ActiveRecord::Model)
|
12
|
+
elsif self.class.data_mapper?
|
13
|
+
self.class.send(:include, Upmin::DataMapper::Model)
|
14
|
+
end
|
15
|
+
|
16
|
+
if model.is_a?(Hash)
|
17
|
+
unless model.has_key?(:id)
|
18
|
+
raise ":id or model instance is required."
|
19
|
+
end
|
20
|
+
@model = self.class.find(model[:id])
|
21
|
+
elsif model.nil?
|
22
|
+
@model = self.model_class.new
|
23
|
+
else
|
24
|
+
@model = model
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def path
|
29
|
+
if new_record?
|
30
|
+
return upmin_new_model_path(klass: model_class_name)
|
31
|
+
else
|
32
|
+
return upmin_model_path(klass: model_class_name, id: id)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def create_path
|
37
|
+
return upmin_create_model_path(klass: model_class_name)
|
10
38
|
end
|
11
39
|
|
12
|
-
## Methods for rendering in views
|
13
40
|
def title
|
14
|
-
return "#{
|
41
|
+
return "#{humanized_name(:singular)} # #{id}"
|
42
|
+
end
|
43
|
+
|
44
|
+
def attributes
|
45
|
+
return @attributes if defined?(@attributes)
|
46
|
+
@attributes = []
|
47
|
+
self.class.attributes.each do |attr_name|
|
48
|
+
@attributes << Upmin::Attribute.new(self, attr_name)
|
49
|
+
end
|
50
|
+
return @attributes
|
51
|
+
end
|
52
|
+
|
53
|
+
def associations
|
54
|
+
return @associations if defined?(@associations)
|
55
|
+
@associations = []
|
56
|
+
self.class.associations.each do |assoc_name|
|
57
|
+
@associations << Upmin::Association.new(self, assoc_name)
|
58
|
+
end
|
59
|
+
return @associations
|
15
60
|
end
|
16
61
|
|
62
|
+
def actions
|
63
|
+
return @actions if defined?(@actions)
|
64
|
+
@actions = []
|
65
|
+
self.class.actions.each do |action_name|
|
66
|
+
@actions << Upmin::Action.new(self, action_name)
|
67
|
+
end
|
68
|
+
return @actions
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
###########################################################
|
73
|
+
### Delegated instance methods
|
74
|
+
###########################################################
|
75
|
+
|
76
|
+
# TODO(jon): Delegations here weren't working in 3.2 so this is done with normal old methods.
|
77
|
+
# delegate(:color, to: :class)
|
17
78
|
def color
|
18
|
-
return
|
19
|
-
end
|
20
|
-
|
21
|
-
def
|
22
|
-
return
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
79
|
+
return self.class.color
|
80
|
+
end
|
81
|
+
# delegate(:humanized_name, to: :class)
|
82
|
+
def humanized_name(type = :plural)
|
83
|
+
return self.class.humanized_name(type)
|
84
|
+
end
|
85
|
+
# delegate(:underscore_name, to: :class)
|
86
|
+
def underscore_name
|
87
|
+
return self.class.underscore_name
|
88
|
+
end
|
89
|
+
# delegate(:model_class, to: :class)
|
90
|
+
def model_class
|
91
|
+
return self.class.model_class
|
92
|
+
end
|
93
|
+
# delegate(:model_class_name, to: :class)
|
94
|
+
def model_class_name
|
95
|
+
return self.class.model_class_name
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
|
101
|
+
###########################################################
|
102
|
+
### Class methods
|
103
|
+
###########################################################
|
104
|
+
|
105
|
+
def Model.count(*args)
|
106
|
+
return model_class.count(*args)
|
107
|
+
end
|
108
|
+
|
109
|
+
def Model.find_class(model)
|
110
|
+
return find_or_create_class(model.to_s)
|
111
|
+
end
|
112
|
+
|
113
|
+
def Model.find_or_create_class(model_name)
|
114
|
+
::Rails.application.eager_load!
|
115
|
+
return "Admin#{model_name}".constantize
|
116
|
+
rescue NameError
|
117
|
+
eval("class ::Admin#{model_name} < Upmin::Model; end")
|
118
|
+
return "Admin#{model_name}".constantize
|
119
|
+
end
|
120
|
+
|
121
|
+
# Returns all upmin models.
|
122
|
+
def Model.all
|
123
|
+
all = []
|
124
|
+
Upmin.configuration.models.each do |m|
|
125
|
+
all << find_or_create_class(m.to_s.camelize)
|
59
126
|
end
|
127
|
+
return all
|
128
|
+
end
|
60
129
|
|
61
|
-
|
130
|
+
def Model.model_class
|
131
|
+
@model_class ||= inferred_model_class
|
62
132
|
end
|
63
133
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
return false
|
68
|
-
return false if attr_name == :created_at
|
69
|
-
return false if attr_name == :updated_at
|
70
|
-
# TODO(jon): Add a way to declare which attributes are editable and which are not later.
|
71
|
-
return instance.respond_to?("#{attr_name}=")
|
134
|
+
def Model.model_class?
|
135
|
+
return model_class
|
136
|
+
rescue Upmin::UninferrableSourceError
|
137
|
+
return false
|
72
138
|
end
|
73
139
|
|
74
|
-
|
75
|
-
|
76
|
-
attr_name = attr_name.to_sym
|
77
|
-
# TODO(jon): Add some way to handle exceptions. Probably a custom error that we display.
|
78
|
-
return instance.send(attr_name)
|
140
|
+
def Model.model_class
|
141
|
+
return @model_class ||= inferred_model_class
|
79
142
|
end
|
80
143
|
|
81
|
-
def
|
82
|
-
|
144
|
+
def Model.inferred_model_class
|
145
|
+
name = model_class_name
|
146
|
+
return name.constantize
|
147
|
+
rescue NameError => error
|
148
|
+
raise if name && !error.missing_name?(name)
|
149
|
+
raise Upmin::UninferrableSourceError.new(self)
|
83
150
|
end
|
84
151
|
|
85
|
-
def
|
86
|
-
|
152
|
+
def Model.model_class_name
|
153
|
+
raise NameError if name.nil? || name.demodulize !~ /Admin.+$/
|
154
|
+
return name.demodulize[5..-1]
|
87
155
|
end
|
88
156
|
|
157
|
+
def Model.model_name
|
158
|
+
return ActiveModel::Name.new(model_class)
|
159
|
+
end
|
89
160
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
if type == :unknown && data = association(assoc_name).first
|
95
|
-
type = data.class.name.underscore
|
161
|
+
def Model.humanized_name(type = :plural)
|
162
|
+
names = model_class_name.split(/(?=[A-Z])/)
|
163
|
+
if type == :plural
|
164
|
+
names[names.length-1] = names.last.pluralize
|
96
165
|
end
|
97
|
-
return
|
166
|
+
return names.join(" ")
|
98
167
|
end
|
99
168
|
|
100
|
-
def
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
association = association.limit(5)
|
106
|
-
end
|
169
|
+
def Model.underscore_name(type = :singular)
|
170
|
+
if type == :singular
|
171
|
+
return model_class_name.underscore
|
172
|
+
else
|
173
|
+
return model_class_name.pluralize.underscore
|
107
174
|
end
|
108
|
-
return association
|
109
175
|
end
|
110
176
|
|
111
|
-
def
|
112
|
-
|
177
|
+
def Model.search_path
|
178
|
+
return Upmin::Engine.routes.url_helpers.upmin_search_path(klass: model_class_name)
|
179
|
+
end
|
180
|
+
|
181
|
+
def Model.color
|
182
|
+
return @color if defined?(@color)
|
183
|
+
@color = Model.next_color
|
184
|
+
return @color
|
185
|
+
end
|
186
|
+
|
187
|
+
def Model.colors
|
188
|
+
return Upmin.configuration.colors
|
113
189
|
end
|
114
190
|
|
115
|
-
def
|
116
|
-
|
117
|
-
|
191
|
+
def Model.next_color
|
192
|
+
@color_index ||= 0
|
193
|
+
next_color = colors[@color_index]
|
194
|
+
@color_index = (@color_index + 1) % colors.length
|
195
|
+
return next_color
|
196
|
+
end
|
197
|
+
|
198
|
+
# This is not currently used, but could be used to ensure colors are always the same.
|
199
|
+
def Model.color_index
|
200
|
+
return @color_index if defined?(@color_index)
|
201
|
+
@color_index = model_class_name.split("").map(&:ord).inject(:+) % colors.length
|
202
|
+
return @color_index
|
203
|
+
end
|
204
|
+
|
205
|
+
|
206
|
+
def Model.active_record?
|
207
|
+
if defined?(ActiveRecord)
|
208
|
+
return model_class.superclass == ::ActiveRecord::Base
|
209
|
+
else
|
210
|
+
return false
|
118
211
|
end
|
212
|
+
end
|
119
213
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
214
|
+
def Model.data_mapper?
|
215
|
+
if defined?(DataMapper)
|
216
|
+
return model_class.is_a?(::DataMapper::Model)
|
217
|
+
else
|
218
|
+
return false
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
|
223
|
+
|
224
|
+
###########################################################
|
225
|
+
### Customization methods for Admin<Model> classes
|
226
|
+
###########################################################
|
227
|
+
|
228
|
+
# Add a single attribute to upmin attributes.
|
229
|
+
# If this is called before upmin_attributes
|
230
|
+
# the attributes will not include any defaults
|
231
|
+
# attributes.
|
232
|
+
def Model.attribute(attribute = nil)
|
233
|
+
@extra_attrs = [] unless defined?(@extra_attrs)
|
234
|
+
@extra_attrs << attribute.to_sym if attribute
|
235
|
+
end
|
236
|
+
|
237
|
+
# Sets the attributes to the provided attributes # if any are any provided.
|
238
|
+
# If no attributes are provided then the
|
239
|
+
# attributes are set to the default attributes of
|
240
|
+
# the model class.
|
241
|
+
def Model.attributes(*attributes)
|
242
|
+
@extra_attrs = [] unless defined?(@extra_attrs)
|
243
|
+
|
244
|
+
if attributes.any?
|
245
|
+
@attributes = attributes.map{|a| a.to_sym}
|
246
|
+
end
|
247
|
+
@attributes ||= default_attributes
|
248
|
+
|
249
|
+
return (@attributes + @extra_attrs).uniq
|
250
|
+
end
|
251
|
+
|
252
|
+
# Add a single action to upmin actions. If this is called
|
253
|
+
# before upmin_actions the actions will not include any defaults
|
254
|
+
# actions.
|
255
|
+
def Model.action(action)
|
256
|
+
@actions ||= []
|
257
|
+
|
258
|
+
action = action.to_sym
|
259
|
+
@actions << action unless @actions.include?(action)
|
260
|
+
end
|
261
|
+
|
262
|
+
# Sets the upmin_actions to the provided actions if any are
|
263
|
+
# provided.
|
264
|
+
# If no actions are provided, and upmin_actions hasn't been defined,
|
265
|
+
# then the upmin_actions are set to the default actions.
|
266
|
+
# Returns the upmin_actions
|
267
|
+
def Model.actions(*actions)
|
268
|
+
if actions.any?
|
269
|
+
# set the actions
|
270
|
+
@actions = actions.map{|a| a.to_sym}
|
131
271
|
end
|
132
|
-
|
272
|
+
@actions ||= []
|
273
|
+
return @actions
|
133
274
|
end
|
134
275
|
|
135
276
|
|
277
|
+
|
278
|
+
###########################################################
|
279
|
+
### Methods that need to be to be overridden. If the
|
280
|
+
### Model.method_name version of these are ever called it
|
281
|
+
### means that it wasn't overridden, or an instance of
|
282
|
+
### the class hasn't been created yet.
|
283
|
+
###########################################################
|
284
|
+
|
285
|
+
def Model.find(*args)
|
286
|
+
new
|
287
|
+
return find(*args)
|
288
|
+
end
|
289
|
+
|
290
|
+
def Model.default_attributes
|
291
|
+
new
|
292
|
+
return default_attributes
|
293
|
+
end
|
294
|
+
|
295
|
+
def Model.attribute_type(attribute)
|
296
|
+
new
|
297
|
+
return attribute_type(attribute)
|
298
|
+
end
|
299
|
+
|
300
|
+
def Model.associations
|
301
|
+
new
|
302
|
+
return associations
|
303
|
+
end
|
304
|
+
|
136
305
|
end
|
137
306
|
end
|