active_scaffold_batch_vho 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/LICENSE.txt +20 -0
- data/README +0 -0
- data/Rakefile +55 -0
- data/frontends/default/views/_batch_update_form.html.erb +7 -0
- data/frontends/default/views/_batch_update_form_attribute.html.erb +12 -0
- data/frontends/default/views/_batch_update_form_attribute_scope.html.erb +9 -0
- data/frontends/default/views/_batch_update_form_body.html.erb +25 -0
- data/frontends/default/views/batch_update.html.erb +5 -0
- data/frontends/default/views/on_batch_base.js.rjs +6 -0
- data/frontends/default/views/on_batch_update.js.rjs +10 -0
- data/init.rb +9 -0
- data/lib/active_scaffold/actions/batch_base.rb +118 -0
- data/lib/active_scaffold/actions/batch_destroy.rb +72 -0
- data/lib/active_scaffold/actions/batch_update.rb +320 -0
- data/lib/active_scaffold/config/batch_base.rb +11 -0
- data/lib/active_scaffold/config/batch_destroy.rb +54 -0
- data/lib/active_scaffold/config/batch_update.rb +45 -0
- data/lib/active_scaffold/helpers/calendar_date_select_update_column_helpers.rb +33 -0
- data/lib/active_scaffold/helpers/datepicker_update_column_helpers.rb +29 -0
- data/lib/active_scaffold/helpers/update_column_helpers.rb +91 -0
- data/lib/active_scaffold/helpers/view_helpers_override.rb +8 -0
- data/lib/active_scaffold_batch/config/core.rb +10 -0
- data/lib/active_scaffold_batch/version.rb +9 -0
- data/lib/active_scaffold_batch.rb +27 -0
- data/lib/active_scaffold_batch_vho.rb +2 -0
- data/uninstall.rb +1 -0
- metadata +168 -0
data/.document
ADDED
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,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,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,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(" ").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(" ").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,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
|
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
|
+
|