forked from zorab47/active_admin-duplicatable
-
Notifications
You must be signed in to change notification settings - Fork 0
/
duplicatable.rb
136 lines (118 loc) · 4.83 KB
/
duplicatable.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
require "active_admin"
require "active_admin/duplicatable/version"
module ActiveAdmin
module Duplicatable
extend ActiveSupport::Concern
# Public: Enable and configure resource duplication
#
# options - Duplication options (default: { via: :form }):
# :via - Method of duplication. Via `:save` is the only way to
# copy a resources relations not present in the form.
#
# Examples
#
# ActiveAdmin.register Post do
# duplicatable via: :save
# end
#
def duplicatable(options = {})
via = options.fetch(:via) { :form }
if via == :save
enable_resource_duplication_via_save
elsif via != :form
enable_resource_duplication_via_custom_method(via)
else
enable_resource_duplication_via_form
end
end
private
# Enables resource duplication via new form.
#
# - Adds a duplicate action button.
# - Preloads a duplicated resource on `:new` to pre-fill the form fields.
#
# No return.
def enable_resource_duplication_via_form
action_item(*compatible_action_item_parameters) do
if controller.action_methods.include?('new') && authorized?(ActiveAdmin::Auth::CREATE, active_admin_config.resource_class)
link_to(I18n.t(:duplicate_model, default: "Duplicate %{model}", scope: [:active_admin], model: active_admin_config.resource_label), action: :new, _source_id: resource.id)
end
end
controller do
before_filter only: :new do
if !params[:_source_id].blank?
source = resource_class.find(params[:_source_id])
@resource ||= source.amoeba_dup if source
end
end
end
end
# Enables resource duplication via save.
#
# - Adds a duplicate action button.
# - Duplicates a resource, persists it, and redirects the user to edit
# the newly duplicated resource.
#
# No return.
def enable_resource_duplication_via_save
action_item(*compatible_action_item_parameters) do
if controller.action_methods.include?('new') && authorized?(ActiveAdmin::Auth::CREATE, active_admin_config.resource_class)
link_to(I18n.t(:duplicate_model, default: "Duplicate %{model}", scope: [:active_admin], model: active_admin_config.resource_label), action: :duplicate)
end
end
member_action :duplicate do
resource = resource_class.find(params[:id])
authorize! ActiveAdmin::Auth::CREATE, resource
duplicate = resource.amoeba_dup
if duplicate.save
redirect_to({ action: :edit, id: duplicate.id }, flash: { notice: "#{active_admin_config.resource_label} was successfully duplicated." })
else
redirect_to({ action: :show }, flash: { error: "#{active_admin_config.resource_label} could not be duplicated." })
end
end
end
# Enables resource duplication via a custom method
#
# - Adds a duplicate action button.
# - Calls a custom duplication method on the model. The method should
# handle any copying of data and persistence of the new record.
# - Redirects the user to edit the newly duplicated resource.
#
# No return.
def enable_resource_duplication_via_custom_method(method)
action_item(*compatible_action_item_parameters) do
if controller.action_methods.include?('new') && authorized?(ActiveAdmin::Auth::CREATE, active_admin_config.resource_class)
link_to(I18n.t(:duplicate_model, default: "Duplicate %{model}", scope: [:active_admin], model: active_admin_config.resource_label), action: :duplicate)
end
end
member_action :duplicate do
resource = resource_class.find(params[:id])
authorize! ActiveAdmin::Auth::CREATE, resource
begin
duplicate = resource.send method
redirect_to({ action: :edit, id: duplicate.id }, flash: { notice: "#{active_admin_config.resource_label} was successfully duplicated." })
rescue => e
Rails.logger.warn(e)
redirect_to({ action: :show }, flash: { error: "#{active_admin_config.resource_label} could not be duplicated." })
end
end
end
# For ActiveAdmin `action_item` compatibility.
#
# - When ActiveAdmin is less than 1.0.0.pre1 exclude name parameter from
# calls to `action_item` for compatibility.
# - When 1.0.0.pre1 or greater provide name to `action_item` to avoid the
# warning message, and later an error.
#
# Returns Array of parameters.
def compatible_action_item_parameters
parameters = [{ :only => [:show] }]
parameters.unshift(:duplicatable_duplicate) if action_item_name_required?
parameters
end
def action_item_name_required?
method(:action_item).parameters.count == 3
end
end
end
ActiveAdmin::ResourceDSL.send :include, ActiveAdmin::Duplicatable