scaffolding_extensions 1.3.12 → 1.4.0

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/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