active_scaffold_duplicate 1.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/LICENSE.txt +20 -0
- data/README.textile +98 -0
- data/app/views/active_scaffold_overrides/clone.js.erb~ +24 -0
- data/app/views/active_scaffold_overrides/duplicate.js.erb +17 -0
- data/app/views/active_scaffold_overrides/duplicate.js.erb~ +19 -0
- data/config/locales/en.yml +3 -0
- data/config/locales/es.yml +3 -0
- data/lib/active_scaffold/actions/clone.rb~ +57 -0
- data/lib/active_scaffold/actions/duplicate.rb +62 -0
- data/lib/active_scaffold/actions/duplicate.rb~ +59 -0
- data/lib/active_scaffold/config/clone.rb~ +43 -0
- data/lib/active_scaffold/config/duplicate.rb +44 -0
- data/lib/active_scaffold/config/duplicate.rb~ +44 -0
- data/lib/active_scaffold_clone.rb~ +24 -0
- data/lib/active_scaffold_duplicate.rb +18 -0
- data/lib/active_scaffold_duplicate.rb~ +18 -0
- data/lib/active_scaffold_duplicate/config/core.rb +4 -0
- data/lib/active_scaffold_duplicate/config/core.rb~ +4 -0
- data/lib/active_scaffold_duplicate/core.rb~ +13 -0
- data/lib/active_scaffold_duplicate/engine.rb +4 -0
- data/lib/active_scaffold_duplicate/engine.rb~ +4 -0
- data/lib/active_scaffold_duplicate/version.rb +9 -0
- data/lib/active_scaffold_duplicate/version.rb~ +9 -0
- data/test/auto_models_controller_test.rb +52 -0
- data/test/config_test.rb +59 -0
- data/test/controllers/auto_models_controller.rb +3 -0
- data/test/controllers/models_controller.rb +3 -0
- data/test/controllers/sortable_models_controller.rb +7 -0
- data/test/models/auto_model.rb +8 -0
- data/test/models/model.rb +2 -0
- data/test/router_test.rb +5 -0
- data/test/schema.rb +9 -0
- data/test/test_helper.rb +48 -0
- metadata +167 -0
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Sergio Cambra
|
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.textile
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
h1. Drag-Drop Sortable for ActiveScaffold
|
2
|
+
|
3
|
+
Currently, this gem is compatible with rails 3.x and ActiveScaffold 3.3.x gems.
|
4
|
+
|
5
|
+
h2. Overview
|
6
|
+
|
7
|
+
This gem adds an action to clone records. By default will only set attributes and belongs_to associations. You must override initialize_dup in your model or define a method to clone the record and set in conf.duplicate.method.
|
8
|
+
|
9
|
+
h2. Installation
|
10
|
+
|
11
|
+
You'll need at least ActiveScaffold 3.3.x to use this, and rails 3.x
|
12
|
+
|
13
|
+
|
14
|
+
<pre>
|
15
|
+
gem install active_scaffold_duplicate
|
16
|
+
</pre>
|
17
|
+
|
18
|
+
h2. Usage
|
19
|
+
|
20
|
+
h4. Step 1
|
21
|
+
|
22
|
+
Override intialize_dup in the model:
|
23
|
+
|
24
|
+
<pre>
|
25
|
+
# app/models/bill.rb
|
26
|
+
class Bill < ActiveRecord::Base
|
27
|
+
belongs_to :customer
|
28
|
+
has_many :items
|
29
|
+
|
30
|
+
def initialize_dup(other)
|
31
|
+
super
|
32
|
+
self.items = other.items.map(&:dup)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
</pre>
|
36
|
+
|
37
|
+
h4. Step 2
|
38
|
+
|
39
|
+
Add duplicate action.
|
40
|
+
|
41
|
+
<pre>
|
42
|
+
class BillsController < ApplicationController
|
43
|
+
active_scaffold do |conf|
|
44
|
+
conf.actions << :duplicate
|
45
|
+
end
|
46
|
+
end
|
47
|
+
</pre>
|
48
|
+
|
49
|
+
h4. Step 3
|
50
|
+
|
51
|
+
Change method to :get in link if you want to display create form instead of cloning record.
|
52
|
+
|
53
|
+
<pre>
|
54
|
+
class BillsController < ApplicationController
|
55
|
+
active_scaffold do |conf|
|
56
|
+
conf.duplicate.link.options.method = :get
|
57
|
+
end
|
58
|
+
end
|
59
|
+
</pre>
|
60
|
+
|
61
|
+
Also you can change it globally.
|
62
|
+
|
63
|
+
<pre>
|
64
|
+
class ApplicationController < ActionController::Base
|
65
|
+
active_scaffold.set_defaults do |conf|
|
66
|
+
conf.duplicate.link.options.method = :get
|
67
|
+
end
|
68
|
+
end
|
69
|
+
</pre>
|
70
|
+
|
71
|
+
|
72
|
+
If you use :post method, you can enable refresh_list to refresh the list instead of only adding new record at top, or set action_after_clone to open edit form for example:
|
73
|
+
|
74
|
+
<pre>
|
75
|
+
conf.duplicate.refresh_list = true
|
76
|
+
conf.duplicate.action_after_clone = :edit
|
77
|
+
</pre>
|
78
|
+
|
79
|
+
h2. Support
|
80
|
+
|
81
|
+
If you have issues installing the gem, search / post to the "Active Scaffold":http://groups.google.com/group/activescaffold forum or "Create an issue":http://github.com/activescaffold/active_scaffold_clone/issues
|
82
|
+
|
83
|
+
h2. Contributing
|
84
|
+
|
85
|
+
Fork, hack, push, and request a pull:
|
86
|
+
|
87
|
+
http://github.com/activescaffold/active_scaffold_duplicate/
|
88
|
+
|
89
|
+
h2. License
|
90
|
+
|
91
|
+
Released under the MIT license (included).
|
92
|
+
|
93
|
+
h2. Author
|
94
|
+
|
95
|
+
Contact me:
|
96
|
+
<pre>
|
97
|
+
Sergio Cambra - irb(main):001:0> ( 'sergioATprogramatica._see_s'.gsub('_see_', 'e').gsub('AT', '@') )
|
98
|
+
</pre>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
try {
|
2
|
+
<% link_selector = "#{element_form_id(:action => :clone)}"
|
3
|
+
insert_at ||= :top %>
|
4
|
+
var action_link = ActiveScaffold.find_action_link('<%= link_selector%>');
|
5
|
+
action_link.update_flash_messages('<%=escape_javascript(render(:partial => 'messages'))%>');
|
6
|
+
<% if controller.send :successful? %>
|
7
|
+
<% if (active_scaffold_config.clone.refresh_list) %>
|
8
|
+
<%= render :partial => 'refresh_list' %>
|
9
|
+
<% else %>
|
10
|
+
<% new_row = render :partial => 'list_record', :locals => {:record => @record} %>
|
11
|
+
ActiveScaffold.create_record_row(action_link.scaffold(),'<%= escape_javascript(new_row) %>', <%= {:insert_at => insert_at}.to_json.html_safe %>);
|
12
|
+
<%= render :partial => 'update_calculations', :formats => [:js] %>
|
13
|
+
<% end %>
|
14
|
+
|
15
|
+
action_link.close();
|
16
|
+
<% if (active_scaffold_config.clone.action_after_clone) %>
|
17
|
+
var link = ActiveScaffold.find_action_link('<%= action_link_id active_scaffold_config.clone.action_after_clone, @record.id %>');
|
18
|
+
if (link) (function() { link.open() })<%= '.defer' if ActiveScaffold.js_framework == :prototype %>();
|
19
|
+
<% end %>
|
20
|
+
<% else %>
|
21
|
+
ActiveScaffold.replace('<%= form_selector %>','<%= escape_javascript(render(:partial => 'create_form', :locals => {:xhr => true})) %>');
|
22
|
+
ActiveScaffold.scroll_to('<%= form_selector %>', true);
|
23
|
+
<% end %>
|
24
|
+
} catch (e) { alert('RJS error:\n\n' + e.toString());}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
try {
|
2
|
+
<% insert_at ||= :top %>
|
3
|
+
<%= render :partial => 'update_messages', :locals => {:messages_id => active_scaffold_messages_id} %>
|
4
|
+
<% if controller.send :successful? %>
|
5
|
+
<% if (active_scaffold_config.duplicate.refresh_list) %>
|
6
|
+
<%= render :partial => 'refresh_list' %>
|
7
|
+
<% else %>
|
8
|
+
<% new_row = render :partial => 'list_record', :locals => {:record => @record} %>
|
9
|
+
ActiveScaffold.create_record_row('<%= active_scaffold_id %>','<%= escape_javascript(new_row) %>', <%= {:insert_at => insert_at}.to_json.html_safe %>);
|
10
|
+
<%= render :partial => 'update_calculations', :formats => [:js] %>
|
11
|
+
<% end %>
|
12
|
+
<% if (active_scaffold_config.duplicate.action_after_clone) %>
|
13
|
+
var link = ActiveScaffold.find_action_link('<%= action_link_id active_scaffold_config.duplicate.action_after_clone, @record.id %>');
|
14
|
+
if (link) (function() { link.open() })<%= '.defer' if ActiveScaffold.js_framework == :prototype %>();
|
15
|
+
<% end %>
|
16
|
+
<% end %>
|
17
|
+
} catch (e) { alert('RJS error:\n\n' + e.toString());}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
try {
|
2
|
+
<% insert_at ||= :top %>
|
3
|
+
<%= render :partial => 'update_messages', :locals => {:messages_id => active_scaffold_messages_id} %>
|
4
|
+
<% if controller.send :successful? %>
|
5
|
+
<% if (active_scaffold_config.duplicate.refresh_list) %>
|
6
|
+
<%= render :partial => 'refresh_list' %>
|
7
|
+
<% else %>
|
8
|
+
<% new_row = render :partial => 'list_record', :locals => {:record => @record} %>
|
9
|
+
ActiveScaffold.create_record_row('<%= active_scaffold_id %>','<%= escape_javascript(new_row) %>', <%= {:insert_at => insert_at}.to_json.html_safe %>);
|
10
|
+
<%= render :partial => 'update_calculations', :formats => [:js] %>
|
11
|
+
<% end %>
|
12
|
+
|
13
|
+
action_link.close();
|
14
|
+
<% if (active_scaffold_config.duplicate.action_after_clone) %>
|
15
|
+
var link = ActiveScaffold.find_action_link('<%= action_link_id active_scaffold_config.duplicate.action_after_clone, @record.id %>');
|
16
|
+
if (link) (function() { link.open() })<%= '.defer' if ActiveScaffold.js_framework == :prototype %>();
|
17
|
+
<% end %>
|
18
|
+
<% end %>
|
19
|
+
} catch (e) { alert('RJS error:\n\n' + e.toString());}
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module ActiveScaffold::Actions
|
2
|
+
module Clone
|
3
|
+
def self.included(base)
|
4
|
+
base.before_filter :clone_authorized_filter, :only => :clone
|
5
|
+
end
|
6
|
+
|
7
|
+
def clone
|
8
|
+
old_record = find_if_allowed(params[:id], :read)
|
9
|
+
@record = old_record.send(active_scaffold_config.clone.method)
|
10
|
+
self.successful = @record.persisted?
|
11
|
+
respond_to_action(:clone)
|
12
|
+
end
|
13
|
+
|
14
|
+
protected
|
15
|
+
def clone_authorized?
|
16
|
+
authorized_for?(:crud_type => :create, :action => :clone)
|
17
|
+
end
|
18
|
+
|
19
|
+
def clone_respond_to_html
|
20
|
+
if successful?
|
21
|
+
flash[:info] = as_(:created_model, :model => @record.to_label)
|
22
|
+
if action = active_scaffold_config.clone.action_after_clone
|
23
|
+
redirect_to params_for(:action => action, :id => @record.id)
|
24
|
+
else
|
25
|
+
return_to_main
|
26
|
+
end
|
27
|
+
else
|
28
|
+
return_to_main
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def clone_respond_to_js
|
33
|
+
render :action => 'clone'
|
34
|
+
end
|
35
|
+
|
36
|
+
def clone_respond_to_xml
|
37
|
+
render :xml => response_object.to_xml(:only => active_scaffold_config.create.columns.names), :content_type => Mime::XML, :status => response_status, :location => response_location
|
38
|
+
end
|
39
|
+
|
40
|
+
def clone_respond_to_json
|
41
|
+
render :text => response_object.to_json(:only => active_scaffold_config.create.columns.names), :content_type => Mime::JSON, :status => response_status, :location => response_location
|
42
|
+
end
|
43
|
+
|
44
|
+
def clone_respond_to_yaml
|
45
|
+
render :text => Hash.from_xml(response_object.to_xml(:only => active_scaffold_config.create.columns.names)).to_yaml, :content_type => Mime::YAML, :status => response_status, :location => response_location
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
def clone_authorized_filter
|
50
|
+
link = active_scaffold_config.clone.link || active_scaffold_config.clone.class.link
|
51
|
+
raise ActiveScaffold::ActionNotAllowed unless self.send(link.security_method)
|
52
|
+
end
|
53
|
+
def clone_formats
|
54
|
+
(default_formats + active_scaffold_config.formats + active_scaffold_config.clone.formats).uniq
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module ActiveScaffold::Actions
|
2
|
+
module Duplicate
|
3
|
+
def self.included(base)
|
4
|
+
base.before_filter :duplicate_authorized_filter, :only => :duplicate
|
5
|
+
end
|
6
|
+
|
7
|
+
def duplicate
|
8
|
+
old_record = find_if_allowed(params[:id], :read)
|
9
|
+
@record = old_record.send(active_scaffold_config.duplicate.method)
|
10
|
+
if request.post?
|
11
|
+
self.successful = @record.save
|
12
|
+
respond_to_action(:duplicate)
|
13
|
+
else
|
14
|
+
respond_to_action(:new)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
def duplicate_authorized?(record = nil)
|
20
|
+
(record || self).authorized_for?(:crud_type => :create, :action => :duplicate)
|
21
|
+
end
|
22
|
+
|
23
|
+
def duplicate_respond_to_html
|
24
|
+
if successful?
|
25
|
+
flash[:info] = as_(:created_model, :model => @record.to_label)
|
26
|
+
if action = active_scaffold_config.duplicate.action_after_clone
|
27
|
+
redirect_to params_for(:action => action, :id => @record.id)
|
28
|
+
else
|
29
|
+
return_to_main
|
30
|
+
end
|
31
|
+
else
|
32
|
+
return_to_main
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def duplicate_respond_to_js
|
37
|
+
do_refresh_list if successful? && active_scaffold_config.duplicate.refresh_list
|
38
|
+
render :action => 'duplicate'
|
39
|
+
end
|
40
|
+
|
41
|
+
def duplicate_respond_to_xml
|
42
|
+
render :xml => response_object.to_xml(:only => active_scaffold_config.create.columns.names), :content_type => Mime::XML, :status => response_status, :location => response_location
|
43
|
+
end
|
44
|
+
|
45
|
+
def duplicate_respond_to_json
|
46
|
+
render :text => response_object.to_json(:only => active_scaffold_config.create.columns.names), :content_type => Mime::JSON, :status => response_status, :location => response_location
|
47
|
+
end
|
48
|
+
|
49
|
+
def duplicate_respond_to_yaml
|
50
|
+
render :text => Hash.from_xml(response_object.to_xml(:only => active_scaffold_config.create.columns.names)).to_yaml, :content_type => Mime::YAML, :status => response_status, :location => response_location
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
def duplicate_authorized_filter
|
55
|
+
link = active_scaffold_config.duplicate.link || active_scaffold_config.duplicate.class.link
|
56
|
+
raise ActiveScaffold::ActionNotAllowed unless self.send(link.security_method)
|
57
|
+
end
|
58
|
+
def duplicate_formats
|
59
|
+
(default_formats + active_scaffold_config.formats + active_scaffold_config.duplicate.formats).uniq
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module ActiveScaffold::Actions
|
2
|
+
module Duplicate
|
3
|
+
def self.included(base)
|
4
|
+
base.before_filter :duplicate_authorized_filter, :only => :duplicate
|
5
|
+
end
|
6
|
+
|
7
|
+
def duplicate
|
8
|
+
old_record = find_if_allowed(params[:id], :read)
|
9
|
+
@record = old_record.send(active_scaffold_config.duplicate.method)
|
10
|
+
debugger
|
11
|
+
self.successful = @record.save
|
12
|
+
respond_to_action(:duplicate)
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
def duplicate_authorized?(record = nil)
|
17
|
+
(record || self).authorized_for?(:crud_type => :create, :action => :duplicate)
|
18
|
+
end
|
19
|
+
|
20
|
+
def duplicate_respond_to_html
|
21
|
+
if successful?
|
22
|
+
flash[:info] = as_(:created_model, :model => @record.to_label)
|
23
|
+
if action = active_scaffold_config.duplicate.action_after_clone
|
24
|
+
redirect_to params_for(:action => action, :id => @record.id)
|
25
|
+
else
|
26
|
+
return_to_main
|
27
|
+
end
|
28
|
+
else
|
29
|
+
return_to_main
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def duplicate_respond_to_js
|
34
|
+
do_refresh_list if successful? && active_scaffold_config.duplicate.refresh_list
|
35
|
+
render :action => 'duplicate'
|
36
|
+
end
|
37
|
+
|
38
|
+
def duplicate_respond_to_xml
|
39
|
+
render :xml => response_object.to_xml(:only => active_scaffold_config.create.columns.names), :content_type => Mime::XML, :status => response_status, :location => response_location
|
40
|
+
end
|
41
|
+
|
42
|
+
def duplicate_respond_to_json
|
43
|
+
render :text => response_object.to_json(:only => active_scaffold_config.create.columns.names), :content_type => Mime::JSON, :status => response_status, :location => response_location
|
44
|
+
end
|
45
|
+
|
46
|
+
def duplicate_respond_to_yaml
|
47
|
+
render :text => Hash.from_xml(response_object.to_xml(:only => active_scaffold_config.create.columns.names)).to_yaml, :content_type => Mime::YAML, :status => response_status, :location => response_location
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
def duplicate_authorized_filter
|
52
|
+
link = active_scaffold_config.duplicate.link || active_scaffold_config.duplicate.class.link
|
53
|
+
raise ActiveScaffold::ActionNotAllowed unless self.send(link.security_method)
|
54
|
+
end
|
55
|
+
def duplicate_formats
|
56
|
+
(default_formats + active_scaffold_config.formats + active_scaffold_config.duplicate.formats).uniq
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module ActiveScaffold::Config
|
2
|
+
class Clone < Base
|
3
|
+
self.crud_type = :create
|
4
|
+
|
5
|
+
def initialize(core_config)
|
6
|
+
@core = core_config
|
7
|
+
self.method = self.class.method
|
8
|
+
self.link = self.class.link.clone
|
9
|
+
self.action_after_clone = self.class.action_after_clone
|
10
|
+
end
|
11
|
+
|
12
|
+
# the method to clone records
|
13
|
+
cattr_accessor :method
|
14
|
+
@@method = :dup
|
15
|
+
|
16
|
+
# which action render after clone
|
17
|
+
cattr_accessor :action_after_clone
|
18
|
+
@@action_after_clone = nil
|
19
|
+
|
20
|
+
# whether we should refresh list after clone or not
|
21
|
+
cattr_accessor :refresh_list
|
22
|
+
@@refresh_list = false
|
23
|
+
|
24
|
+
# the ActionLink for this action
|
25
|
+
cattr_accessor :link
|
26
|
+
@@link = ActiveScaffold::DataStructures::ActionLink.new('clone', :type => :member, :method => :post, :position => false, :security_method => :clone_authorized?, :ignore_method => :clone_ignore?)
|
27
|
+
|
28
|
+
# instance-level configuration
|
29
|
+
# ----------------------------
|
30
|
+
|
31
|
+
# the ActionLink for this action
|
32
|
+
attr_accessor :link
|
33
|
+
|
34
|
+
# the method to clone records
|
35
|
+
attr_accessor :method
|
36
|
+
|
37
|
+
# which action render after clone
|
38
|
+
attr_accessor :action_after_clone
|
39
|
+
|
40
|
+
# whether we should refresh list after clone or not
|
41
|
+
attr_accessor :refresh_list
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module ActiveScaffold::Config
|
2
|
+
class Duplicate < Base
|
3
|
+
self.crud_type = :create
|
4
|
+
|
5
|
+
def initialize(core_config)
|
6
|
+
@core = core_config
|
7
|
+
self.method = self.class.method
|
8
|
+
self.link = self.class.link.clone
|
9
|
+
self.action_after_clone = self.class.action_after_clone
|
10
|
+
self.refresh_list = self.class.refresh_list
|
11
|
+
end
|
12
|
+
|
13
|
+
# the method to clone records
|
14
|
+
cattr_accessor :method
|
15
|
+
@@method = :dup
|
16
|
+
|
17
|
+
# which action render after clone with post
|
18
|
+
cattr_accessor :action_after_clone
|
19
|
+
@@action_after_clone = nil
|
20
|
+
|
21
|
+
# whether we should refresh list after clone or not
|
22
|
+
cattr_accessor :refresh_list
|
23
|
+
@@refresh_list = false
|
24
|
+
|
25
|
+
# the ActionLink for this action
|
26
|
+
cattr_accessor :link
|
27
|
+
@@link = ActiveScaffold::DataStructures::ActionLink.new(:duplicate, :type => :member, :method => :post, :position => false, :security_method => :duplicate_authorized?, :ignore_method => :duplicate_ignore?)
|
28
|
+
|
29
|
+
# instance-level configuration
|
30
|
+
# ----------------------------
|
31
|
+
|
32
|
+
# the ActionLink for this action
|
33
|
+
attr_accessor :link
|
34
|
+
|
35
|
+
# the method to clone records
|
36
|
+
attr_accessor :method
|
37
|
+
|
38
|
+
# which action render after clone with post
|
39
|
+
attr_accessor :action_after_clone
|
40
|
+
|
41
|
+
# whether we should refresh list after clone or not
|
42
|
+
attr_accessor :refresh_list
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module ActiveScaffold::Config
|
2
|
+
class Duplicate < Base
|
3
|
+
self.crud_type = :create
|
4
|
+
|
5
|
+
def initialize(core_config)
|
6
|
+
@core = core_config
|
7
|
+
self.method = self.class.method
|
8
|
+
self.link = self.class.link.clone
|
9
|
+
self.action_after_clone = self.class.action_after_clone
|
10
|
+
self.refresh_list = self.class.refresh_list
|
11
|
+
end
|
12
|
+
|
13
|
+
# the method to clone records
|
14
|
+
cattr_accessor :method
|
15
|
+
@@method = :dup
|
16
|
+
|
17
|
+
# which action render after clone
|
18
|
+
cattr_accessor :action_after_clone
|
19
|
+
@@action_after_clone = nil
|
20
|
+
|
21
|
+
# whether we should refresh list after clone or not
|
22
|
+
cattr_accessor :refresh_list
|
23
|
+
@@refresh_list = false
|
24
|
+
|
25
|
+
# the ActionLink for this action
|
26
|
+
cattr_accessor :link
|
27
|
+
@@link = ActiveScaffold::DataStructures::ActionLink.new(:duplicate, :label => :clone, :type => :member, :method => :post, :position => false, :security_method => :duplicate_authorized?, :ignore_method => :duplicate_ignore?)
|
28
|
+
|
29
|
+
# instance-level configuration
|
30
|
+
# ----------------------------
|
31
|
+
|
32
|
+
# the ActionLink for this action
|
33
|
+
attr_accessor :link
|
34
|
+
|
35
|
+
# the method to clone records
|
36
|
+
attr_accessor :method
|
37
|
+
|
38
|
+
# which action render after clone
|
39
|
+
attr_accessor :action_after_clone
|
40
|
+
|
41
|
+
# whether we should refresh list after clone or not
|
42
|
+
attr_accessor :refresh_list
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "active_scaffold_clone/config/core.rb"
|
2
|
+
require "active_scaffold_clone/engine.rb"
|
3
|
+
|
4
|
+
module ActiveScaffoldClone
|
5
|
+
def self.root
|
6
|
+
File.dirname(__FILE__) + "/.."
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module ActiveScaffold
|
11
|
+
module Actions
|
12
|
+
ActiveScaffold.autoload_subdir('actions', self, File.dirname(__FILE__))
|
13
|
+
end
|
14
|
+
|
15
|
+
module Config
|
16
|
+
ActiveScaffold.autoload_subdir('config', self, File.dirname(__FILE__))
|
17
|
+
end
|
18
|
+
|
19
|
+
module Helpers
|
20
|
+
ActiveScaffold.autoload_subdir('helpers', self, File.dirname(__FILE__))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
ActiveScaffold::Config::Core.send :include, ActiveScaffoldClone::Core
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "active_scaffold_duplicate/config/core.rb"
|
2
|
+
require "active_scaffold_duplicate/engine.rb"
|
3
|
+
|
4
|
+
module ActiveScaffoldDuplicate
|
5
|
+
def self.root
|
6
|
+
File.dirname(__FILE__) + "/.."
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module ActiveScaffold
|
11
|
+
module Actions
|
12
|
+
ActiveScaffold.autoload_subdir('actions', self, File.dirname(__FILE__))
|
13
|
+
end
|
14
|
+
|
15
|
+
module Config
|
16
|
+
ActiveScaffold.autoload_subdir('config', self, File.dirname(__FILE__))
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "active_scaffold_duplicate/config/core.rb"
|
2
|
+
require "active_scaffold_duplicate/engine.rb"
|
3
|
+
|
4
|
+
module ActiveScaffoldClone
|
5
|
+
def self.root
|
6
|
+
File.dirname(__FILE__) + "/.."
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module ActiveScaffold
|
11
|
+
module Actions
|
12
|
+
ActiveScaffold.autoload_subdir('actions', self, File.dirname(__FILE__))
|
13
|
+
end
|
14
|
+
|
15
|
+
module Config
|
16
|
+
ActiveScaffold.autoload_subdir('config', self, File.dirname(__FILE__))
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module ActiveScaffoldSortable
|
2
|
+
module Core
|
3
|
+
def self.included(base)
|
4
|
+
base.alias_method_chain :initialize, :sortable
|
5
|
+
end
|
6
|
+
|
7
|
+
def initialize_with_sortable(model_id)
|
8
|
+
initialize_without_sortable(model_id)
|
9
|
+
# seems some rubies are returning strings in instance_methods and other symbols...
|
10
|
+
self.actions << :sortable if !(model.instance_methods & ['acts_as_list_class', :acts_as_list_class, 'nested_set_scope', :nested_set_scope]).empty?
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'test_helper.rb'
|
2
|
+
|
3
|
+
class AutoModelsControllerTest < ActionController::TestCase
|
4
|
+
@@sortable_regexp = Regexp.new('Sortable.create\("as_auto_models-tbody", \{format:/\^\[\^_-\]\(\?:\[A-Za-z0-9_-\]\*\)-\(\.\*\)-row\$/, onUpdate:function\(\)\{new Ajax.Request\(\'/auto_models/reorder\', \{asynchronous:true, evalScripts:true, parameters:Sortable.serialize\("as_auto_models-tbody"\) \+ \'&controller=\' \+ encodeURIComponent\(\'auto_models\'\)\}\)\}, tag:\'tr\'\}\)')
|
5
|
+
setup { AutoModel.create :name => 'test', :position => 1 }
|
6
|
+
|
7
|
+
context "reordering" do
|
8
|
+
setup do
|
9
|
+
updates = sequence(:updates)
|
10
|
+
AutoModel.expects(:update_all).with({:position => 1}, 'id' => '2').in_sequence(updates)
|
11
|
+
AutoModel.expects(:update_all).with({:position => 2}, 'id' => '1').in_sequence(updates)
|
12
|
+
xhr :post, :reorder, :'as_auto_models-tbody' => ['2', '1']
|
13
|
+
end
|
14
|
+
should_respond_with :success
|
15
|
+
should_render_template :reorder
|
16
|
+
should "update stripe" do
|
17
|
+
assert_equal 'ActiveScaffold.stripe(\'as_auto_models-tbody\');', @response.body
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "listing" do
|
22
|
+
setup { get :index }
|
23
|
+
should "render record with sortable class" do
|
24
|
+
assert_select '.records tr.record.sortable'
|
25
|
+
end
|
26
|
+
should "render sortable script" do
|
27
|
+
assert_select 'script[type=text/javascript]', @@sortable_regexp
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "creating" do
|
32
|
+
setup { xhr :post, :create, :record => {:name => 'test2', :position => 2} }
|
33
|
+
should_respond_with :success
|
34
|
+
should "insert at top" do
|
35
|
+
assert_match "$(\"as_auto_models-tbody\").insert(\"as_auto_models-list-#{assigns(:record).id}-row\");", @response.body
|
36
|
+
end
|
37
|
+
should "update stripe" do
|
38
|
+
assert_match 'ActiveScaffold.stripe(\'as_auto_models-tbody\');', @response.body
|
39
|
+
end
|
40
|
+
should "update sortable" do
|
41
|
+
assert_match @@sortable_regexp, @response.body
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "updating" do
|
46
|
+
setup { xhr :put, :update, :id => 1, :record => {:name => 'test updated'} }
|
47
|
+
should_respond_with :success
|
48
|
+
should "update sortable" do
|
49
|
+
assert_match @@sortable_regexp, @response.body
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/test/config_test.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'test_helper.rb'
|
2
|
+
|
3
|
+
class ConfigTest < Test::Unit::TestCase
|
4
|
+
def test_not_enable_sortable
|
5
|
+
assert !ModelsController.active_scaffold_config.actions.include?(:sortable)
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_auto_enable_sortable
|
9
|
+
assert AutoModelsController.active_scaffold_config.actions.include?(:sortable)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_manual_enable_sortable
|
13
|
+
assert SortableModelsController.active_scaffold_config.actions.include?(:sortable)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_position_column
|
17
|
+
assert_equal :position, AutoModelsController.active_scaffold_config.sortable.column.name
|
18
|
+
assert_equal :name, SortableModelsController.active_scaffold_config.sortable.column.name
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_position_column_not_included
|
22
|
+
assert !AutoModelsController.active_scaffold_config.list.columns.include?(:position)
|
23
|
+
assert !AutoModelsController.active_scaffold_config.update.columns.include?(:position)
|
24
|
+
assert !AutoModelsController.active_scaffold_config.create.columns.include?(:position)
|
25
|
+
assert !AutoModelsController.active_scaffold_config.show.columns.include?(:position)
|
26
|
+
assert !AutoModelsController.active_scaffold_config.subform.columns.include?(:position)
|
27
|
+
assert !AutoModelsController.active_scaffold_config.search.columns.include?(:position)
|
28
|
+
|
29
|
+
assert !SortableModelsController.active_scaffold_config.list.columns.include?(:name)
|
30
|
+
assert !SortableModelsController.active_scaffold_config.update.columns.include?(:name)
|
31
|
+
assert !SortableModelsController.active_scaffold_config.create.columns.include?(:name)
|
32
|
+
assert !SortableModelsController.active_scaffold_config.show.columns.include?(:name)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_sorting
|
36
|
+
assert_equal('"models"."id" ASC', ModelsController.active_scaffold_config.list.sorting.clause)
|
37
|
+
assert ModelsController.active_scaffold_config.columns[:name].sortable?
|
38
|
+
assert ModelsController.active_scaffold_config.columns[:position].sortable?
|
39
|
+
|
40
|
+
assert_equal('"models"."position" ASC', AutoModelsController.active_scaffold_config.list.sorting.clause)
|
41
|
+
assert !AutoModelsController.active_scaffold_config.columns[:name].sortable?
|
42
|
+
|
43
|
+
assert_equal('"models"."name" ASC', SortableModelsController.active_scaffold_config.list.sorting.clause)
|
44
|
+
assert !SortableModelsController.active_scaffold_config.columns[:position].sortable?
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_pagination
|
48
|
+
assert ModelsController.active_scaffold_config.list.pagination
|
49
|
+
assert !AutoModelsController.active_scaffold_config.list.pagination
|
50
|
+
assert !SortableModelsController.active_scaffold_config.list.pagination
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_active_scaffold_paths
|
54
|
+
path = File.join(Rails.root, 'vendor/plugins/active_scaffold_sortable/frontends/default/views')
|
55
|
+
assert !ModelsController.active_scaffold_paths.include?(path)
|
56
|
+
assert AutoModelsController.active_scaffold_paths.include?(path)
|
57
|
+
assert SortableModelsController.active_scaffold_paths.include?(path)
|
58
|
+
end
|
59
|
+
end
|
data/test/router_test.rb
ADDED
data/test/schema.rb
ADDED
data/test/test_helper.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
ENV["RAILS_ENV"] = "test"
|
3
|
+
|
4
|
+
require 'test/unit'
|
5
|
+
# You can use "rake test AR_VERSION=2.0.5" to test against 2.0.5, for example.
|
6
|
+
# The default is to use the latest installed ActiveRecord.
|
7
|
+
if ENV["AR_VERSION"]
|
8
|
+
gem 'activerecord', "#{ENV["AR_VERSION"]}"
|
9
|
+
gem 'actionpack', "#{ENV["AR_VERSION"]}"
|
10
|
+
gem 'activesupport', "#{ENV["AR_VERSION"]}"
|
11
|
+
end
|
12
|
+
require 'rubygems'
|
13
|
+
require 'active_record'
|
14
|
+
require 'action_controller'
|
15
|
+
require 'action_view/test_case'
|
16
|
+
require 'action_mailer'
|
17
|
+
require 'active_support'
|
18
|
+
require 'initializer'
|
19
|
+
ActionController::Base::logger = ActiveSupport::BufferedLogger.new(Tempfile.new('log').path)
|
20
|
+
|
21
|
+
RAILS_ROOT = File.join(File.dirname(__FILE__), '../../../..')
|
22
|
+
Rails.configuration = Rails::Configuration.new
|
23
|
+
|
24
|
+
require 'shoulda'
|
25
|
+
require 'shoulda/rails'
|
26
|
+
require 'mocha'
|
27
|
+
begin
|
28
|
+
require 'redgreen'
|
29
|
+
rescue LoadError
|
30
|
+
end
|
31
|
+
|
32
|
+
ActiveSupport::Dependencies.load_paths = %w(test/models test/controllers lib ../active_scaffold/lib).map {|dir| File.dirname(__FILE__) + "/../#{dir}"}
|
33
|
+
$:.unshift *ActiveSupport::Dependencies.load_paths
|
34
|
+
|
35
|
+
require File.join(File.dirname(__FILE__), '../../active_scaffold/environment')
|
36
|
+
require 'sortable'
|
37
|
+
|
38
|
+
ActionController::Routing::Routes.draw do |map|
|
39
|
+
map.root :controller => 'home'
|
40
|
+
map.resources :sortable_models, :active_scaffold => true
|
41
|
+
map.resources :auto_models, :active_scaffold => true
|
42
|
+
map.resources :models, :active_scaffold => true
|
43
|
+
end
|
44
|
+
|
45
|
+
ActiveRecord::Base.establish_connection :adapter => "sqlite3", :database => ":memory:"
|
46
|
+
silence_stream(STDOUT) do
|
47
|
+
load(File.dirname(__FILE__) + "/schema.rb")
|
48
|
+
end
|
metadata
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: active_scaffold_duplicate
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
- 0
|
10
|
+
version: 1.0.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Sergio Cambra
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-12-18 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
type: :development
|
22
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
23
|
+
none: false
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
hash: 3
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
version_requirements: *id001
|
32
|
+
prerelease: false
|
33
|
+
name: shoulda
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
type: :development
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
hash: 23
|
42
|
+
segments:
|
43
|
+
- 1
|
44
|
+
- 0
|
45
|
+
- 0
|
46
|
+
version: 1.0.0
|
47
|
+
version_requirements: *id002
|
48
|
+
prerelease: false
|
49
|
+
name: bundler
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
type: :development
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 3
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
version_requirements: *id003
|
62
|
+
prerelease: false
|
63
|
+
name: rcov
|
64
|
+
- !ruby/object:Gem::Dependency
|
65
|
+
type: :runtime
|
66
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
hash: -615719623
|
72
|
+
segments:
|
73
|
+
- 3
|
74
|
+
- 3
|
75
|
+
- 0
|
76
|
+
- rc
|
77
|
+
version: 3.3.0.rc
|
78
|
+
version_requirements: *id004
|
79
|
+
prerelease: false
|
80
|
+
name: active_scaffold
|
81
|
+
description: Clone records using a method from model in ActiveScaffold
|
82
|
+
email: activescaffold@googlegroups.com
|
83
|
+
executables: []
|
84
|
+
|
85
|
+
extensions: []
|
86
|
+
|
87
|
+
extra_rdoc_files:
|
88
|
+
- LICENSE.txt
|
89
|
+
- README.textile
|
90
|
+
files:
|
91
|
+
- app/views/active_scaffold_overrides/duplicate.js.erb
|
92
|
+
- app/views/active_scaffold_overrides/clone.js.erb~
|
93
|
+
- app/views/active_scaffold_overrides/duplicate.js.erb~
|
94
|
+
- lib/active_scaffold/actions/clone.rb~
|
95
|
+
- lib/active_scaffold/actions/duplicate.rb
|
96
|
+
- lib/active_scaffold/actions/duplicate.rb~
|
97
|
+
- lib/active_scaffold/config/clone.rb~
|
98
|
+
- lib/active_scaffold/config/duplicate.rb
|
99
|
+
- lib/active_scaffold/config/duplicate.rb~
|
100
|
+
- lib/active_scaffold_duplicate/config/core.rb
|
101
|
+
- lib/active_scaffold_duplicate/config/core.rb~
|
102
|
+
- lib/active_scaffold_duplicate/version.rb
|
103
|
+
- lib/active_scaffold_duplicate/engine.rb
|
104
|
+
- lib/active_scaffold_duplicate/core.rb~
|
105
|
+
- lib/active_scaffold_duplicate/version.rb~
|
106
|
+
- lib/active_scaffold_duplicate/engine.rb~
|
107
|
+
- lib/active_scaffold_duplicate.rb
|
108
|
+
- lib/active_scaffold_duplicate.rb~
|
109
|
+
- lib/active_scaffold_clone.rb~
|
110
|
+
- config/locales/es.yml
|
111
|
+
- config/locales/en.yml
|
112
|
+
- LICENSE.txt
|
113
|
+
- README.textile
|
114
|
+
- test/auto_models_controller_test.rb
|
115
|
+
- test/config_test.rb
|
116
|
+
- test/controllers/auto_models_controller.rb
|
117
|
+
- test/controllers/models_controller.rb
|
118
|
+
- test/controllers/sortable_models_controller.rb
|
119
|
+
- test/models/auto_model.rb
|
120
|
+
- test/models/model.rb
|
121
|
+
- test/router_test.rb
|
122
|
+
- test/schema.rb
|
123
|
+
- test/test_helper.rb
|
124
|
+
homepage: http://github.com/activescaffold/active_scaffold_duplicate
|
125
|
+
licenses:
|
126
|
+
- MIT
|
127
|
+
post_install_message:
|
128
|
+
rdoc_options: []
|
129
|
+
|
130
|
+
require_paths:
|
131
|
+
- lib
|
132
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
133
|
+
none: false
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
hash: 3
|
138
|
+
segments:
|
139
|
+
- 0
|
140
|
+
version: "0"
|
141
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
|
+
none: false
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
hash: 3
|
147
|
+
segments:
|
148
|
+
- 0
|
149
|
+
version: "0"
|
150
|
+
requirements: []
|
151
|
+
|
152
|
+
rubyforge_project:
|
153
|
+
rubygems_version: 1.8.23
|
154
|
+
signing_key:
|
155
|
+
specification_version: 3
|
156
|
+
summary: Clone record gem for Activescaffold
|
157
|
+
test_files:
|
158
|
+
- test/auto_models_controller_test.rb
|
159
|
+
- test/config_test.rb
|
160
|
+
- test/controllers/auto_models_controller.rb
|
161
|
+
- test/controllers/models_controller.rb
|
162
|
+
- test/controllers/sortable_models_controller.rb
|
163
|
+
- test/models/auto_model.rb
|
164
|
+
- test/models/model.rb
|
165
|
+
- test/router_test.rb
|
166
|
+
- test/schema.rb
|
167
|
+
- test/test_helper.rb
|