scaffolding_extensions 1.0.0 → 1.1.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
@@ -28,6 +28,7 @@ Scaffolding Extensions currently supports:
28
28
  * Object/Relational Mappers
29
29
  * ActiveRecord 2.0
30
30
  * DataMapper 0.2.5
31
+ * Sequel 0.5.0
31
32
  * Javascript Libaries (used for Ajax/Autocompleting)
32
33
  * Prototype 1.6.0.1
33
34
  * JQuery 1.2.3
@@ -0,0 +1,4 @@
1
+ Sequel is fully supported by Scaffolding Extensions, but because Sequel provides
2
+ limited reflection abilities for database columns, you should define
3
+ @scaffold_column_types for each model and have entries in it for all columns
4
+ that are not strings.
@@ -85,5 +85,6 @@ require 'scaffolding_extensions/controller/sinatra' if defined? Sinatra
85
85
 
86
86
  require 'scaffolding_extensions/model/active_record' if defined? ActiveRecord::Base
87
87
  require 'scaffolding_extensions/model/data_mapper' if defined? DataMapper::Base
88
+ require 'scaffolding_extensions/model/sequel' if defined? Sequel::Model
88
89
 
89
90
  ScaffoldingExtensions.javascript_library = 'Prototype'
@@ -29,9 +29,11 @@ module ScaffoldingExtensions
29
29
  when :edit
30
30
  content << scaffold_check_link('(associate)', true, "edit_#{singular_name}_#{association}", :id=>soid) unless read_only
31
31
  when :new
32
- associated_params = {}
33
- klass.scaffold_new_associated_object_values(association, so).each{|key, value| associated_params["#{class_name}[#{key}]"] = value}
34
- content << scaffold_check_link('(create)', true, "new_#{class_name}", associated_params) unless read_only
32
+ unless read_only
33
+ associated_params = {}
34
+ klass.scaffold_new_associated_object_values(association, so).each{|key, value| associated_params["#{class_name}[#{key}]"] = value}
35
+ content << scaffold_check_link('(create)', true, "new_#{class_name}", associated_params)
36
+ end
35
37
  end
36
38
  if (records = klass.scaffold_associated_objects(association, so, :session=>scaffold_session)).length > 0
37
39
  content << "<ul>\n"
@@ -242,8 +242,8 @@ module ScaffoldingExtensions::MetaModel
242
242
  # up via columns_hash[column_name].type. If no type is provided, :string is used by default.
243
243
  def scaffold_column_type(column_name)
244
244
  @scaffold_column_types ||= SCAFFOLD_OPTIONS[:column_types].dup
245
- if @scaffold_column_types[column_name]
246
- @scaffold_column_types[column_name]
245
+ if type = @scaffold_column_types[column_name]
246
+ type
247
247
  elsif scaffold_association(column_name)
248
248
  :association
249
249
  elsif type = scaffold_table_column_type(column_name)
@@ -314,7 +314,8 @@ module ScaffoldingExtensions::MetaModel
314
314
 
315
315
  # Creates a new object, setting the attributes if given.
316
316
  def scaffold_new_object(attributes, options)
317
- object = new(scaffold_filter_attributes(:new, attributes || {}))
317
+ object = new
318
+ scaffold_set_attributes(object, scaffold_filter_attributes(:new, attributes || {}))
318
319
  object.send("#{scaffold_session_value}=", options[:session][scaffold_session_value]) if scaffold_session_value
319
320
  object
320
321
  end
@@ -526,7 +527,7 @@ module ScaffoldingExtensions::MetaModel
526
527
 
527
528
  # Condition to ensure field equals value
528
529
  def scaffold_equal_condition(field, value)
529
- ["#{scaffold_table_name}.#{field} = ?", "%#{value}%"]
530
+ ["#{scaffold_table_name}.#{field} = ?", value]
530
531
  end
531
532
 
532
533
  # Filters the provided attributes to just the ones given by scaffold_attributes for
@@ -558,6 +559,14 @@ module ScaffoldingExtensions::MetaModel
558
559
  scaffold_associated_class(association).scaffold_select_order(:association)
559
560
  end
560
561
 
562
+ # Set the object's attributes with the given attributes
563
+ def scaffold_set_attributes(object, attributes)
564
+ attributes.each do |k,v|
565
+ v = nil if v.empty? && scaffold_table_column_type(k) == :boolean
566
+ object.send("#{k}=", v)
567
+ end
568
+ end
569
+
561
570
  # Condition to ensure value is a substring of field
562
571
  def scaffold_substring_condition(field, value)
563
572
  ["#{scaffold_table_name}.#{field} #{scaffold_auto_complete_search_operator} ?", "%#{value}%"]
@@ -39,9 +39,4 @@ module ScaffoldingExtensions::MetaARDM
39
39
  def scaffold_remove_associated_object(association, object, associated_object)
40
40
  object.send(association).delete(associated_object)
41
41
  end
42
-
43
- # Set the object's attributes with the given attributes
44
- def scaffold_set_attributes(object, attributes)
45
- object.attributes = attributes
46
- end
47
42
  end
@@ -0,0 +1,224 @@
1
+ ScaffoldingExtensions::MODEL_SUPERCLASSES << Sequel::Model
2
+
3
+ # Instance methods added to Sequel::Model to allow it to work with Scaffolding Extensions.
4
+ module ScaffoldingExtensions::Sequel
5
+ # Get value for given attribute
6
+ def scaffold_attribute_value(field)
7
+ values[field]
8
+ end
9
+
10
+ # the value of the primary key for this object
11
+ def scaffold_id
12
+ pk
13
+ end
14
+ end
15
+
16
+ # Class methods added to Sequel::Model to allow it to work with Scaffolding Extensions.
17
+ module ScaffoldingExtensions::MetaSequel
18
+ SCAFFOLD_OPTIONS = ::ScaffoldingExtensions::MetaModel::SCAFFOLD_OPTIONS
19
+
20
+ # Add the associated object to the object's association
21
+ def scaffold_add_associated_object(association, object, associated_object)
22
+ object.send(association_add_method_name(association.to_s), associated_object)
23
+ end
24
+
25
+ # Array of all association reflections for this model
26
+ def scaffold_all_associations
27
+ all_association_reflections
28
+ end
29
+
30
+ # The class that this model is associated with via the association
31
+ def scaffold_associated_class(association)
32
+ associated_class(association_reflection(association))
33
+ end
34
+
35
+ # All objects that are currently associated with the given object. This method does not
36
+ # check that the returned associated objects meet the associated class's scaffold_session_value
37
+ # constraint, as it is assumed that all objects currently assocated with the given object
38
+ # have already met the criteria. If that is not the case, you should override this method.
39
+ def scaffold_associated_objects(association, object, options)
40
+ assoc = object.send(association)
41
+ reflection = association_reflection(association)
42
+ reflection[:cache] || reflection[:type] == :many_to_one ? assoc : assoc.all
43
+ end
44
+
45
+ # The association reflection for this association
46
+ def scaffold_association(association)
47
+ association_reflection(association)
48
+ end
49
+
50
+ # The type of association, either :new for :one_to_many (as you can create new objects
51
+ # associated with the current object), :edit for :many_to_many (since you
52
+ # can edit the list of associated objects), or :one for :many_to_one.
53
+ def scaffold_association_type(association)
54
+ case scaffold_association(association)[:type]
55
+ when :one_to_many
56
+ :new
57
+ when :many_to_many
58
+ :edit
59
+ else
60
+ :one
61
+ end
62
+ end
63
+
64
+ # List of symbols for associations to display on the scaffolded edit page. Defaults to
65
+ # all associations. Can be set with an instance variable.
66
+ def scaffold_associations
67
+ associations.sort_by{|name| name.to_s}
68
+ end
69
+
70
+ # Destroys the object
71
+ def scaffold_destroy(object)
72
+ object.destroy
73
+ end
74
+
75
+ # The error to raise, should match other errors raised by the underlying library.
76
+ def scaffold_error_raised
77
+ Sequel::Error
78
+ end
79
+
80
+ # Returns the list of fields to display on the scaffolded forms. Defaults
81
+ # to displaying all columns with the exception of the primary key column.
82
+ # Also includes :many_to_one associations, replacing
83
+ # the foriegn keys with the association itself. Can be set with an instance variable.
84
+ def scaffold_fields(action = :default)
85
+ return @scaffold_fields if @scaffold_fields
86
+ fields = columns - [primary_key]
87
+ all_association_reflections.each do |reflection|
88
+ next unless reflection[:type] == :many_to_one
89
+ fields.delete(reflection[:key].to_sym)
90
+ fields.push(reflection[:name])
91
+ end
92
+ @scaffold_fields = fields.sort_by{|f| f.to_s}
93
+ end
94
+
95
+ # The foreign key for the given reflection
96
+ def scaffold_foreign_key(reflection)
97
+ reflection[:key]
98
+ end
99
+
100
+ # Retrieve a single model object given an id
101
+ def scaffold_get_object(id)
102
+ self[id.to_i] || (raise scaffold_error_raised)
103
+ end
104
+
105
+ # Retrieve multiple objects given a hash of options
106
+ def scaffold_get_objects(options)
107
+ records = dataset
108
+ conditions = options[:conditions]
109
+ if conditions && Array === conditions && conditions.length > 0
110
+ if String === conditions[0]
111
+ records = records.filter(*conditions)
112
+ else
113
+ conditions.each do |cond|
114
+ next if cond.nil?
115
+ records = case cond
116
+ when Hash, String then records.filter(cond)
117
+ when Array then records.filter(*cond)
118
+ when Proc then records.filter(&cond)
119
+ end
120
+ end
121
+ end
122
+ end
123
+ order = options[:order]
124
+ order = [order] unless Array === order
125
+ order.each do |o|
126
+ next if o.nil?
127
+ records = case o
128
+ when Proc then records.order(&o)
129
+ else records.order(o)
130
+ end
131
+ end
132
+ records = records.limit(options[:limit], options[:offset]) if options[:limit]
133
+ records.all
134
+ end
135
+
136
+ # Return the class, left foreign key, right foreign key, and join table for this habtm association
137
+ def scaffold_habtm_reflection_options(association)
138
+ reflection = scaffold_association(association)
139
+ [reflection[:class], reflection[:left_key], reflection[:right_key], reflection[:join_table]]
140
+ end
141
+
142
+ # Sequel doesn't do eager loading yet, so this is always nil
143
+ def scaffold_include(action = :default)
144
+ nil
145
+ end
146
+
147
+ # Returns a hash of values to be used as url parameters on the link to create a new
148
+ # :has_many associated object. Defaults to setting the foreign key field to the
149
+ # record's primary key.
150
+ def scaffold_new_associated_object_values(association, record)
151
+ {scaffold_foreign_key(association_reflection(association))=>record.pk}
152
+ end
153
+
154
+ # The primary key for the given table
155
+ def scaffold_primary_key
156
+ primary_key
157
+ end
158
+
159
+ # Saves the object.
160
+ def scaffold_save(action, object)
161
+ object.save
162
+ end
163
+
164
+ # Sequel doesn't keep enough reflection information, so assume string unless
165
+ # specified by @scaffold_column_types.
166
+ def scaffold_table_column_type(column)
167
+ # column is provided by the user, so we can't just .to_sym it
168
+ @scaffold_column_types_strings ||= Hash.new do |h,k1|
169
+ @scaffold_column_types.each{|k2,v| h[k2] = v; h[k2.to_s] = v}
170
+ h[k1] if h.include?(k1)
171
+ end
172
+ @scaffold_column_types_strings[column] || :string
173
+ end
174
+
175
+ # The name of the underlying table
176
+ def scaffold_table_name
177
+ table_name
178
+ end
179
+
180
+ # Sequel doesn't allow you to use transaction on a model (only on a database),
181
+ # so add a transaction method that starts a transaction on the associated database.
182
+ def transaction(&block)
183
+ db.transaction(&block)
184
+ end
185
+
186
+ private
187
+ # Sequel doesn't do eager loading yet
188
+ def scaffold_include_association(association)
189
+ nil
190
+ end
191
+
192
+ # Updates associated records for a given reflection and from record to point to the
193
+ # to record
194
+ def scaffold_reflection_merge(reflection, from, to)
195
+ case reflection[:type]
196
+ when :one_to_many
197
+ foreign_key = reflection[:key]
198
+ db << "UPDATE #{reflection[:class].table_name} SET #{foreign_key} = #{to} WHERE #{foreign_key} = #{from}"
199
+ when :many_to_many
200
+ foreign_key = reflection[:left_key]
201
+ db << "UPDATE #{reflection[:join_table]} SET #{foreign_key} = #{to} WHERE #{foreign_key} = #{from}"
202
+ end
203
+ end
204
+
205
+ # Remove the associated object from object's association
206
+ def scaffold_remove_associated_object(association, object, associated_object)
207
+ object.send(association_remove_method_name(association.to_s), associated_object)
208
+ end
209
+ end
210
+
211
+ # Add the class methods and instance methods from Scaffolding Extensions
212
+ class Sequel::Model
213
+ SCAFFOLD_OPTIONS = ::ScaffoldingExtensions::MetaModel::SCAFFOLD_OPTIONS
214
+ include ScaffoldingExtensions::Model
215
+ include ScaffoldingExtensions::Sequel
216
+ extend ScaffoldingExtensions::MetaModel
217
+ extend ScaffoldingExtensions::MetaSequel
218
+ extend ScaffoldingExtensions::Overridable
219
+ class << self
220
+ extend ScaffoldingExtensions::MetaOverridable
221
+ scaffold_override_methods(:add_associated_objects, :associated_objects, :association_find_object, :association_find_objects, :find_object, :find_objects, :new_associated_object_values, :remove_associated_objects, :save, :unassociated_objects, :filter_attributes)
222
+ scaffold_override_iv_methods(:associated_human_name, :association_use_auto_complete, :fields, :select_order, :attributes, :select_order_association)
223
+ end
224
+ end
metadata CHANGED
@@ -3,9 +3,9 @@ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: scaffolding_extensions
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.0.0
7
- date: 2008-03-05 00:00:00 -08:00
8
- summary: Administrative database front-end for web-frameworks and ORMs
6
+ version: 1.1.0
7
+ date: 2008-03-15 00:00:00 -07:00
8
+ summary: Administrative database front-end for multiple web-frameworks and ORMs
9
9
  require_paths:
10
10
  - lib
11
11
  email: code@jeremyevans.net
@@ -46,6 +46,7 @@ files:
46
46
  - lib/scaffolding_extensions/model/active_record.rb
47
47
  - lib/scaffolding_extensions/model/data_mapper.rb
48
48
  - lib/scaffolding_extensions/model/ardm.rb
49
+ - lib/scaffolding_extensions/model/sequel.rb
49
50
  - lib/scaffolding_extensions/controller/ramaze.rb
50
51
  - lib/scaffolding_extensions/controller/action_controller.rb
51
52
  - lib/scaffolding_extensions/controller/camping.rb
@@ -58,6 +59,7 @@ files:
58
59
  - doc/ramaze.txt
59
60
  - doc/camping.txt
60
61
  - doc/sinatra.txt
62
+ - doc/sequel.txt
61
63
  - contrib/scaffold_associations_tree
62
64
  - contrib/scaffold_jquery_autocomplete
63
65
  - contrib/scaffold_auto_complete_style