public
Description: A gem to provide free scaffolding for all models
Homepage: http://fightinjoe.com
Clone URL: git://github.com/fightinjoe/merb-autoscaffold.git
Added support for ActiveRecord
Aaron Wheeler (author)
Wed May 21 06:02:36 -0700 2008
commit  e404861f3ef619b5d810678e0ef12e74cf2f221c
tree    eb456b63d85a746f964d75850cfbf5c6ad5da72e
parent  996637d92c8a863aac9c0dd80e021bc273b12ce6
...
 
 
 
 
1
2
3
...
1
2
3
4
5
6
7
0
@@ -1,3 +1,7 @@
0
+0.2.0
0
+ - Controller and View tests
0
+ - Support for DataMapper 0.3.0 and ActiveRecord
0
+
0
 0.1.2
0
  - Support added for habtm relationships
0
  - New Merbivore-styled layout
0
...
2
3
4
5
 
 
6
7
8
...
51
52
53
54
 
55
56
57
...
2
3
4
 
5
6
7
8
9
...
52
53
54
 
55
56
57
58
0
@@ -2,7 +2,8 @@ merb_autoscaffold
0
 =================
0
 
0
 Merb AutoScaffold is a Merb plugin that provides scaffolding for free
0
-for all models.
0
+for all models. Merb AutoScaffold currently works with DataMapper 0.3
0
+and ActiveRecord.
0
 
0
 ==== Usage:
0
 
0
@@ -51,6 +52,6 @@ end
0
 
0
 ==== Caveats
0
 
0
-Currently, autoscaffolds only work with DataMapper 0.3 models.
0
+Currently, autoscaffolds only work with DataMapper 0.3 and ActiveRecord models.
0
 
0
 Autoscaffolds also will not work with flat Merb apps.
0
\ No newline at end of file
...
58
59
60
61
 
62
63
64
...
68
69
70
71
 
72
73
74
...
89
90
91
92
 
93
94
95
...
100
101
102
103
 
104
105
106
...
122
123
124
125
 
126
127
128
 
129
130
131
...
142
143
144
145
 
146
147
 
148
149
150
...
168
169
170
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
172
173
174
 
175
176
177
 
178
179
180
...
58
59
60
 
61
62
63
64
...
68
69
70
 
71
72
73
74
...
89
90
91
 
92
93
94
95
...
100
101
102
 
103
104
105
106
...
122
123
124
 
125
126
127
 
128
129
130
131
...
142
143
144
 
145
146
 
147
148
149
150
...
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
 
204
 
205
206
207
 
208
209
210
211
0
@@ -58,7 +58,7 @@ module MerbAutoScaffold
0
           else
0
             def index
0
               @models = Paginator.new( self.class.Model.count, 20) do |offset, per_page|
0
- self.class.Model.all(:limit => per_page, :offset => offset)
0
+ find_all( self.class.Model, :limit => per_page, :offset => offset )
0
               end
0
               render
0
             end
0
@@ -68,7 +68,7 @@ module MerbAutoScaffold
0
             native_actions << 'show'
0
           else
0
             def show
0
- @model = self.class.Model.first(params[:id])
0
+ @model = find_first( self.class.Model, params[:id] )
0
               raise NotFound unless @model
0
               display @model
0
             end
0
@@ -89,7 +89,7 @@ module MerbAutoScaffold
0
           else
0
             def edit
0
               only_provides :html
0
- @model = self.class.Model.first(params[:id])
0
+ @model = find_first( self.class.Model, params[:id] )
0
               raise NotFound unless @model
0
               render
0
             end
0
@@ -100,7 +100,7 @@ module MerbAutoScaffold
0
             native_actions << 'create'
0
           else
0
             def create
0
- associations = scaf_has_manys.collect { |a|
0
+ associations = self.class.Model.scaf_has_manys.collect { |a|
0
                 [ a, params['model'].delete( a.name ) ]
0
               }
0
 
0
@@ -122,10 +122,10 @@ module MerbAutoScaffold
0
             def update
0
               params[:model].each { |k,v| params[:model][k] = nil if v.blank? }
0
 
0
- @model = self.class.Model.first(params[:id])
0
+ @model = find_first( self.class.Model, params[:id] )
0
               raise NotFound unless @model
0
 
0
- associations = scaf_has_manys.collect { |a|
0
+ associations = self.class.Model.scaf_has_manys.collect { |a|
0
                 [ a, params['model'].delete( a.name ) ]
0
               }
0
 
0
@@ -142,9 +142,9 @@ module MerbAutoScaffold
0
             native_actions << 'destroy'
0
           else
0
             def destroy
0
- @model = self.class.Model.first(params[:id])
0
+ @model = find_first( self.class.Model, params[:id] )
0
               raise NotFound unless @model
0
- if @model.destroy!
0
+ if delete( @model )
0
                 redirect url( "scaffold_#{self.class.Model.plural_name}" )
0
               else
0
                 raise BadRequest
0
@@ -168,13 +168,44 @@ module MerbAutoScaffold
0
             end
0
           end
0
 
0
+ def find_first( klass, *params )
0
+ # wanted to use klass.superclass here, but the case statment seems to be checking the
0
+ # class of klass.superclass instead of an equality check
0
+ case klass.new
0
+ when ActiveRecord::Base then return klass.find(:first, *params)
0
+ when DataMapper::Base then return klass.first( *params )
0
+ end
0
+ end
0
+
0
+ def find_all( klass, *params )
0
+ case klass.new
0
+ when ActiveRecord::Base then return klass.find(:all, *params)
0
+ when DataMapper::Base then return klass.all( *params )
0
+ end
0
+ end
0
+
0
+ def delete( obj )
0
+ case obj
0
+ when ActiveRecord::Base then return obj.destroy
0
+ when DataMapper::Base then return obj.destroy!
0
+ end
0
+ end
0
+
0
+ def clear_association( object, assoc )
0
+ rel = object.send( assoc.name )
0
+ case object
0
+ when ActiveRecord::Base then rel.clear
0
+ when DataMapper::Base then rel.nullify_association
0
+ end
0
+ rel
0
+ end
0
+
0
           def update_has_many_association( assoc, model, ids )
0
- rel = model.send( assoc.name )
0
             # remove all of the associated items
0
- rel.nullify_association
0
+ rel = clear_association( model, assoc )
0
 
0
             # add all of the objects to the relationship
0
- for obj in assoc.associated_table.klass.all( :id.in => ids )
0
+ for obj in find_all( assoc.klass, :conditions => ['id in (?)', ids] )
0
               rel << obj
0
             end
0
             model.save
...
1
 
2
3
4
...
16
17
18
19
 
 
 
 
 
 
 
 
 
20
21
22
...
 
1
2
3
4
...
16
17
18
 
19
20
21
22
23
24
25
26
27
28
29
30
0
@@ -1,4 +1,4 @@
0
-require File.join( File.dirname(__FILE__), 'orms', 'datamapper' )
0
+%w(datamapper activerecord).each { |r| require File.join( File.dirname(__FILE__), 'orms', r ) }
0
 
0
 module MerbAutoScaffold
0
   class Models
0
@@ -16,7 +16,15 @@ module MerbAutoScaffold
0
             def self.singular_name() self.to_s.snake_case.to_sym; end
0
             def self.plural_name() self.to_s.snake_case.pluralize.to_sym; end
0
           }
0
- model.meta_eval { include MerbAutoScaffold::ORMs::DataMapper }
0
+ extension = case model.new
0
+ # wanted to use klass.superclass here, but the case statment seems to be checking the
0
+ # class of klass.superclass instead of an equality check
0
+ when ActiveRecord::Base then MerbAutoScaffold::ORMs::ActiveRecord
0
+ when DataMapper::Base then MerbAutoScaffold::ORMs::DataMapper
0
+ else raise "Merb AutoScaffold does not currently support the #{ model.class.superclass } ORM"
0
+ end
0
+
0
+ model.meta_eval { include extension }
0
           @models << model
0
         end
0
       }
...
1
2
3
4
5
6
7
 
 
 
 
8
9
10
...
25
26
27
 
 
 
 
 
 
 
 
 
 
 
28
29
30
31
...
1
2
3
 
4
5
6
7
8
9
10
11
12
13
...
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
0
@@ -1,10 +1,13 @@
0
 module MerbAutoScaffold
0
 module ORMs
0
 module DataMapper
0
- def scaf_table() database.schema[ self ]; end
0
   def scaf_columns() scaf_table.columns; end
0
   def scaf_assocs() scaf_table.associations; end
0
 
0
+ def scaf_serial_columns
0
+ scaf_columns.select { |c| c.options[:serial] }
0
+ end
0
+
0
   def scaf_has_manys
0
     scaf_assocs.select { |a|
0
       a.is_a?(::DataMapper::Associations::HasManyAssociation) ||
0
@@ -25,6 +28,17 @@ module DataMapper
0
   def scaf_foreign_keys
0
     scaf_belongs_tos.collect(&:foreign_key_name)
0
   end
0
+
0
+ def scaf_foreign_key_name( assoc )
0
+ assoc.foreign_key_name
0
+ end
0
+
0
+ def scaf_find_all_available_items_to_association( assoc )
0
+ assoc.associated_table.klass.all
0
+ end
0
+
0
+ private
0
+ def scaf_table() database.schema[ self ]; end
0
 end
0
 end
0
 end
0
\ No newline at end of file
...
6
7
8
 
9
10
11
 
 
12
13
14
 
15
16
17
...
6
7
8
9
10
 
 
11
12
13
14
 
15
16
17
18
0
@@ -6,12 +6,13 @@
0
   #
0
   # association<DataMapper::Associations::BelongsToAssociation> - the association to display
0
   # model<DataMapper::Base> - the model which belongs to the object being selected
0
+ foreign_key = model.class.scaf_foreign_key_name( association )
0
 %>
0
-<select name="model[<%= association.foreign_key_name %>]">
0
- <% selected_value = model.send( association.foreign_key_name ) %>
0
+<select name="model[<%= foreign_key %>]">
0
+ <% selected_value = model.send( foreign_key ) %>
0
 
0
   <option value=""></option>
0
- <% for obj in association.constant.all %>
0
+ <% for obj in find_all( association.klass ) %>
0
     <option value="<%= obj.id %>"<%= ' selected="selected"' if obj.id == selected_value %>>
0
       <%= obj.try(:title) || obj.try(:name) || "#{ obj.class.to_s } ##{ obj.id }" %>
0
     </option>
...
1
2
3
4
 
 
 
 
 
5
6
7
8
9
 
10
11
12
...
1
2
3
 
4
5
6
7
8
9
10
11
12
 
13
14
15
16
0
@@ -1,12 +1,16 @@
0
 <dl>
0
   <% model.class.scaf_columns.each do |column| %>
0
 
0
- <% next if model.class.scaf_foreign_keys.include?( column.name ) %>
0
+ <%
0
+ # Do not display a form field for a foreign key. Instead,
0
+ # display a select option below.
0
+ next if model.class.scaf_foreign_keys.include?( column.name )
0
+ %>
0
 
0
     <dt><%= column.name %></dt>
0
     <dd>
0
 
0
- <% if column.options[:serial] %>
0
+ <% if model.class.scaf_serial_columns.include?( column ) %>
0
         <%= model.send( column.name ) || '&nbsp' %>
0
 
0
       <% else %>
...
12
13
14
15
 
16
17
18
...
12
13
14
 
15
16
17
18
0
@@ -12,7 +12,7 @@
0
 <dt><%= association.name.to_s.capitalize %></dt>
0
 <dd>
0
   <select name="model[<%= association.name %>][]" multiple="multiple">
0
- <% for obj in association.associated_table.klass.all %>
0
+ <% for obj in model.class.scaf_find_all_available_items_to_association( association ) %>
0
       <option value="<%= obj.id %>"<%= ' selected="selected"' if model.send( association.name ).include?( obj ) %>>
0
         <%= scaf_title( obj ) %>
0
       </option>
...
6
7
8
9
 
10
11
12
...
6
7
8
 
9
10
11
12
0
@@ -6,7 +6,7 @@
0
     <a href="<%= url( "scaffold_#{self.class.Model.singular_name}", @model ) %>">Cancel</a>
0
   </h2>
0
 
0
- <form action="<%= url( "scaffold_#{self.class.Model.singular_name}", @model ) %>" method="POST">
0
+ <form action="<%= url( "scaffold_#{self.class.Model.singular_name}", @model.id ) %>" method="POST">
0
     <input type="hidden" name="_method" value="PUT" />
0
     <%= partial( 'form', :model => @model ) %>
0
     <input type="submit" value="Update" />
...
13
14
15
16
 
17
18
19
20
 
21
22
23
...
13
14
15
 
16
17
18
19
 
20
21
22
23
0
@@ -13,11 +13,11 @@
0
   </h2>
0
 
0
   <dl>
0
- <% @model.class.scaf_table.columns.each do |column| %>
0
+ <% @model.class.scaf_columns.each do |column| %>
0
       <dt><%= column.name %></dt>
0
       <dd>
0
         <% if association = @model.class.scaf_assoc_hash[column.name] %>
0
- <% obj = association.constant.get( @model.send( column.name ) ) %>
0
+ <% obj = find_first( association.klass, @model.send( column.name ) ) %>
0
           <%= scaf_link( obj ) unless obj.blank? %>
0
         <% else %>
0
           <%= @model.send( column.name ) || '&nbsp;' %>

Comments

    No one has commented yet.