sferik-merb-admin 0.3.6 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +3 -4
- data/Rakefile +1 -1
- data/app/controllers/main.rb +13 -51
- data/app/helpers/main_helper.rb +7 -1
- data/app/views/layout/form.html.erb +1 -1
- data/app/views/layout/list.html.erb +1 -1
- data/app/views/main/_belongs_to.html.erb +2 -2
- data/app/views/main/_big_decimal.html.erb +1 -1
- data/app/views/main/_boolean.html.erb +1 -1
- data/app/views/main/_date.html.erb +1 -1
- data/app/views/main/{_date_time.html.erb → _datetime.html.erb} +1 -1
- data/app/views/main/_float.html.erb +1 -1
- data/app/views/main/_has_many.html.erb +2 -2
- data/app/views/main/_has_one.html.erb +3 -3
- data/app/views/main/_integer.html.erb +1 -1
- data/app/views/main/_string.html.erb +1 -1
- data/app/views/main/_text.html.erb +1 -1
- data/app/views/main/_time.html.erb +1 -1
- data/app/views/main/_timestamp.html.erb +12 -0
- data/app/views/main/delete.html.erb +3 -3
- data/app/views/main/edit.html.erb +2 -2
- data/app/views/main/index.html.erb +4 -4
- data/app/views/main/list.html.erb +6 -63
- data/app/views/main/new.html.erb +1 -1
- data/lib/abstract_model.rb +27 -6
- data/lib/activerecord_support.rb +169 -0
- data/lib/datamapper_support.rb +55 -23
- data/lib/generic_support.rb +1 -1
- data/lib/merb-admin.rb +1 -1
- data/spec/models/activerecord/division.rb +8 -0
- data/spec/models/activerecord/draft.rb +16 -0
- data/spec/models/activerecord/league.rb +6 -0
- data/spec/models/activerecord/player.rb +10 -0
- data/spec/models/activerecord/team.rb +11 -0
- data/spec/models/{division.rb → datamapper/division.rb} +0 -0
- data/spec/models/{draft.rb → datamapper/draft.rb} +0 -0
- data/spec/models/{league.rb → datamapper/league.rb} +0 -0
- data/spec/models/{player.rb → datamapper/player.rb} +1 -2
- data/spec/models/{team.rb → datamapper/team.rb} +0 -0
- data/spec/requests/main_spec.rb +41 -136
- data/spec/spec_helper.rb +57 -21
- metadata +17 -15
- data/lib/metaid.rb +0 -19
- data/spec/fixtures/division_fixture.rb +0 -4
- data/spec/fixtures/draft_fixture.rb +0 -10
- data/spec/fixtures/league_fixture.rb +0 -3
- data/spec/fixtures/player_fixture.rb +0 -7
- data/spec/fixtures/team_fixture.rb +0 -5
data/README.markdown
CHANGED
@@ -14,7 +14,7 @@ At the command prompt, type:
|
|
14
14
|
|
15
15
|
In your app, add the following dependency to `config/dependencies.rb`:
|
16
16
|
|
17
|
-
dependency "sferik-merb-admin", "0.
|
17
|
+
dependency "sferik-merb-admin", "0.4.0", :require_as => "merb-admin"
|
18
18
|
|
19
19
|
Add the following route to `config/router.rb`:
|
20
20
|
|
@@ -26,7 +26,7 @@ Then, run the following rake task:
|
|
26
26
|
|
27
27
|
## Configure it (optional)
|
28
28
|
|
29
|
-
|
29
|
+
If you're feeling crafty, you can set a couple configuration options in `config/init.rb`:
|
30
30
|
|
31
31
|
Merb::BootLoader.before_app_loads do
|
32
32
|
Merb::Slices::config[:merb_admin][:app_name] = "My App"
|
@@ -54,6 +54,5 @@ Many thanks to:
|
|
54
54
|
* [Wilson Miner](http://www.wilsonminer.com) for contributing the stylesheets and javascripts from [Django](http://www.djangoproject.com)
|
55
55
|
* [Aaron Wheeler](http://fightinjoe.com/) for contributing libraries from [Merb AutoScaffold](http://github.com/fightinjoe/merb-autoscaffold)
|
56
56
|
* [Lori Holden](http://loriholden.com/) for contributing the [merb-pagination](http://github.com/lholden/merb-pagination) helper
|
57
|
-
* [why the lucky stiff](http://whytheluckystiff.net/) for [metaid](http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html)
|
58
57
|
|
59
|
-
Also, thanks to [beer](http://www.
|
58
|
+
Also, thanks to [beer](http://www.21st-amendment.com).
|
data/Rakefile
CHANGED
@@ -9,7 +9,7 @@ AUTHOR = "Erik Michaels-Ober"
|
|
9
9
|
EMAIL = "sferik@gmail.com"
|
10
10
|
HOMEPAGE = "http://twitter.com/sferik"
|
11
11
|
SUMMARY = "MerbAdmin is a Merb plugin that provides an easy-to-use interface for managing your data."
|
12
|
-
GEM_VERSION = "0.
|
12
|
+
GEM_VERSION = "0.4.0"
|
13
13
|
|
14
14
|
spec = Gem::Specification.new do |s|
|
15
15
|
s.rubyforge_project = "merb"
|
data/app/controllers/main.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require File.join( File.dirname(__FILE__), '..', '..', 'lib', 'abstract_model' )
|
2
|
-
require File.join( File.dirname(__FILE__), '..', '..', 'lib', 'metaid' )
|
3
2
|
|
4
3
|
class MerbAdmin::Main < MerbAdmin::Application
|
5
4
|
include Merb::MerbAdmin::MainHelper
|
@@ -14,15 +13,12 @@ class MerbAdmin::Main < MerbAdmin::Application
|
|
14
13
|
|
15
14
|
def list
|
16
15
|
options = {}
|
17
|
-
merge_filter(options)
|
18
|
-
merge_query(options)
|
19
|
-
merge_sort(options)
|
20
16
|
|
21
17
|
if params[:all]
|
22
18
|
options = {
|
23
19
|
:limit => MerbAdmin[:per_page] * 2,
|
24
20
|
}.merge(options)
|
25
|
-
@objects = @abstract_model.
|
21
|
+
@objects = @abstract_model.all(options).reverse
|
26
22
|
else
|
27
23
|
@current_page = (params[:page] || 1).to_i
|
28
24
|
options = {
|
@@ -60,14 +56,14 @@ class MerbAdmin::Main < MerbAdmin::Application
|
|
60
56
|
@object = @abstract_model.new(object)
|
61
57
|
if @object.save && has_one_associations.each{|association, id| update_has_one_association(association, id)} && has_many_associations.each{|association, ids| update_has_many_association(association, ids)}
|
62
58
|
if params[:_continue]
|
63
|
-
redirect(
|
59
|
+
redirect(url(:admin_edit, :model_name => @abstract_model.singular_name, :id => @object.id), :message => {:notice => "#{@abstract_model.pretty_name} was successfully created"})
|
64
60
|
elsif params[:_add_another]
|
65
|
-
redirect(
|
61
|
+
redirect(url(:admin_new, :model_name => @abstract_model.singular_name), :message => {:notice => "#{@abstract_model.pretty_name} was successfully created"})
|
66
62
|
else
|
67
|
-
redirect(
|
63
|
+
redirect(url(:admin_list, :model_name => @abstract_model.singular_name), :message => {:notice => "#{@abstract_model.pretty_name} was successfully created"})
|
68
64
|
end
|
69
65
|
else
|
70
|
-
message[:error] = "#{@abstract_model.pretty_name
|
66
|
+
message[:error] = "#{@abstract_model.pretty_name} failed to be created"
|
71
67
|
render(:new, :layout => 'form')
|
72
68
|
end
|
73
69
|
end
|
@@ -82,14 +78,14 @@ class MerbAdmin::Main < MerbAdmin::Application
|
|
82
78
|
has_many_associations = @abstract_model.has_many_associations.map{|association| [association, (params[:associations] || {}).delete(association[:name])]}
|
83
79
|
if @object.update_attributes(object) && has_one_associations.each{|association, id| update_has_one_association(association, id)} && has_many_associations.each{|association, ids| update_has_many_association(association, ids)}
|
84
80
|
if params[:_continue]
|
85
|
-
redirect(
|
81
|
+
redirect(url(:admin_edit, :model_name => @abstract_model.singular_name, :id => @object.id), :message => {:notice => "#{@abstract_model.pretty_name} was successfully updated"})
|
86
82
|
elsif params[:_add_another]
|
87
|
-
redirect(
|
83
|
+
redirect(url(:admin_new, :model_name => @abstract_model.singular_name), :message => {:notice => "#{@abstract_model.pretty_name} was successfully updated"})
|
88
84
|
else
|
89
|
-
redirect(
|
85
|
+
redirect(url(:admin_list, :model_name => @abstract_model.singular_name), :message => {:notice => "#{@abstract_model.pretty_name} was successfully updated"})
|
90
86
|
end
|
91
87
|
else
|
92
|
-
message[:error] = "#{@abstract_model.pretty_name
|
88
|
+
message[:error] = "#{@abstract_model.pretty_name} failed to be updated"
|
93
89
|
render(:edit, :layout => 'form')
|
94
90
|
end
|
95
91
|
end
|
@@ -100,7 +96,7 @@ class MerbAdmin::Main < MerbAdmin::Application
|
|
100
96
|
|
101
97
|
def destroy
|
102
98
|
if @object.destroy
|
103
|
-
redirect(
|
99
|
+
redirect(url(:admin_list, :model_name => @abstract_model.singular_name), :message => {:notice => "#{@abstract_model.pretty_name} was successfully destroyed"})
|
104
100
|
else
|
105
101
|
raise BadRequest
|
106
102
|
end
|
@@ -123,46 +119,13 @@ class MerbAdmin::Main < MerbAdmin::Application
|
|
123
119
|
end
|
124
120
|
|
125
121
|
def find_object
|
126
|
-
@object = @abstract_model.
|
122
|
+
@object = @abstract_model.get(params[:id])
|
127
123
|
raise NotFound unless @object
|
128
124
|
end
|
129
125
|
|
130
|
-
def merge_filter(options)
|
131
|
-
return unless params[:filter]
|
132
|
-
params[:filter].each_pair do |key, value|
|
133
|
-
@properties.each do |property|
|
134
|
-
next unless property[:name] == key.to_sym
|
135
|
-
if property[:type] == :boolean
|
136
|
-
options.merge!(key.to_sym => (value == 'true'))
|
137
|
-
elsif property[:type] == :integer && property[:flag_map]
|
138
|
-
options.merge!(key.to_sym => value.to_sym)
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
def merge_query(options)
|
145
|
-
return unless params[:query]
|
146
|
-
condition_statement = []
|
147
|
-
conditions = []
|
148
|
-
@properties.each do |property|
|
149
|
-
next unless property[:type] == :string
|
150
|
-
condition_statement << "#{property[:name]} LIKE ?"
|
151
|
-
conditions << "%#{params[:query]}%"
|
152
|
-
end
|
153
|
-
conditions.unshift(condition_statement.join(' OR '))
|
154
|
-
options.merge!(:conditions => conditions) unless conditions == ['']
|
155
|
-
end
|
156
|
-
|
157
|
-
def merge_sort(options)
|
158
|
-
sort = params[:sort] || "id"
|
159
|
-
order = params[:sort_reverse] == "true" ? :desc : :asc
|
160
|
-
options.merge!(:order => [sort.to_sym.send(order)])
|
161
|
-
end
|
162
|
-
|
163
126
|
def update_has_one_association(association, id)
|
164
127
|
model = MerbAdmin::AbstractModel.new(association[:child_model])
|
165
|
-
if object = model.
|
128
|
+
if object = model.get(id)
|
166
129
|
object.update_attributes(association[:child_key].first => @object.id)
|
167
130
|
end
|
168
131
|
end
|
@@ -172,9 +135,8 @@ class MerbAdmin::Main < MerbAdmin::Application
|
|
172
135
|
relationship = @object.send(association[:name])
|
173
136
|
@object.clear_association(relationship)
|
174
137
|
# Add all of the objects to the relationship
|
175
|
-
conditions = {association[:parent_key].first => ids}
|
176
138
|
model = MerbAdmin::AbstractModel.new(association[:child_model])
|
177
|
-
for object in model.
|
139
|
+
for object in model.all_in(ids)
|
178
140
|
relationship << object
|
179
141
|
end
|
180
142
|
@object.save
|
data/app/helpers/main_helper.rb
CHANGED
@@ -3,7 +3,13 @@ module Merb
|
|
3
3
|
module MerbAdmin
|
4
4
|
module MainHelper
|
5
5
|
def object_title(object)
|
6
|
-
object.
|
6
|
+
if object.respond_to?(:name)
|
7
|
+
object.name
|
8
|
+
elsif object.respond_to?(:title)
|
9
|
+
object.title
|
10
|
+
else
|
11
|
+
"#{object.class.to_s} ##{object.id}"
|
12
|
+
end
|
7
13
|
end
|
8
14
|
|
9
15
|
# Given a page count and the current page, we generate a set of pagination
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<%
|
2
2
|
slice_name = "MerbAdmin" + (MerbAdmin[:app_name].blank? ? "" : " for #{MerbAdmin[:app_name]}")
|
3
|
-
page_name = action_name.capitalize + " " + @abstract_model.pretty_name
|
3
|
+
page_name = action_name.capitalize + " " + @abstract_model.pretty_name.downcase
|
4
4
|
%>
|
5
5
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
6
6
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-us" lang="en-us">
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<%
|
2
2
|
slice_name = "MerbAdmin" + (MerbAdmin[:app_name].blank? ? "" : " for #{MerbAdmin[:app_name]}")
|
3
|
-
page_name = "Select " + @abstract_model.pretty_name + " to edit"
|
3
|
+
page_name = "Select " + @abstract_model.pretty_name.downcase + " to edit"
|
4
4
|
%>
|
5
5
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
6
6
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-us" lang="en-us">
|
@@ -1,8 +1,8 @@
|
|
1
1
|
<%
|
2
2
|
child_key = association[:child_key].first
|
3
|
-
collection = MerbAdmin::AbstractModel.new(association[:parent_model]).
|
3
|
+
collection = MerbAdmin::AbstractModel.new(association[:parent_model]).all.map{|o| [o.id, object_title(o)]}.sort_by{|o| o[1]}
|
4
4
|
selected = @object.send(child_key)
|
5
|
-
label = association[:pretty_name]
|
5
|
+
label = association[:pretty_name]
|
6
6
|
required = false
|
7
7
|
@properties.each do |property|
|
8
8
|
next unless property[:name] == child_key
|
@@ -1,8 +1,8 @@
|
|
1
1
|
<%
|
2
2
|
name = association[:name]
|
3
|
-
collection = MerbAdmin::AbstractModel.new(association[:child_model]).
|
3
|
+
collection = MerbAdmin::AbstractModel.new(association[:child_model]).all.map{|o| [o.id, object_title(o)]}.sort_by{|o| o[1]}
|
4
4
|
selected = @object.send(name)
|
5
|
-
label = association[:pretty_name]
|
5
|
+
label = association[:pretty_name]
|
6
6
|
%>
|
7
7
|
<fieldset class="module aligned">
|
8
8
|
<h2><%= label %></h2>
|
@@ -1,9 +1,9 @@
|
|
1
1
|
<%
|
2
2
|
child_key = association[:child_key].first
|
3
3
|
name = association[:name]
|
4
|
-
collection = MerbAdmin::AbstractModel.new(association[:child_model]).
|
5
|
-
selected =
|
6
|
-
label = association[:pretty_name]
|
4
|
+
collection = MerbAdmin::AbstractModel.new(association[:child_model]).all.map{|o| [o.id, object_title(o)]}.sort_by{|o| o[1]}
|
5
|
+
selected = @object.send(association[:name])
|
6
|
+
label = association[:pretty_name]
|
7
7
|
required = false
|
8
8
|
@properties.each do |property|
|
9
9
|
next unless property[:name] == child_key
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<%
|
2
|
+
name = property[:name]
|
3
|
+
value = @object.send(name)
|
4
|
+
label = property[:pretty_name]
|
5
|
+
required = !property[:nullable?]
|
6
|
+
%>
|
7
|
+
<div>
|
8
|
+
<%= text_field(name, :class => "vDateField", :value => value.respond_to?(:strftime) ? value.strftime("%Y-%m-%d %H:%M:%S") : nil, :label => label) %>
|
9
|
+
<p class="help">
|
10
|
+
<%= required ? "Required." : "Optional." %>
|
11
|
+
</p>
|
12
|
+
</div>
|
@@ -1,10 +1,10 @@
|
|
1
|
-
<p>Are you sure you want to delete the <%= @abstract_model.pretty_name %>? All of the following related items will be deleted:</p>
|
1
|
+
<p>Are you sure you want to delete the <%= @abstract_model.pretty_name.downcase %>? All of the following related items will be deleted:</p>
|
2
2
|
<ul>
|
3
3
|
<li>
|
4
|
-
<%= link_to(@model_name,
|
4
|
+
<%= link_to(@model_name, url(:admin_edit, :model_name => @abstract_model.singular_name, :id => @object.id))%>
|
5
5
|
</li>
|
6
6
|
</ul>
|
7
|
-
<%= form_for(@object, :action =>
|
7
|
+
<%= form_for(@object, :action => url(:admin_destroy, :model_name => @abstract_model.singular_name, :id => @object.id), :method => :delete) do %>
|
8
8
|
<div>
|
9
9
|
<%= submit "Yes, I'm sure" %>
|
10
10
|
</div>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<div id="content-main">
|
2
|
-
<%= form_for(@object, :action =>
|
2
|
+
<%= form_for(@object, :action => url(:admin_update, :model_name => @abstract_model.singular_name, :id => @object.id)) do %>
|
3
3
|
<div>
|
4
4
|
<%= partial('properties', :properties => @properties) -%>
|
5
5
|
<% @abstract_model.belongs_to_associations.each do |association| %>
|
@@ -14,7 +14,7 @@
|
|
14
14
|
<div class="submit-row" >
|
15
15
|
<%= submit "Save", :class => "default", :name => "_save" %>
|
16
16
|
<p class="deletelink-box">
|
17
|
-
<%= link_to("Delete",
|
17
|
+
<%= link_to("Delete", url(:admin_delete, :model_name => @abstract_model.singular_name, :id => @object.id), :class => "deletelink") %>
|
18
18
|
</p>
|
19
19
|
<%= submit "Save and add another", :name => "_add_another" %>
|
20
20
|
<%= submit "Save and continue editing", :name => "_continue" %>
|
@@ -2,18 +2,18 @@
|
|
2
2
|
<div class="module">
|
3
3
|
<table summary="Models available in the application.">
|
4
4
|
<caption>
|
5
|
-
<%= link_to("Models",
|
5
|
+
<%= link_to("Models", url(:admin_dashboard), :class => "section") %>
|
6
6
|
</caption>
|
7
7
|
<% @abstract_models.each do |abstract_model| %>
|
8
8
|
<tr>
|
9
9
|
<th scope="row">
|
10
|
-
<%= link_to(abstract_model.plural_name.to_s.capitalize,
|
10
|
+
<%= link_to(abstract_model.plural_name.to_s.capitalize, url(:admin_list, :model_name => abstract_model.singular_name)) %>
|
11
11
|
</th>
|
12
12
|
<td>
|
13
|
-
<%= link_to("Add",
|
13
|
+
<%= link_to("Add", url(:admin_new, :model_name => abstract_model.singular_name), :class => "addlink") %>
|
14
14
|
</td>
|
15
15
|
<td>
|
16
|
-
<%= link_to("Edit",
|
16
|
+
<%= link_to("Edit", url(:admin_list, :model_name => abstract_model.singular_name), :class => "changelink") %>
|
17
17
|
</td>
|
18
18
|
</tr>
|
19
19
|
<% end %>
|
@@ -1,78 +1,21 @@
|
|
1
1
|
<%
|
2
2
|
params = request.params.except(:action, :controller, :model_name)
|
3
|
-
filter = params[:filter]
|
4
|
-
query = params[:query]
|
5
|
-
sort = params[:sort]
|
6
|
-
sort_reverse = params[:sort_reverse]
|
7
3
|
%>
|
8
4
|
<div id="content-main">
|
9
5
|
<ul class="object-tools">
|
10
6
|
<li>
|
11
|
-
<%= link_to("Add #{@abstract_model.pretty_name}",
|
7
|
+
<%= link_to("Add #{@abstract_model.pretty_name.downcase}", url(:admin_new, :model_name => @abstract_model.singular_name), :class => "addlink") %>
|
12
8
|
</li>
|
13
9
|
</ul>
|
14
|
-
<div class="module
|
15
|
-
<div id="toolbar">
|
16
|
-
<form id="changelist-search" action="" method="get">
|
17
|
-
<div>
|
18
|
-
<label for="searchbar"><img src="<%= image_path("icon_searchbox.png") %>" alt="Search" /></label>
|
19
|
-
<input type="text" size="40" name="query" value="" id="searchbar" />
|
20
|
-
<input type="submit" value="Search" />
|
21
|
-
<% if filter || query %>
|
22
|
-
<span class="small quiet"><%= @record_count %> <%= @record_count == 1 ? "result" : "results" %> (<a href="?"><%= @abstract_model.count %> total</a>)</span>
|
23
|
-
<% end %>
|
24
|
-
<% if filter %>
|
25
|
-
<% filter.each do |name, value| %>
|
26
|
-
<input type="hidden" name="filter[<%= name %>]" value="<%= value %>"/>
|
27
|
-
<% end %>
|
28
|
-
<% end %>
|
29
|
-
</div>
|
30
|
-
</form>
|
31
|
-
</div>
|
32
|
-
<script type="text/javascript">document.getElementById("searchbar").focus();</script>
|
33
|
-
<div id="changelist-filter">
|
34
|
-
<h2>Filter</h2>
|
35
|
-
<% @properties.each do |property| %>
|
36
|
-
<% type = property[:type] %>
|
37
|
-
<% name = property[:name] %>
|
38
|
-
<% pretty_name = property[:pretty_name] %>
|
39
|
-
<% flag_map = property[:flag_map] %>
|
40
|
-
<% if type == :boolean %>
|
41
|
-
<h3>By <%= pretty_name %></h3>
|
42
|
-
<ul>
|
43
|
-
<li class="<%= filter.nil? || filter[name].blank? ? "selected" : nil %>">
|
44
|
-
<a href="?<%= Merb::Parse.params_to_query_string(params.merge(:filter => (filter || {}).reject{|key, value| key.to_sym == name})) %>">All</a>
|
45
|
-
</li>
|
46
|
-
<li class="<%= filter && filter[name] == "true" ? "selected" : nil %>">
|
47
|
-
<a href="?<%= Merb::Parse.params_to_query_string(params.merge(:filter => (filter || {}).merge({name => "true"}))) %>">Yes</a>
|
48
|
-
</li>
|
49
|
-
<li class="<%= filter && filter[name] == "false" ? "selected" : nil %>">
|
50
|
-
<a href="?<%= Merb::Parse.params_to_query_string(params.merge(:filter => (filter || {}).merge({name => "false"}))) %>">No</a>
|
51
|
-
</li>
|
52
|
-
</ul>
|
53
|
-
<% elsif type == :integer && flag_map %>
|
54
|
-
<h3>By <%= pretty_name %></h3>
|
55
|
-
<ul>
|
56
|
-
<li class="<%= filter.nil? || filter[name].blank? ? "selected" : nil %>">
|
57
|
-
<a href="?<%= Merb::Parse.params_to_query_string(params.merge(:filter => (filter || {}).reject{|key, value| key.to_sym == name})) %>">All</a>
|
58
|
-
</li>
|
59
|
-
<% flag_map.values.map{|v| v.to_s}.sort.each do |value| %>
|
60
|
-
<li class="<%= filter && filter[name] == value ? "selected" : nil %>">
|
61
|
-
<a href="?<%= Merb::Parse.params_to_query_string(params.merge(:filter => (filter || {}).merge({name => value}))) %>"><%= value.capitalize.gsub('_', ' ')%></a>
|
62
|
-
</li>
|
63
|
-
<% end %>
|
64
|
-
</ul>
|
65
|
-
<% end %>
|
66
|
-
<% end %>
|
67
|
-
</div>
|
10
|
+
<div class="module" id="changelist">
|
68
11
|
<table cellspacing="0">
|
69
12
|
<thead>
|
70
13
|
<tr>
|
71
14
|
<% @properties.each do |property| %>
|
72
15
|
<% name = property[:name] %>
|
73
16
|
<% pretty_name = property[:pretty_name] %>
|
74
|
-
<th
|
75
|
-
|
17
|
+
<th>
|
18
|
+
<%= pretty_name %>
|
76
19
|
</th>
|
77
20
|
<% end %>
|
78
21
|
</tr>
|
@@ -84,7 +27,7 @@
|
|
84
27
|
<% type = property[:type] %>
|
85
28
|
<% name = property[:name] %>
|
86
29
|
<td>
|
87
|
-
<a href="<%=
|
30
|
+
<a href="<%= url(:admin_edit, :model_name => @abstract_model.singular_name, :id => object.id) %>">
|
88
31
|
<% case type %>
|
89
32
|
<% when :boolean %>
|
90
33
|
<% if object.send(name) == true %>
|
@@ -119,7 +62,7 @@
|
|
119
62
|
<% if @page_count.to_i > 1 %>
|
120
63
|
<%= paginate(@current_page, @page_count, :url => '?' + Merb::Parse.params_to_query_string(params)) %>
|
121
64
|
<% end %>
|
122
|
-
<%= @record_count %> <%= @record_count == 1 ? @abstract_model.pretty_name : @abstract_model.pretty_name.pluralize %>
|
65
|
+
<%= @record_count %> <%= @record_count == 1 ? @abstract_model.pretty_name.downcase : @abstract_model.pretty_name.downcase.pluralize %>
|
123
66
|
<% if @page_count.to_i == 2 %>
|
124
67
|
<%= link_to("Show all", '?' + Merb::Parse.params_to_query_string(params.merge(:all => true)), :class => "showall") %>
|
125
68
|
<% end %>
|
data/app/views/main/new.html.erb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
<div id="content-main">
|
2
|
-
<%= form_for(@object, :action =>
|
2
|
+
<%= form_for(@object, :action => url(:admin_create, :model_name => @abstract_model.singular_name)) do %>
|
3
3
|
<div>
|
4
4
|
<%= partial('properties', :properties => @properties) -%>
|
5
5
|
<% @abstract_model.belongs_to_associations.each do |association| %>
|
data/lib/abstract_model.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'generic_support'
|
2
|
+
require 'activerecord_support'
|
2
3
|
require 'datamapper_support'
|
3
4
|
|
4
5
|
module MerbAdmin
|
@@ -8,6 +9,15 @@ module MerbAdmin
|
|
8
9
|
return @models if @models
|
9
10
|
@models ||= []
|
10
11
|
case Merb.orm
|
12
|
+
when :activerecord
|
13
|
+
Dir.glob(Merb.dir_for(:model) / Merb.glob_for(:model)).each do |filename|
|
14
|
+
# FIXME: This heuristic for finding ActiveRecord models is too strict
|
15
|
+
File.read(filename).scan(/^class ([\w\d_\-:]+) < ActiveRecord::Base$/).flatten.each do |m|
|
16
|
+
model = lookup(m.to_s.to_sym)
|
17
|
+
@models << new(model) if model
|
18
|
+
end
|
19
|
+
end
|
20
|
+
@models.sort!{|a, b| a.model.to_s <=> b.model.to_s}
|
11
21
|
when :datamapper
|
12
22
|
DataMapper::Resource.descendants.each do |m|
|
13
23
|
# Remove DataMapperSessionStore because it's included by default
|
@@ -17,29 +27,40 @@ module MerbAdmin
|
|
17
27
|
end
|
18
28
|
@models.sort!{|a, b| a.model.to_s <=> b.model.to_s}
|
19
29
|
else
|
20
|
-
raise "MerbAdmin does not
|
30
|
+
raise "MerbAdmin does not support the #{Merb.orm} ORM"
|
21
31
|
end
|
22
32
|
end
|
23
33
|
|
24
34
|
# Given a symbol +model_name+, finds the corresponding model class
|
25
35
|
def self.lookup(model_name)
|
26
|
-
|
27
|
-
|
28
|
-
|
36
|
+
begin
|
37
|
+
model = const_get(model_name)
|
38
|
+
rescue NameError
|
39
|
+
raise "MerbAdmin could not find model #{model_name}"
|
40
|
+
end
|
41
|
+
|
42
|
+
case Merb.orm
|
43
|
+
when :activerecord
|
44
|
+
return model if model.superclass == ActiveRecord::Base
|
45
|
+
when :datamapper
|
46
|
+
return model if model.include?(DataMapper::Resource)
|
47
|
+
end
|
29
48
|
nil
|
30
49
|
end
|
31
50
|
|
32
51
|
attr_accessor :model
|
33
52
|
|
34
53
|
def initialize(model)
|
35
|
-
model = self.class.lookup(model.camel_case
|
54
|
+
model = self.class.lookup(model.to_s.camel_case) unless model.is_a?(Class)
|
36
55
|
@model = model
|
37
56
|
self.extend(GenericSupport)
|
38
57
|
case Merb.orm
|
58
|
+
when :activerecord
|
59
|
+
self.extend(ActiverecordSupport)
|
39
60
|
when :datamapper
|
40
61
|
self.extend(DatamapperSupport)
|
41
62
|
else
|
42
|
-
raise "MerbAdmin does not
|
63
|
+
raise "MerbAdmin does not support the #{Merb.orm} ORM"
|
43
64
|
end
|
44
65
|
end
|
45
66
|
end
|