active_scaffold_duplicate 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. data/LICENSE.txt +20 -0
  2. data/README.textile +98 -0
  3. data/app/views/active_scaffold_overrides/clone.js.erb~ +24 -0
  4. data/app/views/active_scaffold_overrides/duplicate.js.erb +17 -0
  5. data/app/views/active_scaffold_overrides/duplicate.js.erb~ +19 -0
  6. data/config/locales/en.yml +3 -0
  7. data/config/locales/es.yml +3 -0
  8. data/lib/active_scaffold/actions/clone.rb~ +57 -0
  9. data/lib/active_scaffold/actions/duplicate.rb +62 -0
  10. data/lib/active_scaffold/actions/duplicate.rb~ +59 -0
  11. data/lib/active_scaffold/config/clone.rb~ +43 -0
  12. data/lib/active_scaffold/config/duplicate.rb +44 -0
  13. data/lib/active_scaffold/config/duplicate.rb~ +44 -0
  14. data/lib/active_scaffold_clone.rb~ +24 -0
  15. data/lib/active_scaffold_duplicate.rb +18 -0
  16. data/lib/active_scaffold_duplicate.rb~ +18 -0
  17. data/lib/active_scaffold_duplicate/config/core.rb +4 -0
  18. data/lib/active_scaffold_duplicate/config/core.rb~ +4 -0
  19. data/lib/active_scaffold_duplicate/core.rb~ +13 -0
  20. data/lib/active_scaffold_duplicate/engine.rb +4 -0
  21. data/lib/active_scaffold_duplicate/engine.rb~ +4 -0
  22. data/lib/active_scaffold_duplicate/version.rb +9 -0
  23. data/lib/active_scaffold_duplicate/version.rb~ +9 -0
  24. data/test/auto_models_controller_test.rb +52 -0
  25. data/test/config_test.rb +59 -0
  26. data/test/controllers/auto_models_controller.rb +3 -0
  27. data/test/controllers/models_controller.rb +3 -0
  28. data/test/controllers/sortable_models_controller.rb +7 -0
  29. data/test/models/auto_model.rb +8 -0
  30. data/test/models/model.rb +2 -0
  31. data/test/router_test.rb +5 -0
  32. data/test/schema.rb +9 -0
  33. data/test/test_helper.rb +48 -0
  34. 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,3 @@
1
+ en:
2
+ active_scaffold:
3
+ duplicate: Dup
@@ -0,0 +1,3 @@
1
+ es:
2
+ active_scaffold:
3
+ duplicate: Duplicar
@@ -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,4 @@
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[:member][:duplicate] = [:post, :get]
4
+ end
@@ -0,0 +1,4 @@
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[:member][:clone] = :post
4
+ 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,4 @@
1
+ module ActiveScaffoldDuplicate
2
+ class Engine < ::Rails::Engine
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module ActiveScaffoldClone
2
+ class Engine < ::Rails::Engine
3
+ end
4
+ end
@@ -0,0 +1,9 @@
1
+ module ActiveScaffoldDuplicate
2
+ module Version
3
+ MAJOR = 1
4
+ MINOR = 0
5
+ PATCH = 0
6
+
7
+ STRING = [MAJOR, MINOR, PATCH].compact.join('.')
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module ActiveScaffoldClone
2
+ module Version
3
+ MAJOR = 1
4
+ MINOR = 0
5
+ PATCH = 0
6
+
7
+ STRING = [MAJOR, MINOR, PATCH].compact.join('.')
8
+ end
9
+ 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
@@ -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
@@ -0,0 +1,3 @@
1
+ class AutoModelsController < ActionController::Base
2
+ active_scaffold :auto_model
3
+ end
@@ -0,0 +1,3 @@
1
+ class ModelsController < ActionController::Base
2
+ active_scaffold
3
+ end
@@ -0,0 +1,7 @@
1
+ class SortableModelsController < ActionController::Base
2
+ active_scaffold :model do |config|
3
+ config.actions.exclude :search
4
+ config.actions << :sortable
5
+ config.sortable.column = :name
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ class AutoModel < Model
2
+ def acts_as_list_class
3
+ end
4
+
5
+ def position_column
6
+ 'position'
7
+ end
8
+ end
@@ -0,0 +1,2 @@
1
+ class Model < ActiveRecord::Base
2
+ end
@@ -0,0 +1,5 @@
1
+ require 'test_helper.rb'
2
+
3
+ class RouterTest < ActionController::TestCase
4
+ should_route :post, "/sortable_models/reorder", :controller => :sortable_models, :action => :reorder
5
+ end
data/test/schema.rb ADDED
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+
3
+ ActiveRecord::Schema.define(:version => 1) do
4
+ create_table 'models', :force => true do |t|
5
+ t.string 'name'
6
+ t.integer 'position'
7
+ end
8
+ add_index 'models', ['position']
9
+ end
@@ -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