active_scaffold_batch_vho 3.0.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/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 vhochstein
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
File without changes
data/Rakefile ADDED
@@ -0,0 +1,55 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'rake'
11
+
12
+ require 'jeweler'
13
+ require './lib/active_scaffold_batch/version.rb'
14
+
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "active_scaffold_batch_vho"
18
+ gem.version = ActiveScaffoldBatch::Version::STRING
19
+ gem.homepage = "http://github.com/vhochstein/active_scaffold_batch"
20
+ gem.license = "MIT"
21
+ gem.summary = %Q{Batch Processing for ActiveScaffold}
22
+ gem.description = %Q{You want to destroy/update many records at once with activescaffold?}
23
+ gem.email = "activescaffold@googlegroups.com"
24
+ gem.authors = ["Volker Hochstein"]
25
+ gem.add_runtime_dependency 'active_scaffold_vho', '~> 3.0'
26
+ # Include your dependencies below. Runtime dependencies are required when using your gem,
27
+ # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
28
+ # gem.add_runtime_dependency 'jabber4r', '> 0.1'
29
+ # gem.add_development_dependency 'rspec', '> 1.2.3'
30
+ end
31
+ Jeweler::RubygemsDotOrgTasks.new
32
+
33
+ require 'rake/testtask'
34
+ Rake::TestTask.new(:test) do |test|
35
+ test.libs << 'lib' << 'test'
36
+ test.pattern = 'test/**/test_*.rb'
37
+ test.verbose = true
38
+ end
39
+
40
+ require 'rcov/rcovtask'
41
+ Rcov::RcovTask.new do |test|
42
+ test.libs << 'test'
43
+ test.pattern = 'test/**/test_*.rb'
44
+ test.verbose = true
45
+ end
46
+
47
+ task :default => :test
48
+
49
+ require 'rake/rdoctask'
50
+ Rake::RDocTask.new do |rdoc|
51
+ rdoc.rdoc_dir = 'rdoc'
52
+ rdoc.title = "active_scaffold_batch #{ActiveScaffoldBatch::Version::STRING}"
53
+ rdoc.rdoc_files.include('README*')
54
+ rdoc.rdoc_files.include('lib/**/*.rb')
55
+ end
@@ -0,0 +1,7 @@
1
+ <%= render :partial => "base_form", :locals => {:xhr => xhr ||= nil,
2
+ :form_action => form_action ||= :batch_update,
3
+ :method => method ||= :post,
4
+ :cancel_link => cancel_link ||= true,
5
+ :body_partial => 'batch_update_form_body',
6
+ :headline => headline ||= active_scaffold_config.batch_update.label} %>
7
+
@@ -0,0 +1,12 @@
1
+ <% scope ||= nil %>
2
+ <dl>
3
+ <dt>
4
+ <label for="<%= active_scaffold_input_options(column, scope)[:id] %>"><%= column.label %></label>
5
+ </dt>
6
+ <dd>
7
+ <%= active_scaffold_update_for column, scope %>
8
+ <% if column.description -%>
9
+ <span class="description"><%= column.description %></span>
10
+ <% end -%>
11
+ </dd>
12
+ </dl>
@@ -0,0 +1,9 @@
1
+ <% scope ||= nil %>
2
+ <dl>
3
+ <dt>
4
+ <label for="record_batch_scope"><%= as_(:records) %></label>
5
+ </dt>
6
+ <dd>
7
+ <%= active_scaffold_update_scope_select %>
8
+ </dd>
9
+ </dl>
@@ -0,0 +1,25 @@
1
+ <% subsection_id ||= nil %>
2
+ <ol class="form" <%= "id=#{subsection_id}" unless subsection_id.nil? %> <%= 'style="display: none;"' if columns.collapsed -%>>
3
+ <li class="form-element">
4
+ <%= render :partial => 'batch_update_form_attribute_scope' -%>
5
+ </li>
6
+ <% columns.each :for => @record do |column| %>
7
+ <% next if column.plural_association? || (column.association && [:has_one].include?(column.association.macro)) %>
8
+ <% renders_as = column_renders_as(column) %>
9
+ <% if renders_as == :subsection -%>
10
+ <% subsection_id = sub_section_id(:sub_section => column.label) %>
11
+ <li class="sub-section">
12
+ <h5><%= column.label %></h5>
13
+ <%= render :partial => 'form', :locals => { :columns => column, :subsection_id => subsection_id} %>
14
+ <%= link_to_visibility_toggle(subsection_id, {:default_visible => !column.collapsed}) -%>
15
+ </li>
16
+ <% elsif column.readonly_association?
17
+ next %>
18
+ <% else
19
+ renders_as = :field if renders_as == :subform -%>
20
+ <li class="form-element <%= column.css_class unless column.css_class.nil? %>">
21
+ <%= render :partial => 'batch_update_form_attribute', :locals => { :column => column } -%>
22
+ </li>
23
+ <% end -%>
24
+ <% end -%>
25
+ </ol>
@@ -0,0 +1,5 @@
1
+ <div class="active-scaffold">
2
+ <div class="batch-update-view <%= "#{params[:controller]}-view" %> view">
3
+ <%= render :partial => 'batch_update_form' -%>
4
+ </div>
5
+ </div>
@@ -0,0 +1,6 @@
1
+ unless @error_records.empty?
2
+ flash[:error] = @error_records.collect do |record|
3
+ active_scaffold_error_messages_for(record, :object_name => "#{record.class.model_name.human.downcase}#{record.new_record? ? '' : ": #{record.to_label}"}", :header_message => '', :message => "#{record.class.model_name.human.downcase}#{record.new_record? ? '' : ": #{record.to_label}"}", :container_tag => nil, :list_type => :br)
4
+ end.join.html_safe
5
+ end
6
+ page.call 'ActiveScaffold.replace_html', active_scaffold_content_id, render(:partial => 'list', :layout => false)
@@ -0,0 +1,10 @@
1
+ form_selector = "#{element_form_id(:action => :batch_update)}"
2
+
3
+ if controller.send :batch_successful?
4
+ page.call 'ActiveScaffold.replace_html', active_scaffold_content_id, render(:partial => 'list', :layout => false)
5
+ page << "ActiveScaffold.find_action_link('#{form_selector}').close();"
6
+ else
7
+ page << "ActiveScaffold.find_action_link('#{form_selector}').update_flash_messages('#{escape_javascript(render(:partial => 'messages').strip)}');"
8
+ page.call 'ActiveScaffold.replace', form_selector, render(:partial => 'batch_update_form', :locals => {:xhr => true})
9
+ page.call 'ActiveScaffold.scroll_to', form_selector
10
+ end
data/init.rb ADDED
@@ -0,0 +1,9 @@
1
+ ACTIVE_SCAFFOLD_BATCH_INSTALLED = :plugin
2
+
3
+ require 'active_scaffold_batch'
4
+
5
+ begin
6
+ ActiveScaffoldAssets.copy_to_public(ActiveScaffoldBatch.root)
7
+ rescue
8
+ raise $! unless Rails.env == 'production'
9
+ end
@@ -0,0 +1,118 @@
1
+ module ActiveScaffold::Actions
2
+ module BatchBase
3
+
4
+ def self.included(base)
5
+ base.add_active_scaffold_path File.join(ActiveScaffold::Config::BatchBase.plugin_directory, 'frontends', 'default' , 'views')
6
+ base.helper_method :batch_scope
7
+ end
8
+
9
+ protected
10
+
11
+ def batch_action(batch_action = :batch_base)
12
+ process_action_link_action(batch_action) do
13
+ process_batch
14
+ end
15
+ end
16
+
17
+ def process_batch
18
+ do_batch
19
+ do_search if respond_to? :do_search
20
+ do_list
21
+ end
22
+
23
+ def batch_scope
24
+ if params[:batch_scope]
25
+ @batch_scope = params[:batch_scope] if ['LISTED', 'MARKED'].include?(params[:batch_scope])
26
+ params.delete :batch_scope
27
+ end if @batch_scope.nil?
28
+ @batch_scope
29
+ end
30
+
31
+ def error_records
32
+ @error_records ||= []
33
+ end
34
+
35
+ # in case of an error we have to prepare @record object to have assigned all
36
+ # defined batch_update values, however, do not set those ones with an override
37
+ # these ones will manage on their own
38
+ def prepare_error_record
39
+ end
40
+
41
+ def batch_successful?
42
+ error_records.empty?
43
+ end
44
+
45
+ def do_batch
46
+ send("before_do_#{action_name}") if respond_to?("before_do_#{action_name}")
47
+ send("#{action_name}_#{batch_scope.downcase}") if !batch_scope.nil? && respond_to?("#{action_name}_#{batch_scope.downcase}")
48
+ prepare_error_record unless batch_successful?
49
+ end
50
+
51
+ def authorized_for_job?(record)
52
+ if record.authorized_for?(:crud_type => active_scaffold_config.send(action_name).crud_type)
53
+ true
54
+ else
55
+ record.errors.add(:base, as_(:no_authorization_for_action, :action => action_name))
56
+ error_records << record
57
+ false
58
+ end
59
+ end
60
+
61
+ def batch_base_respond_to_html
62
+ if respond_to? "#{action_name}_respond_to_html"
63
+ send("#{action_name}_respond_to_html")
64
+ else
65
+ if params[:iframe]=='true' # was this an iframe post ?
66
+ responds_to_parent do
67
+ render :action => 'on_batch_base.js', :layout => false
68
+ end
69
+ else # just a regular post
70
+ if batch_successful?
71
+ flash[:info] = as_(:batch_processing_successful)
72
+ end
73
+ return_to_main
74
+ end
75
+ end
76
+ end
77
+
78
+ def batch_base_respond_to_js
79
+ if respond_to? "#{action_name}_respond_to_js"
80
+ send("#{action_name}_respond_to_js")
81
+ else
82
+ render :action => "on_batch_base"
83
+ end
84
+ end
85
+
86
+ def batch_base_respond_to_xml
87
+ if respond_to? "#{action_name}_respond_to_xml"
88
+ send("#{action_name}_respond_to_xml")
89
+ else
90
+ render :xml => response_object.to_xml(:only => active_scaffold_config.send(action_name).columns.names), :content_type => Mime::XML, :status => response_status
91
+ end
92
+ end
93
+
94
+ def batch_base_respond_to_json
95
+ if respond_to? "#{action_name}_respond_to_json"
96
+ send("#{action_name}_respond_to_json")
97
+ else
98
+ render :text => response_object.to_json(:only => active_scaffold_config.send(action_name).columns.names), :content_type => Mime::JSON, :status => response_status
99
+ end
100
+ end
101
+
102
+ def batch_base_respond_to_yaml
103
+ if respond_to? "#{action_name}_respond_to_yaml"
104
+ send("#{action_name}_respond_to_yaml")
105
+ else
106
+ render :text => Hash.from_xml(response_object.to_xml(:only => active_scaffold_config.send(action_name).columns.names)).to_yaml, :content_type => Mime::YAML, :status => response_status
107
+ end
108
+ end
109
+
110
+ def batch_base_formats
111
+ if respond_to? "#{action_name}_formats"
112
+ send("#{action_name}_formats")
113
+ else
114
+ (default_formats + active_scaffold_config.formats + active_scaffold_config.send(action_name).formats).uniq
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,72 @@
1
+ module ActiveScaffold::Actions
2
+ module BatchDestroy
3
+
4
+ def self.included(base)
5
+ base.before_filter :batch_destroy_authorized_filter, :only => [:batch_destroy]
6
+ end
7
+
8
+ def batch_destroy
9
+ batch_action
10
+ end
11
+
12
+ protected
13
+
14
+ def batch_destroy_listed
15
+ case active_scaffold_config.batch_destroy.process_mode
16
+ when :delete then
17
+ each_record_in_scope do |record|
18
+ destroy_record(record) if authorized_for_job?(record)
19
+ end
20
+ when :delete_all then
21
+ do_search if respond_to? :do_search
22
+ active_scaffold_config.model.delete_all(all_conditions)
23
+ else
24
+ Rails.logger.error("Unknown process_mode: #{active_scaffold_config.batch_destroy.process_mode} for action batch_destroy")
25
+ end
26
+
27
+ end
28
+
29
+ def batch_destroy_marked
30
+ case active_scaffold_config.batch_destroy.process_mode
31
+ when :delete then
32
+ active_scaffold_config.model.marked.each do |record|
33
+ destroy_record(record) if authorized_for_job?(record)
34
+ end
35
+ when :delete_all then
36
+ active_scaffold_config.model.marked.delete_all
37
+ do_demark_all
38
+ else
39
+ Rails.logger.error("Unknown process_mode: #{active_scaffold_config.batch_destroy.process_mode} for action batch_destroy")
40
+ end
41
+ end
42
+
43
+ def destroy_record(record)
44
+ @successful = nil
45
+ @record = record
46
+
47
+ do_destroy
48
+ if successful?
49
+ @record.marked = false if batch_scope == 'MARKED'
50
+ else
51
+ error_records << @record
52
+ end
53
+ end
54
+
55
+ # The default security delegates to ActiveRecordPermissions.
56
+ # You may override the method to customize.
57
+ def batch_destroy_authorized?(record = nil)
58
+ authorized_for?(:crud_type => :delete)
59
+ end
60
+
61
+ def batch_destroy_marked_ignore?(record = nil)
62
+ !active_scaffold_config.list.columns.include? :marked
63
+ end
64
+
65
+ private
66
+
67
+ def batch_destroy_authorized_filter
68
+ link = active_scaffold_config.batch_destroy.link || active_scaffold_config.batch_destroy.class.link
69
+ raise ActiveScaffold::ActionNotAllowed unless self.send(link.first.security_method)
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,320 @@
1
+ module ActiveScaffold::Actions
2
+ module BatchUpdate
3
+
4
+ GenericOperators = [
5
+ 'NO_UPDATE',
6
+ 'REPLACE'
7
+ ]
8
+ NumericOperators = [
9
+ 'PLUS',
10
+ 'MINUS',
11
+ 'TIMES',
12
+ 'DIVISION'
13
+ ]
14
+ NumericOptions = [
15
+ 'ABSOLUTE',
16
+ 'PERCENT'
17
+ ]
18
+
19
+ DateOperators = [
20
+ 'PLUS',
21
+ 'MINUS'
22
+ ]
23
+
24
+ def self.included(base)
25
+ base.before_filter :batch_update_authorized_filter, :only => [:batch_edit, :batch_update]
26
+ base.verify :method => [:post, :put],
27
+ :only => :batch_update,
28
+ :redirect_to => { :action => :index }
29
+ base.helper_method :batch_update_values
30
+ end
31
+
32
+ def batch_edit
33
+ do_batch_edit
34
+ respond_to_action(:batch_edit)
35
+ end
36
+
37
+ def batch_update
38
+ batch_action
39
+ end
40
+
41
+
42
+ protected
43
+ def batch_edit_respond_to_html
44
+ if batch_successful?
45
+ render(:action => 'batch_update')
46
+ else
47
+ return_to_main
48
+ end
49
+ end
50
+
51
+ def batch_edit_respond_to_js
52
+ render(:partial => 'batch_update_form')
53
+ end
54
+
55
+ def selected_columns
56
+ if @selected_columns.nil?
57
+ @selected_columns = []
58
+ if params[:record] && params[:record].is_a?(Hash)
59
+ params[:record].each do |key, value|
60
+ @selected_columns << key.to_sym if value[:operator] != 'NO_UPDATE'
61
+ end
62
+ end
63
+ end
64
+ @selected_columns
65
+ end
66
+
67
+
68
+ def batch_update_values
69
+ @batch_update_values || {}
70
+ end
71
+
72
+ def batch_update_respond_to_html
73
+ if params[:iframe]=='true' # was this an iframe post ?
74
+ responds_to_parent do
75
+ render :action => 'on_batch_update.js', :layout => false
76
+ end
77
+ else # just a regular post
78
+ if batch_successful?
79
+ flash[:info] = as_(:updated_model, :model => @record.to_label)
80
+ return_to_main
81
+ else
82
+ render(:action => 'batch_update')
83
+ end
84
+ end
85
+ end
86
+
87
+ def batch_update_respond_to_js
88
+ render :action => 'on_batch_update'
89
+ end
90
+
91
+ def do_batch_edit
92
+ self.successful = true
93
+ do_new
94
+ end
95
+
96
+ def before_do_batch_update
97
+ update_columns = active_scaffold_config.batch_update.columns
98
+ @batch_update_values = attribute_values_from_params(update_columns, params[:record])
99
+ end
100
+
101
+ # in case of an error we have to prepare @record object to have assigned all
102
+ # defined batch_update values, however, do not set those ones with an override
103
+ # these ones will manage on their own
104
+ def prepare_error_record
105
+ do_new
106
+ batch_update_values.each do |attribute, value|
107
+ form_ui = colunm_form_ui(value[:column])
108
+ set_record_attribute(value[:column], attribute, value[:value]) unless form_ui && override_batch_update_value?(form_ui)
109
+ end
110
+ end
111
+
112
+ def batch_update_listed
113
+ case active_scaffold_config.batch_update.process_mode
114
+ when :update then
115
+ each_record_in_scope {|record| update_record(record) if authorized_for_job?(record)}
116
+ when :update_all then
117
+ updates = updates_for_update_all
118
+ unless updates.first.empty?
119
+ do_search if respond_to? :do_search
120
+ # all_conditions might fail cause joins are not working in update_all
121
+ active_scaffold_config.model.update_all(updates, all_conditions)
122
+ end
123
+ else
124
+ Rails.logger.error("Unknown process_mode: #{active_scaffold_config.batch_update.process_mode} for action batch_update")
125
+ end
126
+
127
+ end
128
+
129
+ def batch_update_marked
130
+ case active_scaffold_config.batch_update.process_mode
131
+ when :update then
132
+ active_scaffold_config.model.marked.each {|record| update_record(record) if authorized_for_job?(record)}
133
+ when :update_all then
134
+ updates = updates_for_update_all
135
+ unless updates.first.empty?
136
+ active_scaffold_config.model.marked.update_all(updates)
137
+ do_demark_all
138
+ end
139
+ else
140
+ Rails.logger.error("Unknown process_mode: #{active_scaffold_config.batch_update.process_mode} for action batch_update")
141
+ end
142
+ end
143
+
144
+ def updates_for_update_all()
145
+ update_all = [[]]
146
+ batch_update_values.each do |attribute, value|
147
+ sql_set, value = get_update_all_attribute(value[:column], attribute, value[:value])
148
+ unless sql_set.nil?
149
+ update_all.first << sql_set
150
+ update_all << value if sql_set.include?('?')
151
+ end
152
+ end
153
+ update_all[0] = update_all.first.join(',')
154
+ update_all
155
+ end
156
+
157
+ def update_record(record)
158
+ @successful = nil
159
+ @record = record
160
+
161
+ batch_update_values.each do |attribute, value|
162
+ set_record_attribute(value[:column], attribute, value[:value])
163
+ end
164
+
165
+ update_save
166
+ if successful?
167
+ @record.marked = false if batch_scope == 'MARKED'
168
+ else
169
+ error_records << @record
170
+ end
171
+ end
172
+
173
+ def set_record_attribute(column, attribute, value)
174
+ form_ui = colunm_form_ui(column)
175
+ if form_ui && override_batch_update_value?(form_ui)
176
+ @record.send("#{attribute}=", send(override_batch_update_value(form_ui), column, @record, value))
177
+ else
178
+ @record.send("#{attribute}=", value[:operator] == 'NULL' ? nil : value[:value])
179
+ end
180
+ end
181
+
182
+ def colunm_form_ui(column)
183
+ form_ui = column.form_ui
184
+ form_ui = column.column.type if form_ui.nil? && column.column
185
+ end
186
+
187
+ def get_update_all_attribute(column, attribute, value)
188
+ form_ui = column.form_ui
189
+ form_ui = column.column.type if form_ui.nil? && column.column
190
+
191
+ if form_ui && override_batch_update_all_value?(form_ui)
192
+ update_value = send(override_batch_update_all_value(form_ui), column, value)
193
+ if update_value.nil?
194
+ sql_set = nil
195
+ else
196
+ sql_set = "#{attribute} = #{update_value}"
197
+ update_value = nil
198
+ end
199
+ else
200
+ sql_set = "#{attribute} = ?"
201
+ update_value = value[:operator] == 'NULL' ? nil : value[:value]
202
+ end
203
+
204
+ return sql_set, update_value
205
+ end
206
+
207
+ def attribute_values_from_params(columns, attributes)
208
+ values = {}
209
+ columns.each :for => active_scaffold_config.model.new, :crud_type => :update, :flatten => true do |column|
210
+ values[column.name] = {:column => column, :value => attributes[column.name].merge(:value => column_value_from_param_value(nil, column, attributes[column.name][:value]))} if selected_columns.include? column.name
211
+ end
212
+ values
213
+ end
214
+
215
+
216
+ # The default security delegates to ActiveRecordPermissions.
217
+ # You may override the method to customize.
218
+ def batch_update_authorized?(record = nil)
219
+ authorized_for?(:crud_type => :update)
220
+ end
221
+
222
+ def batch_update_value_for_numeric(column, record, calculation_info)
223
+ current_value = record.send(column.name)
224
+ if ActiveScaffold::Actions::BatchUpdate::GenericOperators.include?(calculation_info[:operator]) || ActiveScaffold::Actions::BatchUpdate::NumericOperators.include?(calculation_info[:operator])
225
+ operand = self.class.condition_value_for_numeric(column, calculation_info[:value])
226
+ operand = current_value / 100 * operand if calculation_info[:opt] == 'PERCENT'
227
+ case calculation_info[:operator]
228
+ when 'REPLACE' then operand
229
+ when 'NULL' then nil
230
+ when 'PLUS' then current_value.present? ? current_value + operand : nil
231
+ when 'MINUS' then current_value.present? ? current_value - operand : nil
232
+ when 'TIMES' then current_value.present? ? current_value * operand : nil
233
+ when 'DIVISION' then current_value.present? ? current_value / operand : nil
234
+ else
235
+ current_value
236
+ end
237
+ else
238
+ current_value
239
+ end
240
+ end
241
+ alias_method :batch_update_value_for_integer, :batch_update_value_for_numeric
242
+ alias_method :batch_update_value_for_decimal, :batch_update_value_for_numeric
243
+ alias_method :batch_update_value_for_float, :batch_update_value_for_numeric
244
+
245
+ def batch_update_all_value_for_numeric(column, calculation_info)
246
+ if ActiveScaffold::Actions::BatchUpdate::GenericOperators.include?(calculation_info[:operator]) || ActiveScaffold::Actions::BatchUpdate::NumericOperators.include?(calculation_info[:operator])
247
+ operand = active_scaffold_config.model.quote_value(self.class.condition_value_for_numeric(column, calculation_info[:value]))
248
+ if calculation_info[:opt] == 'PERCENT'#
249
+ operand = "#{active_scaffold_config.model.connection.quote_column_name(column.name)} / 100.0 * #{operand}"
250
+ end
251
+ case calculation_info[:operator]
252
+ when 'REPLACE' then operand
253
+ when 'NULL' then active_scaffold_config.model.quote_value(nil)
254
+ when 'PLUS' then "#{active_scaffold_config.model.connection.quote_column_name(column.name)} + #{operand}"
255
+ when 'MINUS' then "#{active_scaffold_config.model.connection.quote_column_name(column.name)} - #{operand}"
256
+ when 'TIMES' then "#{active_scaffold_config.model.connection.quote_column_name(column.name)} * #{operand}"
257
+ when 'DIVISION' then "#{active_scaffold_config.model.connection.quote_column_name(column.name)} / #{operand}"
258
+ else
259
+ nil
260
+ end
261
+ else
262
+ nil
263
+ end
264
+ end
265
+ alias_method :batch_update_all_value_for_integer, :batch_update_all_value_for_numeric
266
+ alias_method :batch_update_all_value_for_decimal, :batch_update_all_value_for_numeric
267
+ alias_method :batch_update_all_value_for_float, :batch_update_all_value_for_numeric
268
+
269
+ def batch_update_value_for_date_picker(column, record, calculation_info)
270
+ current_value = record.send(column.name)
271
+ {"number"=>"", "unit"=>"DAYS", "value"=>"November 16, 2010", "operator"=>"REPLACE"}
272
+ if ActiveScaffold::Actions::BatchUpdate::GenericOperators.include?(calculation_info[:operator]) || ActiveScaffold::Actions::BatchUpdate::DateOperators.include?(calculation_info[:operator])
273
+ operand = self.class.condition_value_for_datetime(calculation_info[:value], column.column.type == :date ? :to_date : :to_time)
274
+ case calculation_info[:operator]
275
+ when 'REPLACE' then operand
276
+ when 'NULL' then nil
277
+ when 'PLUS' then
278
+ trend_number = [calculation_info['number'].to_i, 1].max
279
+ current_value.in((trend_number).send(calculation_info['unit'].downcase.singularize.to_sym))
280
+ when 'MINUS' then
281
+ trend_number = [calculation_info['number'].to_i, 1].max
282
+ current_value.ago((trend_number).send(calculation_info['unit'].downcase.singularize.to_sym))
283
+ else
284
+ current_value
285
+ end
286
+ else
287
+ current_value
288
+ end
289
+ end
290
+ alias_method :batch_update_value_for_calendar_date_select, :batch_update_value_for_date_picker
291
+
292
+
293
+
294
+ def override_batch_update_value?(form_ui)
295
+ respond_to?(override_batch_update_value(form_ui))
296
+ end
297
+
298
+ def override_batch_update_value(form_ui)
299
+ "batch_update_value_for_#{form_ui}"
300
+ end
301
+
302
+ def override_batch_update_all_value?(form_ui)
303
+ respond_to?(override_batch_update_all_value(form_ui))
304
+ end
305
+
306
+ def override_batch_update_all_value(form_ui)
307
+ "batch_update_all_value_for_#{form_ui}"
308
+ end
309
+
310
+ private
311
+
312
+ def batch_update_authorized_filter
313
+ link = active_scaffold_config.batch_update.link || active_scaffold_config.batch_update.class.link
314
+ raise ActiveScaffold::ActionNotAllowed unless self.send(link.security_method)
315
+ end
316
+ def batch_edit_formats
317
+ (default_formats + active_scaffold_config.formats).uniq
318
+ end
319
+ end
320
+ end
@@ -0,0 +1,11 @@
1
+ module ActiveScaffold::Config
2
+ class BatchBase < ActiveScaffold::Config::Base
3
+ def initialize(core_config)
4
+ @core = core_config
5
+ end
6
+
7
+ # configures where the plugin itself is located. there is no instance version of this.
8
+ cattr_accessor :plugin_directory
9
+ @@plugin_directory = File.expand_path(__FILE__).match(%{(^.*)/lib/active_scaffold/config/batch_base.rb})[1]
10
+ end
11
+ end
@@ -0,0 +1,54 @@
1
+ module ActiveScaffold::Config
2
+ class BatchDestroy < ActiveScaffold::Config::Base
3
+ self.crud_type = :delete
4
+
5
+ def initialize(core_config)
6
+ @core = core_config
7
+
8
+ # start with the ActionLink defined globally
9
+ @link = self.class.link
10
+ @action_group = self.class.action_group.clone if self.class.action_group
11
+ @action_group ||= 'collection.batch.destroy'
12
+ @process_mode = self.class.process_mode
13
+ end
14
+
15
+ # global level configuration
16
+ # --------------------------
17
+ # the ActionLink for this action
18
+ def self.link
19
+ @@link
20
+ end
21
+ def self.link=(val)
22
+ @@link = val
23
+ end
24
+ @@link = [ ActiveScaffold::DataStructures::ActionLink.new('batch_destroy', :label => :listed, :type => :collection, :method => :delete, :position => false, :crud_type => :delete, :confirm => :are_you_sure_to_delete, :parameters => {:batch_scope => 'LISTED'},:security_method => :batch_destroy_authorized?),
25
+ ActiveScaffold::DataStructures::ActionLink.new('batch_destroy', :label => :marked, :type => :collection, :method => :delete, :position => false, :crud_type => :delete, :confirm => :are_you_sure_to_delete, :parameters => {:batch_scope => 'MARKED'}, :security_method => :batch_destroy_authorized?, :ignore_method => :batch_destroy_marked_ignore?)]
26
+
27
+ # configures where the plugin itself is located. there is no instance version of this.
28
+ cattr_accessor :plugin_directory
29
+ @@plugin_directory = File.expand_path(__FILE__).match(/vendor\/plugins\/([^\/]*)/)[1]
30
+
31
+ # configures how batch updates should be processed
32
+ # :delete => standard activerecord delete including validations
33
+ # :delete_all => updating in one sql call without activerecord instantiation and validation
34
+ cattr_accessor :process_mode
35
+ @@process_mode = :delete
36
+
37
+
38
+ # instance-level configuration
39
+ # ----------------------------
40
+
41
+ # see class accessor
42
+ attr_accessor :process_mode
43
+
44
+ # the ActionLink for this action
45
+ attr_accessor :link
46
+
47
+ # the label= method already exists in the Form base class
48
+ def label(model = nil)
49
+ model ||= @core.label(:count => 2)
50
+ @label ? as_(@label) : as_(:deleted_model, :model => model)
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,45 @@
1
+ module ActiveScaffold::Config
2
+ class BatchUpdate < ActiveScaffold::Config::Form
3
+ self.crud_type = :update
4
+ def initialize(*args)
5
+ super
6
+ @process_mode = self.class.process_mode
7
+ @action_group ||= 'collection.batch'
8
+ end
9
+
10
+ # global level configuration
11
+ # --------------------------
12
+ # the ActionLink for this action
13
+ def self.link
14
+ @@link
15
+ end
16
+ def self.link=(val)
17
+ @@link = val
18
+ end
19
+ @@link = ActiveScaffold::DataStructures::ActionLink.new('batch_edit', :label => :edit, :type => :collection, :security_method => :batch_update_authorized?)
20
+
21
+ # configures where the plugin itself is located. there is no instance version of this.
22
+ cattr_accessor :plugin_directory
23
+ @@plugin_directory = File.expand_path(__FILE__).match(/vendor\/plugins\/([^\/]*)/)[1]
24
+
25
+ # configures how batch updates should be processed
26
+ # :update => standard activerecord update including validations
27
+ # :update_all => updating in one sql call without activerecord instantiation and validation
28
+ cattr_accessor :process_mode
29
+ @@process_mode = :update
30
+
31
+
32
+ # instance-level configuration
33
+ # ----------------------------
34
+
35
+ # see class accessor
36
+ attr_accessor :process_mode
37
+
38
+
39
+ # the label= method already exists in the Form base class
40
+ def label(model = nil)
41
+ model ||= @core.label(:count => 2)
42
+ @label ? as_(@label) : as_(:update_model, :model => model)
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,33 @@
1
+ module ActiveScaffold
2
+ module Helpers
3
+ module CalendarDateSelectUpdateColumnHelpers
4
+ def active_scaffold_update_calendar_date_select(column, options)
5
+ current_params = {:value => nil, :number => nil, :unit => nil, :operator => 'NO_UPDATE'}
6
+ current_params.merge!(batch_update_values[column.name][:value].symbolize_keys) if batch_update_values[column.name] && batch_update_values[column.name][:value]
7
+ Rails.logger.info("update_date column: #{column.name}: #{current_params[:value].inspect}, class: #{current_params[:value].class}")
8
+ Rails.logger.info("update_date column: #{column.name}: options #{options.inspect}")
9
+ current_params[:value] = nil if current_params[:value].is_a?(String)
10
+ Rails.logger.info("update_date2 column: #{column.name}: #{current_params[:value].inspect}, class: #{current_params[:value].class}")
11
+ operator_options = active_scaffold_update_generic_operators(column)
12
+ operator_options.concat(ActiveScaffold::Actions::BatchUpdate::DateOperators.collect {|comp| [as_(comp.downcase.to_sym), comp]}) if active_scaffold_config.batch_update.process_mode == :update
13
+ options = options.merge(:show => ['PLUS', 'MINUS'].exclude?(current_params[:operator]))
14
+ tags = []
15
+ tags << select_tag("[record][#{column.name}][operator]",
16
+ options_for_select(operator_options, current_params[:operator]),
17
+ :id => "#{options[:id]}_operator",
18
+ :class => "text-input as_update_date_operator")
19
+ tags << active_scaffold_search_date_bridge_calendar_control(column, options, current_params[:value], 'value')
20
+ tags << active_scaffold_update_date_bridge_trend_tag(column, current_params, options)
21
+ tags.join("&nbsp;").html_safe
22
+ end
23
+
24
+ def active_scaffold_update_date_bridge_trend_tag(column, current_params, options)
25
+ active_scaffold_date_bridge_trend_tag(column, options,
26
+ {:name_prefix => '[record]',
27
+ :number_value => current_params[:number],
28
+ :unit_value => current_params[:unit],
29
+ :show => ['PLUS','MINUS'].include?(current_params[:operator])})
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,29 @@
1
+ module ActiveScaffold
2
+ module Helpers
3
+ module DatepickerUpdateColumnHelpers
4
+ def active_scaffold_update_date_picker(column, options)
5
+ current_params = {:value => nil, :number => nil, :unit => nil, :operator => 'NO_UPDATE'}
6
+ current_params.merge!(batch_update_values[column.name][:value].symbolize_keys) if batch_update_values[column.name] && batch_update_values[column.name][:value]
7
+ operator_options = active_scaffold_update_generic_operators(column)
8
+ operator_options.concat(ActiveScaffold::Actions::BatchUpdate::DateOperators.collect {|comp| [as_(comp.downcase.to_sym), comp]}) if active_scaffold_config.batch_update.process_mode == :update
9
+ options = options.merge(:show => ['PLUS', 'MINUS'].exclude?(current_params[:operator]))
10
+ tags = []
11
+ tags << select_tag("[record][#{column.name}][operator]",
12
+ options_for_select(operator_options, current_params[:operator]),
13
+ :id => "#{options[:id]}_operator",
14
+ :class => "text-input as_update_date_operator")
15
+ tags << active_scaffold_search_date_bridge_calendar_control(column, options, current_params[:value], 'value')
16
+ tags << active_scaffold_update_date_bridge_trend_tag(column, current_params, options)
17
+ tags.join("&nbsp;").html_safe
18
+ end
19
+
20
+ def active_scaffold_update_date_bridge_trend_tag(column, current_params, options)
21
+ active_scaffold_date_bridge_trend_tag(column, options,
22
+ {:name_prefix => '[record]',
23
+ :number_value => current_params[:number],
24
+ :unit_value => current_params[:unit],
25
+ :show => ['PLUS','MINUS'].include?(current_params[:operator])})
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,91 @@
1
+ module ActiveScaffold
2
+ module Helpers
3
+ # Helpers that assist with the rendering of a Form Column
4
+ module UpdateColumnHelpers
5
+ # This method decides which input to use for the given column.
6
+ # It does not do any rendering. It only decides which method is responsible for rendering.
7
+ def active_scaffold_update_for(column, scope = nil, options = {})
8
+ options = active_scaffold_input_options(column, scope, options)
9
+
10
+ # first, check if the dev has created an override for this specific field for search
11
+ if override_update_field?(column)
12
+ send(override_update_field(column), @record, options)
13
+ # second, check if the dev has specified a valid form_ui for this column, using specific ui for searches
14
+ elsif column.form_ui and override_update?(column.form_ui)
15
+ send(override_update(column.form_ui), column, options)
16
+ elsif column.column and override_update?(column.column.type)
17
+ send(override_update(column.column.type), column, options)
18
+ else
19
+ active_scaffold_update_generic_operators_select(column, options)<< ' ' << active_scaffold_render_input(column, options.merge(:name => "record[#{column.name}][value]"))
20
+ end
21
+ end
22
+
23
+ def active_scaffold_update_generic_operators(column)
24
+ operators = ActiveScaffold::Actions::BatchUpdate::GenericOperators.collect {|comp| [as_(comp.downcase.to_sym), comp]}
25
+ if column.column.nil? || column.column.null
26
+ operators << [as_(:null), 'NULL']
27
+ end
28
+ operators
29
+ end
30
+
31
+ def active_scaffold_update_generic_operators_select(column, options)
32
+ current = {:operator => 'NO_UPDATE'}
33
+ current.merge!(batch_update_values[column.name][:value].symbolize_keys) if batch_update_values[column.name] && batch_update_values[column.name][:value]
34
+ select_tag("[record][#{column.name}][operator]",
35
+ options_for_select(active_scaffold_update_generic_operators(column), current[:operator]),
36
+ :id => "#{options[:id]}_operator",
37
+ :class => "as_batch_update_operator text_input")
38
+ end
39
+
40
+ def active_scaffold_update_numeric(column, options)
41
+ current = {:value => nil, :opt => 'ABSOLUTE', :operator => 'NO_UPDATE'}
42
+ current.merge!(batch_update_values[column.name][:value].symbolize_keys) if batch_update_values[column.name] && batch_update_values[column.name][:value]
43
+ operator_options = active_scaffold_update_generic_operators(column) + ActiveScaffold::Actions::BatchUpdate::NumericOperators.collect {|comp| [as_(comp.downcase.to_sym), comp]}
44
+ select_options = ActiveScaffold::Actions::BatchUpdate::NumericOptions.collect {|comp| [as_(comp.downcase.to_sym), comp]}
45
+ html = select_tag("[record][#{column.name}][operator]",
46
+ options_for_select(operator_options, current[:operator]),
47
+ :id => "#{options[:id]}_operator",
48
+ :class => "as_update_numeric_option")
49
+ html << ' ' << text_field_tag("[record][#{column.name}][value]", current[:value], active_scaffold_input_text_options)
50
+ html << ' ' << select_tag("[record][#{column.name}][opt]",
51
+ options_for_select(select_options, current[:opt]),
52
+ :id => "#{options[:id]}_opt",
53
+ :class => "as_update_numeric_option")
54
+ html
55
+ end
56
+ alias_method :active_scaffold_update_integer, :active_scaffold_update_numeric
57
+ alias_method :active_scaffold_update_decimal, :active_scaffold_update_numeric
58
+ alias_method :active_scaffold_update_float, :active_scaffold_update_numeric
59
+
60
+ def active_scaffold_update_scope_select
61
+ select_options = [[as_(:listed), 'LISTED']]
62
+ select_options << [as_(:marked), 'MARKED'] if active_scaffold_config.actions.include?(:mark)
63
+ select_tag("batch_scope",
64
+ options_for_select(select_options, batch_scope || select_options.last[1]),
65
+ :class => "text_input")
66
+ end
67
+
68
+ ##
69
+ ## Search column override signatures
70
+ ##
71
+
72
+ def override_update_field?(column)
73
+ respond_to?(override_update_field(column))
74
+ end
75
+
76
+ # the naming convention for overriding form fields with helpers
77
+ def override_update_field(column)
78
+ "#{column.name}_update_column"
79
+ end
80
+
81
+ def override_update?(update_ui)
82
+ respond_to?(override_update(update_ui))
83
+ end
84
+
85
+ # the naming convention for overriding search input types with helpers
86
+ def override_update(update_ui)
87
+ "active_scaffold_update_#{update_ui}"
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,8 @@
1
+ ActionView::Base.class_eval do
2
+ include ActiveScaffold::Helpers::UpdateColumnHelpers
3
+ if ActiveScaffold.js_framework == :jquery
4
+ include ActiveScaffold::Helpers::DatepickerUpdateColumnHelpers
5
+ elsif ActiveScaffold.js_framework == :prototype
6
+ include ActiveScaffold::Helpers::CalendarDateSelectUpdateColumnHelpers
7
+ end
8
+ end
@@ -0,0 +1,10 @@
1
+ # Need to open the AS module carefully due to Rails 2.3 lazy loading
2
+ ActiveScaffold::Config::Core.class_eval do
3
+ ActionDispatch::Routing::ACTIVE_SCAFFOLD_CORE_ROUTING[:collection][:batch_edit] = :get
4
+ ActionDispatch::Routing::ACTIVE_SCAFFOLD_CORE_ROUTING[:collection][:batch_update] = :post
5
+ #not working because routing picks show route instead
6
+ #ActionDispatch::Routing::ACTIVE_SCAFFOLD_CORE_ROUTING[:collection][:batch_destroy] = :get
7
+ #you may define a route for your controller before resource routes
8
+ #match 'players/batch_destroy' => 'players#batch_destroy', :via => [:get]
9
+ ActionDispatch::Routing::ACTIVE_SCAFFOLD_CORE_ROUTING[:collection][:batch_destroy] = :delete
10
+ end
@@ -0,0 +1,9 @@
1
+ module ActiveScaffoldBatch
2
+ module Version
3
+ MAJOR = 3
4
+ MINOR = 0
5
+ PATCH = 0
6
+
7
+ STRING = [MAJOR, MINOR, PATCH].compact.join('.')
8
+ end
9
+ end
@@ -0,0 +1,27 @@
1
+ # Make sure that ActiveScaffold has already been included
2
+ ActiveScaffold rescue throw "should have included ActiveScaffold plug in first. Please make sure that this overwrite plugging comes alphabetically after the ActiveScaffold plug in"
3
+
4
+ # Load our overrides
5
+ require "#{File.dirname(__FILE__)}/active_scaffold_batch/config/core.rb"
6
+ require "#{File.dirname(__FILE__)}/active_scaffold/config/batch_update.rb"
7
+ require "#{File.dirname(__FILE__)}/active_scaffold/actions/batch_update.rb"
8
+ require "#{File.dirname(__FILE__)}/active_scaffold/helpers/view_helpers_override.rb"
9
+
10
+ module ActiveScaffoldBatch
11
+ def self.root
12
+ File.dirname(__FILE__) + "/.."
13
+ end
14
+ end
15
+
16
+
17
+ ##
18
+ ## Run the install assets script, too, just to make sure
19
+ ## But at least rescue the action in production
20
+ ##
21
+ Rails::Application.initializer("active_scaffold_batch.install_assets") do
22
+ begin
23
+ ActiveScaffoldAssets.copy_to_public(ActiveScaffoldBatch.root)
24
+ rescue
25
+ raise $! unless Rails.env == 'production'
26
+ end
27
+ end unless defined?(ACTIVE_SCAFFOLD_BATCH_INSTALLED) && ACTIVE_SCAFFOLD_BATCH_INSTALLED == :plugin
@@ -0,0 +1,2 @@
1
+ ACTIVE_SCAFFOLD_BATCH_INSTALLED = :gem
2
+ require 'active_scaffold_batch'
data/uninstall.rb ADDED
@@ -0,0 +1 @@
1
+ # see active_scaffold/uninstall.rb
metadata ADDED
@@ -0,0 +1,168 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: active_scaffold_batch_vho
3
+ version: !ruby/object:Gem::Version
4
+ hash: 7
5
+ prerelease: false
6
+ segments:
7
+ - 3
8
+ - 0
9
+ - 0
10
+ version: 3.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Volker Hochstein
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-01-26 00:00:00 +01:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ prerelease: false
23
+ name: shoulda
24
+ version_requirements: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ requirement: *id001
34
+ type: :development
35
+ - !ruby/object:Gem::Dependency
36
+ prerelease: false
37
+ name: bundler
38
+ version_requirements: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ hash: 23
44
+ segments:
45
+ - 1
46
+ - 0
47
+ - 0
48
+ version: 1.0.0
49
+ requirement: *id002
50
+ type: :development
51
+ - !ruby/object:Gem::Dependency
52
+ prerelease: false
53
+ name: jeweler
54
+ version_requirements: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ~>
58
+ - !ruby/object:Gem::Version
59
+ hash: 7
60
+ segments:
61
+ - 1
62
+ - 5
63
+ - 2
64
+ version: 1.5.2
65
+ requirement: *id003
66
+ type: :development
67
+ - !ruby/object:Gem::Dependency
68
+ prerelease: false
69
+ name: rcov
70
+ version_requirements: &id004 !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ hash: 3
76
+ segments:
77
+ - 0
78
+ version: "0"
79
+ requirement: *id004
80
+ type: :development
81
+ - !ruby/object:Gem::Dependency
82
+ prerelease: false
83
+ name: active_scaffold_vho
84
+ version_requirements: &id005 !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ hash: 7
90
+ segments:
91
+ - 3
92
+ - 0
93
+ version: "3.0"
94
+ requirement: *id005
95
+ type: :runtime
96
+ description: You want to destroy/update many records at once with activescaffold?
97
+ email: activescaffold@googlegroups.com
98
+ executables: []
99
+
100
+ extensions: []
101
+
102
+ extra_rdoc_files:
103
+ - LICENSE.txt
104
+ - README
105
+ files:
106
+ - .document
107
+ - LICENSE.txt
108
+ - README
109
+ - Rakefile
110
+ - frontends/default/views/_batch_update_form.html.erb
111
+ - frontends/default/views/_batch_update_form_attribute.html.erb
112
+ - frontends/default/views/_batch_update_form_attribute_scope.html.erb
113
+ - frontends/default/views/_batch_update_form_body.html.erb
114
+ - frontends/default/views/batch_update.html.erb
115
+ - frontends/default/views/on_batch_base.js.rjs
116
+ - frontends/default/views/on_batch_update.js.rjs
117
+ - init.rb
118
+ - lib/active_scaffold/actions/batch_base.rb
119
+ - lib/active_scaffold/actions/batch_destroy.rb
120
+ - lib/active_scaffold/actions/batch_update.rb
121
+ - lib/active_scaffold/config/batch_base.rb
122
+ - lib/active_scaffold/config/batch_destroy.rb
123
+ - lib/active_scaffold/config/batch_update.rb
124
+ - lib/active_scaffold/helpers/calendar_date_select_update_column_helpers.rb
125
+ - lib/active_scaffold/helpers/datepicker_update_column_helpers.rb
126
+ - lib/active_scaffold/helpers/update_column_helpers.rb
127
+ - lib/active_scaffold/helpers/view_helpers_override.rb
128
+ - lib/active_scaffold_batch.rb
129
+ - lib/active_scaffold_batch/config/core.rb
130
+ - lib/active_scaffold_batch/version.rb
131
+ - lib/active_scaffold_batch_vho.rb
132
+ - uninstall.rb
133
+ has_rdoc: true
134
+ homepage: http://github.com/vhochstein/active_scaffold_batch
135
+ licenses:
136
+ - MIT
137
+ post_install_message:
138
+ rdoc_options: []
139
+
140
+ require_paths:
141
+ - lib
142
+ required_ruby_version: !ruby/object:Gem::Requirement
143
+ none: false
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ hash: 3
148
+ segments:
149
+ - 0
150
+ version: "0"
151
+ required_rubygems_version: !ruby/object:Gem::Requirement
152
+ none: false
153
+ requirements:
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ hash: 3
157
+ segments:
158
+ - 0
159
+ version: "0"
160
+ requirements: []
161
+
162
+ rubyforge_project:
163
+ rubygems_version: 1.3.7
164
+ signing_key:
165
+ specification_version: 3
166
+ summary: Batch Processing for ActiveScaffold
167
+ test_files: []
168
+