merb-admin 0.8.1 → 0.8.3
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.
- data/.gitignore +29 -27
- data/Gemfile +24 -22
- data/Gemfile.lock +86 -0
- data/LICENSE +20 -20
- data/README.rdoc +54 -58
- data/Rakefile +11 -44
- data/app/controllers/application.rb +6 -6
- data/app/controllers/main.rb +191 -191
- data/app/helpers/application_helper.rb +64 -64
- data/app/helpers/main_helper.rb +167 -167
- data/app/models/.gitkeep +0 -0
- data/app/views/layout/_message.html.erb +10 -10
- data/app/views/layout/dashboard.html.erb +34 -34
- data/app/views/layout/form.html.erb +48 -48
- data/app/views/layout/list.html.erb +42 -42
- data/app/views/main/_belongs_to.html.erb +29 -29
- data/app/views/main/_big_decimal.html.erb +12 -12
- data/app/views/main/_boolean.html.erb +7 -7
- data/app/views/main/_date.html.erb +12 -12
- data/app/views/main/_datetime.html.erb +12 -12
- data/app/views/main/_float.html.erb +12 -12
- data/app/views/main/_has_many.html.erb +16 -16
- data/app/views/main/_has_one.html.erb +30 -30
- data/app/views/main/_integer.html.erb +12 -12
- data/app/views/main/_properties.html.erb +18 -18
- data/app/views/main/_string.html.erb +15 -15
- data/app/views/main/_text.html.erb +11 -11
- data/app/views/main/_time.html.erb +12 -12
- data/app/views/main/_timestamp.html.erb +12 -12
- data/app/views/main/delete.html.erb +28 -28
- data/app/views/main/edit.html.erb +19 -19
- data/app/views/main/index.html.erb +22 -22
- data/app/views/main/list.html.erb +93 -93
- data/app/views/main/new.html.erb +16 -16
- data/config/init.rb +30 -0
- data/config/router.rb +4 -0
- data/lib/abstract_model.rb +84 -86
- data/lib/active_record_support.rb +147 -147
- data/lib/datamapper_support.rb +139 -140
- data/lib/generic_support.rb +13 -13
- data/lib/merb-admin.rb +99 -99
- data/lib/merb-admin/merbtasks.rb +103 -103
- data/lib/merb-admin/slicetasks.rb +174 -174
- data/lib/merb-admin/spectasks.rb +55 -55
- data/lib/merb-admin/version.rb +3 -0
- data/lib/sequel_support.rb +275 -275
- data/merb-admin.gemspec +42 -232
- data/public/javascripts/CollapsedFieldsets.js +85 -85
- data/public/javascripts/DateTimeShortcuts.js +255 -255
- data/public/javascripts/RelatedObjectLookups.js +96 -96
- data/public/javascripts/SelectBox.js +111 -111
- data/public/javascripts/SelectFilter2.js +113 -113
- data/public/javascripts/actions.js +39 -39
- data/public/javascripts/calendar.js +143 -143
- data/public/javascripts/core.js +176 -176
- data/public/javascripts/dateparse.js +233 -233
- data/public/javascripts/getElementsBySelector.js +167 -167
- data/public/javascripts/i18n.js +33 -33
- data/public/javascripts/ordering.js +137 -137
- data/public/javascripts/timeparse.js +94 -94
- data/public/javascripts/urlify.js +140 -140
- data/public/stylesheets/base.css +746 -746
- data/public/stylesheets/changelists.css +269 -269
- data/public/stylesheets/dashboard.css +24 -24
- data/public/stylesheets/forms.css +327 -327
- data/public/stylesheets/global.css +142 -142
- data/public/stylesheets/ie.css +50 -50
- data/public/stylesheets/layout.css +29 -29
- data/public/stylesheets/login.css +54 -54
- data/public/stylesheets/master.css +1 -1
- data/public/stylesheets/patch-iewin.css +7 -7
- data/public/stylesheets/rtl.css +206 -206
- data/public/stylesheets/widgets.css +506 -506
- data/screenshots/create.png +0 -0
- data/screenshots/delete.png +0 -0
- data/screenshots/edit.png +0 -0
- data/screenshots/index.png +0 -0
- data/screenshots/list.png +0 -0
- data/screenshots/new.png +0 -0
- data/spec/controllers/main_spec.rb +25 -25
- data/spec/migrations/activerecord/001_create_divisions_migration.rb +13 -13
- data/spec/migrations/activerecord/002_create_drafts_migration.rb +19 -19
- data/spec/migrations/activerecord/003_create_leagues_migration.rb +12 -12
- data/spec/migrations/activerecord/004_create_players_migration.rb +19 -20
- data/spec/migrations/activerecord/005_create_teams_migration.rb +22 -22
- data/spec/migrations/sequel/001_create_divisions_migration.rb +15 -15
- data/spec/migrations/sequel/002_create_drafts_migration.rb +21 -21
- data/spec/migrations/sequel/003_create_leagues_migration.rb +14 -14
- data/spec/migrations/sequel/004_create_players_migration.rb +21 -22
- data/spec/migrations/sequel/005_create_teams_migration.rb +24 -24
- data/spec/models/activerecord/division.rb +7 -7
- data/spec/models/activerecord/draft.rb +11 -11
- data/spec/models/activerecord/league.rb +6 -6
- data/spec/models/activerecord/player.rb +8 -8
- data/spec/models/activerecord/team.rb +13 -13
- data/spec/models/datamapper/division.rb +12 -12
- data/spec/models/datamapper/draft.rb +18 -18
- data/spec/models/datamapper/league.rb +11 -11
- data/spec/models/datamapper/player.rb +20 -21
- data/spec/models/datamapper/team.rb +22 -22
- data/spec/models/sequel/division.rb +15 -15
- data/spec/models/sequel/draft.rb +19 -19
- data/spec/models/sequel/league.rb +14 -14
- data/spec/models/sequel/player.rb +18 -18
- data/spec/models/sequel/team.rb +21 -21
- data/spec/requests/main_spec.rb +763 -763
- data/spec/spec_helper.rb +113 -112
- metadata +247 -41
- data/VERSION +0 -1
data/app/views/main/new.html.erb
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
<div id="content-main">
|
|
2
|
-
<%= form_for(@object, :action => url(:merb_admin_create, :model_name => @abstract_model.to_param)) do %>
|
|
3
|
-
<div>
|
|
4
|
-
<%= partial('properties', :properties => @properties) -%>
|
|
5
|
-
<%= partial('belongs_to', :with => @abstract_model.belongs_to_associations, :as => :association) -%>
|
|
6
|
-
<%= partial('has_one', :with => @abstract_model.has_one_associations, :as => :association) -%>
|
|
7
|
-
<%= partial('has_many', :with => @abstract_model.has_many_associations, :as => :association) -%>
|
|
8
|
-
<div class="submit-row" >
|
|
9
|
-
<%= submit "Save", :class => "default", :name => "_save" %>
|
|
10
|
-
<%= submit "Save and add another", :name => "_add_another" %>
|
|
11
|
-
<%= submit "Save and continue editing", :name => "_continue" %>
|
|
12
|
-
</div>
|
|
13
|
-
</div>
|
|
14
|
-
<% end =%>
|
|
15
|
-
|
|
16
|
-
</div>
|
|
1
|
+
<div id="content-main">
|
|
2
|
+
<%= form_for(@object, :action => url(:merb_admin_create, :model_name => @abstract_model.to_param)) do %>
|
|
3
|
+
<div>
|
|
4
|
+
<%= partial('properties', :properties => @properties) -%>
|
|
5
|
+
<%= partial('belongs_to', :with => @abstract_model.belongs_to_associations, :as => :association) -%>
|
|
6
|
+
<%= partial('has_one', :with => @abstract_model.has_one_associations, :as => :association) -%>
|
|
7
|
+
<%= partial('has_many', :with => @abstract_model.has_many_associations, :as => :association) -%>
|
|
8
|
+
<div class="submit-row" >
|
|
9
|
+
<%= submit "Save", :class => "default", :name => "_save" %>
|
|
10
|
+
<%= submit "Save and add another", :name => "_add_another" %>
|
|
11
|
+
<%= submit "Save and continue editing", :name => "_continue" %>
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
14
|
+
<% end =%>
|
|
15
|
+
|
|
16
|
+
</div>
|
data/config/init.rb
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#
|
|
2
|
+
# ==== Standalone MerbAdmin configuration
|
|
3
|
+
#
|
|
4
|
+
# This configuration/environment file is only loaded by bin/slice, which can be
|
|
5
|
+
# used during development of the slice. It has no effect on this slice being
|
|
6
|
+
# loaded in a host application. To run your slice in standalone mode, just
|
|
7
|
+
# run 'slice' from its directory. The 'slice' command is very similar to
|
|
8
|
+
# the 'merb' command, and takes all the same options, including -i to drop
|
|
9
|
+
# into an irb session for example.
|
|
10
|
+
#
|
|
11
|
+
# The usual Merb configuration directives and init.rb setup methods apply,
|
|
12
|
+
# including use_orm and before_app_loads/after_app_loads.
|
|
13
|
+
#
|
|
14
|
+
# If you need need different configurations for different environments you can
|
|
15
|
+
# even create the specific environment file in config/environments/ just like
|
|
16
|
+
# in a regular Merb application.
|
|
17
|
+
#
|
|
18
|
+
# In fact, a slice is no different from a normal # Merb application - it only
|
|
19
|
+
# differs by the fact that seamlessly integrates into a so called 'host'
|
|
20
|
+
# application, which in turn can override or finetune the slice implementation
|
|
21
|
+
# code and views.
|
|
22
|
+
|
|
23
|
+
use_test :rspec
|
|
24
|
+
use_template_engine :erb
|
|
25
|
+
|
|
26
|
+
Merb::Config.use do |c|
|
|
27
|
+
c[:exception_details] = true
|
|
28
|
+
c[:reload_templates] = true
|
|
29
|
+
c[:reload_classes] = true
|
|
30
|
+
end
|
data/config/router.rb
ADDED
data/lib/abstract_model.rb
CHANGED
|
@@ -1,86 +1,84 @@
|
|
|
1
|
-
require 'generic_support'
|
|
2
|
-
|
|
3
|
-
module MerbAdmin
|
|
4
|
-
class AbstractModel
|
|
5
|
-
# Returns all models for a given Merb app
|
|
6
|
-
def self.all
|
|
7
|
-
@models = []
|
|
8
|
-
orm = Merb.orm
|
|
9
|
-
case orm
|
|
10
|
-
when :activerecord, :sequel
|
|
11
|
-
Dir.glob(Merb.dir_for(:model) / Merb.glob_for(:model)).each do |filename|
|
|
12
|
-
File.read(filename).scan(/class ([\w\d_\-:]+)/).flatten.each do |model_name|
|
|
13
|
-
add_model(model_name)
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
when :datamapper
|
|
17
|
-
DataMapper::Model.descendants.each do |model|
|
|
18
|
-
add_model(model.to_s)
|
|
19
|
-
end
|
|
20
|
-
else
|
|
21
|
-
raise "MerbAdmin does not support the #{orm} ORM"
|
|
22
|
-
end
|
|
23
|
-
@models.sort!{|x, y| x.model.to_s <=> y.model.to_s}
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def self.add_model(model_name)
|
|
27
|
-
model = lookup(model_name)
|
|
28
|
-
@models << new(model) if model
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# Given a string +model_name+, finds the corresponding model class
|
|
32
|
-
def self.lookup(model_name)
|
|
33
|
-
return nil if MerbAdmin[:excluded_models].include?(model_name)
|
|
34
|
-
begin
|
|
35
|
-
model = Object.full_const_get(model_name)
|
|
36
|
-
rescue NameError
|
|
37
|
-
raise "MerbAdmin could not find model #{model_name}"
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
case Merb.orm
|
|
41
|
-
when :activerecord
|
|
42
|
-
model if superclasses(model).include?(ActiveRecord::Base)
|
|
43
|
-
when :
|
|
44
|
-
model if model.include?(
|
|
45
|
-
|
|
46
|
-
model
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
model =
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
end
|
|
86
|
-
end
|
|
1
|
+
require 'generic_support'
|
|
2
|
+
|
|
3
|
+
module MerbAdmin
|
|
4
|
+
class AbstractModel
|
|
5
|
+
# Returns all models for a given Merb app
|
|
6
|
+
def self.all
|
|
7
|
+
@models = []
|
|
8
|
+
orm = Merb.orm
|
|
9
|
+
case orm
|
|
10
|
+
when :activerecord, :sequel
|
|
11
|
+
Dir.glob(Merb.dir_for(:model) / Merb.glob_for(:model)).each do |filename|
|
|
12
|
+
File.read(filename).scan(/class ([\w\d_\-:]+)/).flatten.each do |model_name|
|
|
13
|
+
add_model(model_name)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
when :datamapper
|
|
17
|
+
DataMapper::Model.descendants.each do |model|
|
|
18
|
+
add_model(model.to_s)
|
|
19
|
+
end
|
|
20
|
+
else
|
|
21
|
+
raise "MerbAdmin does not support the #{orm} ORM"
|
|
22
|
+
end
|
|
23
|
+
@models.sort!{|x, y| x.model.to_s <=> y.model.to_s}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.add_model(model_name)
|
|
27
|
+
model = lookup(model_name)
|
|
28
|
+
@models << new(model) if model
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Given a string +model_name+, finds the corresponding model class
|
|
32
|
+
def self.lookup(model_name)
|
|
33
|
+
return nil if MerbAdmin[:excluded_models].include?(model_name)
|
|
34
|
+
begin
|
|
35
|
+
model = Object.full_const_get(model_name)
|
|
36
|
+
rescue NameError
|
|
37
|
+
raise "MerbAdmin could not find model #{model_name}"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
case Merb.orm
|
|
41
|
+
when :activerecord
|
|
42
|
+
model if superclasses(model).include?(ActiveRecord::Base)
|
|
43
|
+
when :sequel
|
|
44
|
+
model if superclasses(model).include?(Sequel::Model)
|
|
45
|
+
else
|
|
46
|
+
model
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
attr_accessor :model
|
|
51
|
+
|
|
52
|
+
def initialize(model)
|
|
53
|
+
model = self.class.lookup(model.to_s.camel_case) unless model.is_a?(Class)
|
|
54
|
+
orm = Merb.orm
|
|
55
|
+
@model = model
|
|
56
|
+
self.extend(GenericSupport)
|
|
57
|
+
case orm
|
|
58
|
+
when :activerecord
|
|
59
|
+
require 'active_record_support'
|
|
60
|
+
self.extend(ActiverecordSupport)
|
|
61
|
+
when :datamapper
|
|
62
|
+
require 'datamapper_support'
|
|
63
|
+
self.extend(DatamapperSupport)
|
|
64
|
+
when :sequel
|
|
65
|
+
require 'sequel_support'
|
|
66
|
+
self.extend(SequelSupport)
|
|
67
|
+
else
|
|
68
|
+
raise "MerbAdmin does not support the #{orm} ORM"
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
private
|
|
73
|
+
|
|
74
|
+
def self.superclasses(klass)
|
|
75
|
+
superclasses = []
|
|
76
|
+
while klass
|
|
77
|
+
superclasses << klass.superclass if klass && klass.superclass
|
|
78
|
+
klass = klass.superclass
|
|
79
|
+
end
|
|
80
|
+
superclasses
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -1,147 +1,147 @@
|
|
|
1
|
-
require 'active_record'
|
|
2
|
-
|
|
3
|
-
module MerbAdmin
|
|
4
|
-
class AbstractModel
|
|
5
|
-
module ActiverecordSupport
|
|
6
|
-
def get(id)
|
|
7
|
-
model.find_by_id(id).extend(InstanceMethods)
|
|
8
|
-
rescue ActiveRecord::RecordNotFound
|
|
9
|
-
nil
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def count(options = {})
|
|
13
|
-
model.count(options.reject{|key, value| [:sort, :sort_reverse].include?(key)})
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def first(options = {})
|
|
17
|
-
model.first(merge_order(options)).extend(InstanceMethods)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def all(options = {})
|
|
21
|
-
model.all(merge_order(options))
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def paginated(options = {})
|
|
25
|
-
page = options.delete(:page) || 1
|
|
26
|
-
per_page = options.delete(:per_page) || MerbAdmin[:per_page]
|
|
27
|
-
|
|
28
|
-
page_count = (count(options).to_f / per_page).ceil
|
|
29
|
-
|
|
30
|
-
options.merge!({
|
|
31
|
-
:limit => per_page,
|
|
32
|
-
:offset => (page - 1) * per_page
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
[page_count, all(options)]
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def create(params = {})
|
|
39
|
-
model.create(params).extend(InstanceMethods)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def new(params = {})
|
|
43
|
-
model.new(params).extend(InstanceMethods)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def destroy_all!
|
|
47
|
-
model.all.each do |object|
|
|
48
|
-
object.destroy
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def has_many_associations
|
|
53
|
-
associations.select do |association|
|
|
54
|
-
association[:type] == :has_many
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def has_one_associations
|
|
59
|
-
associations.select do |association|
|
|
60
|
-
association[:type] == :has_one
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def belongs_to_associations
|
|
65
|
-
associations.select do |association|
|
|
66
|
-
association[:type] == :belongs_to
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def associations
|
|
71
|
-
model.reflect_on_all_associations.map do |association|
|
|
72
|
-
{
|
|
73
|
-
:name => association.name,
|
|
74
|
-
:pretty_name => association.name.to_s.gsub('_', ' ').capitalize,
|
|
75
|
-
:type => association.macro,
|
|
76
|
-
:parent_model => association_parent_model_lookup(association),
|
|
77
|
-
:parent_key => association_parent_key_lookup(association),
|
|
78
|
-
:child_model => association_child_model_lookup(association),
|
|
79
|
-
:child_key => association_child_key_lookup(association),
|
|
80
|
-
}
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def properties
|
|
85
|
-
model.columns.map do |property|
|
|
86
|
-
{
|
|
87
|
-
:name => property.name.to_sym,
|
|
88
|
-
:pretty_name => property.human_name,
|
|
89
|
-
:type => property.type,
|
|
90
|
-
:length => property.limit,
|
|
91
|
-
:nullable? => property.null,
|
|
92
|
-
:serial? => property.primary,
|
|
93
|
-
}
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
private
|
|
98
|
-
|
|
99
|
-
def merge_order(options)
|
|
100
|
-
@sort ||= options.delete(:sort) || "id"
|
|
101
|
-
@sort_order ||= options.delete(:sort_reverse) ? "desc" : "asc"
|
|
102
|
-
options.merge(:order => ["#{@sort} #{@sort_order}"])
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
def association_parent_model_lookup(association)
|
|
106
|
-
case association.macro
|
|
107
|
-
when :belongs_to
|
|
108
|
-
association.klass
|
|
109
|
-
when :has_one, :has_many
|
|
110
|
-
association.active_record
|
|
111
|
-
else
|
|
112
|
-
raise "Unknown association type"
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
def association_parent_key_lookup(association)
|
|
117
|
-
[:id]
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
def association_child_model_lookup(association)
|
|
121
|
-
case association.macro
|
|
122
|
-
when :belongs_to
|
|
123
|
-
association.active_record
|
|
124
|
-
when :has_one, :has_many
|
|
125
|
-
association.klass
|
|
126
|
-
else
|
|
127
|
-
raise "Unknown association type"
|
|
128
|
-
end
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
def association_child_key_lookup(association)
|
|
132
|
-
case association.macro
|
|
133
|
-
when :belongs_to
|
|
134
|
-
["#{association.class_name.snake_case}_id".to_sym]
|
|
135
|
-
when :has_one, :has_many
|
|
136
|
-
[association.primary_key_name.to_sym]
|
|
137
|
-
else
|
|
138
|
-
raise "Unknown association type"
|
|
139
|
-
end
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
module InstanceMethods
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
end
|
|
146
|
-
end
|
|
147
|
-
end
|
|
1
|
+
require 'active_record'
|
|
2
|
+
|
|
3
|
+
module MerbAdmin
|
|
4
|
+
class AbstractModel
|
|
5
|
+
module ActiverecordSupport
|
|
6
|
+
def get(id)
|
|
7
|
+
model.find_by_id(id).extend(InstanceMethods)
|
|
8
|
+
rescue ActiveRecord::RecordNotFound
|
|
9
|
+
nil
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def count(options = {})
|
|
13
|
+
model.count(options.reject{|key, value| [:sort, :sort_reverse].include?(key)})
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def first(options = {})
|
|
17
|
+
model.first(merge_order(options)).extend(InstanceMethods)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def all(options = {})
|
|
21
|
+
model.all(merge_order(options))
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def paginated(options = {})
|
|
25
|
+
page = options.delete(:page) || 1
|
|
26
|
+
per_page = options.delete(:per_page) || MerbAdmin[:per_page]
|
|
27
|
+
|
|
28
|
+
page_count = (count(options).to_f / per_page).ceil
|
|
29
|
+
|
|
30
|
+
options.merge!({
|
|
31
|
+
:limit => per_page,
|
|
32
|
+
:offset => (page - 1) * per_page
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
[page_count, all(options)]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def create(params = {})
|
|
39
|
+
model.create(params).extend(InstanceMethods)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def new(params = {})
|
|
43
|
+
model.new(params).extend(InstanceMethods)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def destroy_all!
|
|
47
|
+
model.all.each do |object|
|
|
48
|
+
object.destroy
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def has_many_associations
|
|
53
|
+
associations.select do |association|
|
|
54
|
+
association[:type] == :has_many
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def has_one_associations
|
|
59
|
+
associations.select do |association|
|
|
60
|
+
association[:type] == :has_one
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def belongs_to_associations
|
|
65
|
+
associations.select do |association|
|
|
66
|
+
association[:type] == :belongs_to
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def associations
|
|
71
|
+
model.reflect_on_all_associations.map do |association|
|
|
72
|
+
{
|
|
73
|
+
:name => association.name,
|
|
74
|
+
:pretty_name => association.name.to_s.gsub('_', ' ').capitalize,
|
|
75
|
+
:type => association.macro,
|
|
76
|
+
:parent_model => association_parent_model_lookup(association),
|
|
77
|
+
:parent_key => association_parent_key_lookup(association),
|
|
78
|
+
:child_model => association_child_model_lookup(association),
|
|
79
|
+
:child_key => association_child_key_lookup(association),
|
|
80
|
+
}
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def properties
|
|
85
|
+
model.columns.map do |property|
|
|
86
|
+
{
|
|
87
|
+
:name => property.name.to_sym,
|
|
88
|
+
:pretty_name => property.human_name,
|
|
89
|
+
:type => property.type,
|
|
90
|
+
:length => property.limit,
|
|
91
|
+
:nullable? => property.null,
|
|
92
|
+
:serial? => property.primary,
|
|
93
|
+
}
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
private
|
|
98
|
+
|
|
99
|
+
def merge_order(options)
|
|
100
|
+
@sort ||= options.delete(:sort) || "id"
|
|
101
|
+
@sort_order ||= options.delete(:sort_reverse) ? "desc" : "asc"
|
|
102
|
+
options.merge(:order => ["#{@sort} #{@sort_order}"])
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def association_parent_model_lookup(association)
|
|
106
|
+
case association.macro
|
|
107
|
+
when :belongs_to
|
|
108
|
+
association.klass
|
|
109
|
+
when :has_one, :has_many
|
|
110
|
+
association.active_record
|
|
111
|
+
else
|
|
112
|
+
raise "Unknown association type"
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def association_parent_key_lookup(association)
|
|
117
|
+
[:id]
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def association_child_model_lookup(association)
|
|
121
|
+
case association.macro
|
|
122
|
+
when :belongs_to
|
|
123
|
+
association.active_record
|
|
124
|
+
when :has_one, :has_many
|
|
125
|
+
association.klass
|
|
126
|
+
else
|
|
127
|
+
raise "Unknown association type"
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def association_child_key_lookup(association)
|
|
132
|
+
case association.macro
|
|
133
|
+
when :belongs_to
|
|
134
|
+
["#{association.class_name.snake_case}_id".to_sym]
|
|
135
|
+
when :has_one, :has_many
|
|
136
|
+
[association.primary_key_name.to_sym]
|
|
137
|
+
else
|
|
138
|
+
raise "Unknown association type"
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
module InstanceMethods
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|