scaffolding_extensions 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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