scaffolding_extensions 1.3.12 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -29,6 +29,7 @@ Scaffolding Extensions currently supports:
29
29
  * Object Relational Mappers
30
30
  * ActiveRecord 2.3.5
31
31
  * Sequel 3.8.0
32
+ * DataMapper 0.10.2 (see doc/datamapper.txt for details)
32
33
  * Javascript Libaries (used for Ajax/Autocompleting)
33
34
  * Prototype 1.6.0.3
34
35
  * JQuery 1.2.3
@@ -37,17 +38,11 @@ Support for other web frameworks and ORMs can be added, see the
37
38
  controller_spec.txt and model_spec.txt files for the methods that need to be
38
39
  defined.
39
40
 
40
- The current version of Scaffolding Extensions is quite different from older
41
- versions (svn revision 89 and previous). Older versions of Rails should be
42
- able to use an older version of the plugin, which won't be discussed further as
43
- it is substantially different from the current version (see the conversion.txt
44
- file for details).
45
-
46
41
  You can get Scaffolding Extensions via git or as a gem:
47
42
 
48
43
  * git: git://github.com/jeremyevans/scaffolding_extensions.git
49
44
  * gem: sudo gem install scaffolding_extensions
50
- * demo: http://scaffolding-extensions.jeremyevans.net
45
+ * demo: http://se-demo.heroku.com
51
46
  * github: http://github.com/jeremyevans/scaffolding_extensions
52
47
  * RDoc: http://scaffolding-ext.rubyforge.org
53
48
  * Bug Tracker: http://rubyforge.org/tracker/?atid=22169&group_id=5726&func=browse
@@ -0,0 +1,20 @@
1
+ The DataMapper module has some quirks, mainly:
2
+
3
+ 1. For models that have the "storage_name" explicitly defined,
4
+ the "has n, :through => Resource" relation doesn't work well.
5
+ Don't use models, that have non-standard table names, or
6
+ create the habtm resource by hand (check the test application)
7
+
8
+ 2. Because DataMapper uses a module instead of a superclass, you have
9
+ to add the appropriate scaffolding_extensions modules by hand.
10
+ The simplest way is to use the `add_scaffolding_methods` method in
11
+ your controller, or initialization script:
12
+
13
+ class Dm < Merb::Controller
14
+ add_scaffolding_methods [DmOfficer, DmMeeting, DmEmployee, DmGroup, DmPosition]
15
+ scaffold DmOfficer
16
+ scaffold DmMeeting
17
+ scaffold_all_models :only =>[DmEmployee, DmGroup, DmPosition]
18
+ end
19
+
20
+ You need dm-core, dm-validations, and do_sqlite3 in order to run the test_suite for scaffolding_extensions with datamapper.
@@ -0,0 +1,300 @@
1
+ require 'pp'
2
+
3
+ ScaffoldingExtensions::MODEL_SUPERCLASSES << DataMapper::Resource
4
+
5
+ def get_key_array_safe(key)
6
+ if key.is_a?(Array) then
7
+ if key.length==1
8
+ key.first
9
+ else
10
+ key
11
+ end
12
+ else
13
+ key
14
+ end
15
+ end
16
+
17
+ def get_ordering_options(ordopts)
18
+ result = []
19
+ if ordopts then
20
+ ordering = ordopts.dup
21
+ else
22
+ return nil
23
+ end
24
+ ordering = ordering.split(',') unless ordering.is_a?(Array)
25
+ ordering.each do |ord|
26
+ asc = :asc
27
+ if ord.upcase =~ /DESC/
28
+ asc = :desc
29
+ end
30
+ ord.gsub!(/[Dd][Ee][Ss][Cc]|[Aa][Ss][Cc]/,"")
31
+ ord.strip!
32
+ if ord =~ /(\w+)\.(\w+)/
33
+ tablename = $1
34
+ propertyname = $2
35
+ #TODO handling of associated orderings
36
+ #optionshash[:order] << DataMapper::Query::Direction.new(eval("#{tablename.downcase.gsub(/\b[a-z]/) { |a| a.upcase }.gsub(/\s/, "")
37
+ #}.properties[:#{propertyname.downcase}]"),asc)
38
+ result << eval(":#{propertyname}.#{asc.to_s}")
39
+ elsif ord =~ /(\w+)/
40
+ propertyname = $1
41
+ result << eval(":#{propertyname}.#{asc.to_s}")
42
+ else
43
+ # TODO Warning message
44
+ end
45
+ end
46
+ result
47
+ end
48
+
49
+ # Instance methods added to DataMapper::Resource to allow it to work with Scaffolding Extensions.
50
+ module ScaffoldingExtensions::DataMapper
51
+ # Get value for given attribute
52
+ def scaffold_attribute_value(field)
53
+ self[field]
54
+ end
55
+
56
+ # the value of the primary key for this object
57
+ def scaffold_id
58
+ get_key_array_safe(self.key)
59
+ end
60
+ end
61
+
62
+ # Class methods added to DataMapper::Resource to allow it to work with Scaffolding Extensions.
63
+ module ScaffoldingExtensions::MetaDataMapper
64
+ SCAFFOLD_OPTIONS = ::ScaffoldingExtensions::MetaModel::SCAFFOLD_OPTIONS
65
+
66
+ # Add the associated object to the object's association
67
+ def scaffold_add_associated_object(association, object, associated_object)
68
+ ap = object.send(association)
69
+ ap << associated_object unless ap.include?(associated_object)
70
+ object.save
71
+ end
72
+
73
+ # Array of all association reflections for this model
74
+ # only shows the associations that are scaffolding_enabled
75
+ def scaffold_all_associations
76
+ relationships.values.select { |v|
77
+ v.send(:target_model).respond_to?(:scaffold_name)
78
+ }
79
+ end
80
+
81
+ # The class that this model is associated with via the association
82
+ def scaffold_associated_class(association)
83
+ relationships[association].target_model
84
+ end
85
+
86
+ # The association reflection for this association
87
+ def scaffold_association(association)
88
+ relationships[association]
89
+ end
90
+
91
+ # The type of association, either :new for :one_to_many (as you can create new objects
92
+ # associated with the current object), :edit for :many_to_many (since you
93
+ # can edit the list of associated objects), or :one for :many_to_one.
94
+ def scaffold_association_type(association)
95
+ if relationships[association].class == DataMapper::Associations::OneToMany::Relationship
96
+ :new
97
+ elsif relationships[association].class == DataMapper::Associations::ManyToMany::Relationship
98
+ :edit
99
+ else
100
+ :one
101
+ end
102
+ end
103
+
104
+ # List of symbols for associations to display on the scaffolded edit page. Defaults to
105
+ # all associations for which the scaffolding is enabled. Can be set with an instance variable.
106
+ def scaffold_associations
107
+ @scaffold_associations ||= relationships.keys.select { |v|
108
+ relationships[v].send(:target_model).respond_to?(:scaffold_name)
109
+ }
110
+ end
111
+
112
+ # Destroys the object
113
+ def scaffold_destroy(object)
114
+ object.destroy
115
+ end
116
+
117
+ # The error to raise, should match other errors raised by the underlying library.
118
+ def scaffold_error_raised
119
+ DataMapper::ObjectNotFoundError
120
+ end
121
+
122
+ # Returns the list of fields to display on the scaffolded forms. Defaults
123
+ # to displaying all columns with the exception of the primary key column.
124
+ # Also includes :many_to_one associations, replacing
125
+ # the foriegn keys with the association itself. Can be set with an instance variable.
126
+ def scaffold_fields(action = :default)
127
+ return @scaffold_fields if @scaffold_fields
128
+ fields = (properties.map {|a| a.name}) - [scaffold_primary_key]
129
+ scaffold_all_associations.each do |reflection|
130
+ next unless reflection.class == DataMapper::Associations::ManyToOne::Relationship
131
+ fields.delete(get_key_array_safe(reflection.send(:child_key)).name)
132
+ fields.push(reflection.name)
133
+ end
134
+ @scaffold_fields = fields.sort_by{|f| f.to_s}
135
+ end
136
+
137
+ # The foreign key for the given reflection
138
+ def scaffold_foreign_key(reflection)
139
+ get_key_array_safe(reflection.child_key).name
140
+ end
141
+
142
+ # Retrieve a single model object given an id
143
+ def scaffold_get_object(id)
144
+ self.get(id) || (raise scaffold_error_raised)
145
+ end
146
+
147
+ # All objects that are currently associated with the given object. This method does not
148
+ # check that the returned associated objects meet the associated class's scaffold_session_value
149
+ # constraint, as it is assumed that all objects currently assocated with the given object
150
+ # have already met the criteria. If that is not the case, you should override this method.
151
+ def scaffold_associated_objects(association, object, options)
152
+ object.send(association,:order => get_ordering_options(scaffold_select_order_association(association)))
153
+ end
154
+
155
+ # Retrieve multiple objects given a hash of options
156
+ def scaffold_get_objects(options)
157
+ optionshash = {}
158
+ data = self.all
159
+ if options[:conditions]
160
+ conditions = options[:conditions]
161
+ if conditions && Array === conditions && conditions.length > 0
162
+ if String === conditions[0]
163
+ data = data.all(:conditions => conditions)
164
+ else
165
+ conditions.each do |cond|
166
+ next if cond.nil?
167
+ data = case cond
168
+ when Hash, String then data.all(:conditions => [cond.gsub("NULL","?"),nil])
169
+ when Array then
170
+ if cond.length==1
171
+ data.all(:conditions => [cond[0].gsub("NULL","?"),nil])
172
+ else
173
+ data.all(:conditions => cond)
174
+ end
175
+ when Proc then data.all(&cond)
176
+ end
177
+ end
178
+ end
179
+ end
180
+ end
181
+ slice = nil
182
+ if options[:limit]
183
+ startpos = options[:offset] || 0
184
+ endpos = options[:limit]
185
+ slice = [startpos,endpos]
186
+ end
187
+ # TODO includes break SQL generation
188
+ # optionshash[:links] = options[:include] if options[:include]
189
+ # optionshash[:links] = [optionshash[:links]] unless optionshash[:links].is_a?(Array)
190
+ if options[:order] then
191
+ optionshash[:order] = get_ordering_options(options[:order])
192
+ end
193
+ if slice then
194
+ q = data.all(optionshash).slice(*slice)
195
+ else
196
+ q = data.all(optionshash)
197
+ end
198
+ #p repository.adapter.send("select_statement",q.query)
199
+ q.to_a
200
+ end
201
+
202
+ # Return the class, left foreign key, right foreign key, and join table for this habtm association
203
+ def scaffold_habtm_reflection_options(association)
204
+ habtm = relationships[association]
205
+ [
206
+ habtm.target_model,
207
+ get_key_array_safe(habtm.through.child_key).name,
208
+ get_key_array_safe(habtm.via.child_key).name,
209
+ habtm.send(:through_model).storage_name
210
+ ]
211
+ end
212
+
213
+ # Returns a hash of values to be used as url parameters on the link to create a new
214
+ # :has_many associated object. Defaults to setting the foreign key field to the
215
+ # record's primary key.
216
+ def scaffold_new_associated_object_values(association, record)
217
+ {scaffold_foreign_key(scaffold_association(association))=>record.scaffold_id}
218
+ end
219
+
220
+ # The primary key for the given table
221
+ def scaffold_primary_key
222
+ get_key_array_safe(key).name
223
+ end
224
+
225
+ # Saves the object.
226
+ def scaffold_save(action, object)
227
+ object.save
228
+ end
229
+
230
+ # The column type for the given table column, or nil if it isn't a table column
231
+ def scaffold_table_column_type(column)
232
+ column = self.properties[column]
233
+ if column then
234
+ if column.type == DataMapper::Types::Text
235
+ :text
236
+ else
237
+ column.type.to_s.split("::").last.downcase.intern
238
+ end
239
+ else
240
+ nil
241
+ end
242
+ end
243
+
244
+ # The name of the underlying table
245
+ def scaffold_table_name
246
+ storage_name
247
+ end
248
+
249
+ private
250
+ # Updates associated records for a given reflection and from record to point to the
251
+ # to record
252
+ def scaffold_reflection_merge(reflection, from, to)
253
+ if reflection.class == DataMapper::Associations::OneToMany::Relationship
254
+ foreign_key = get_key_array_safe(reflection.target_key).name
255
+ p reflection
256
+ p reflection.target_model
257
+ table = reflection.target_model
258
+ elsif reflection.class == DataMapper::Associations::ManyToMany::Relationship
259
+ foreign_key = get_key_array_safe(reflection.through.child_key).name
260
+ p reflection
261
+ table = reflection.send(:through_model)
262
+ p table
263
+ else
264
+ return
265
+ end
266
+ table.all(foreign_key => from).update(foreign_key => to)
267
+ end
268
+
269
+ # Remove the associated object from object's association
270
+ def scaffold_remove_associated_object(association, object, associated_object)
271
+ object.send(association).delete(associated_object)
272
+ object.save
273
+ end
274
+
275
+ # Set the object's attributes with the given attributes
276
+ def scaffold_set_attributes(object, attributes)
277
+ attributes.each do |k,v|
278
+ v = nil if v.empty? and (scaffold_table_column_type(k) == :boolean or scaffold_table_column_type(k) == :integer)
279
+ object.send("#{k}=", v)
280
+ end
281
+ end
282
+
283
+ end
284
+
285
+ def add_scaffolding_methods(classes)
286
+ unless classes.is_a?(Array)
287
+ classes = [classes]
288
+ end
289
+ classes.each do |cl|
290
+ cl.class_eval <<-ECLASS
291
+ SCAFFOLD_OPTIONS = ::ScaffoldingExtensions::MetaModel::SCAFFOLD_OPTIONS
292
+ include ScaffoldingExtensions::Model
293
+ include ScaffoldingExtensions::DataMapper
294
+ extend ScaffoldingExtensions::MetaModel
295
+ extend ScaffoldingExtensions::MetaDataMapper
296
+ extend ScaffoldingExtensions::Overridable
297
+ ECLASS
298
+ end
299
+ end
300
+
@@ -94,6 +94,9 @@ require 'scaffolding_extensions/controller/sinatra' if defined? Sinatra
94
94
  require 'scaffolding_extensions/controller/merb' if defined? Merb
95
95
 
96
96
  require 'scaffolding_extensions/model/active_record' if defined? ActiveRecord::Base
97
+ if defined? DataMapper::Resource
98
+ require 'scaffolding_extensions/model/datamapper'
99
+ end
97
100
  if defined? Sequel::Model
98
101
  require('sequel/extensions/inflector') unless [:singularize, :pluralize, :camelize, :underscore, :constantize].all?{|meth| "".respond_to?(meth)}
99
102
  require 'scaffolding_extensions/model/sequel'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scaffolding_extensions
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.12
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-01-04 00:00:00 -08:00
12
+ date: 2010-03-08 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -26,6 +26,7 @@ files:
26
26
  - README
27
27
  - lib/scaffolding_extensions/model/active_record.rb
28
28
  - lib/scaffolding_extensions/model/sequel.rb
29
+ - lib/scaffolding_extensions/model/datamapper.rb
29
30
  - lib/scaffolding_extensions/controller/action_controller.rb
30
31
  - lib/scaffolding_extensions/controller/camping.rb
31
32
  - lib/scaffolding_extensions/controller/ramaze.rb
@@ -50,6 +51,7 @@ files:
50
51
  - doc/sinatra.txt
51
52
  - doc/testing.txt
52
53
  - doc/advanced.txt
54
+ - doc/datamapper.txt
53
55
  - contrib/scaffold_associations_tree/README
54
56
  - contrib/scaffold_associations_tree/bullet.gif
55
57
  - contrib/scaffold_associations_tree/minus.gif
@@ -94,6 +96,7 @@ rdoc_options:
94
96
  - doc/sinatra.txt
95
97
  - doc/testing.txt
96
98
  - doc/advanced.txt
99
+ - doc/datamapper.txt
97
100
  require_paths:
98
101
  - lib
99
102
  required_ruby_version: !ruby/object:Gem::Requirement