-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
bulk_model_controller_mixin.rb
109 lines (90 loc) · 3.47 KB
/
bulk_model_controller_mixin.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
require_relative "model_controller_mixin"
# Mixin for creating records in bulk. This is unique compared to update/destroy because we overload
# the existing `create` action to support bulk creation.
module RESTFramework::Mixins::BulkCreateModelMixin
# While bulk update/destroy are obvious because they create new router endpoints, bulk create
# overloads the existing collection `POST` endpoint, so we add a special key to the options
# metadata to indicate bulk create is supported.
def get_options_metadata
return super.merge({bulk_create: true})
end
def create
if params[:_json].is_a?(Array)
records = self.create_all!
serialized_records = self.bulk_serialize(records)
return api_response(serialized_records)
end
return super
end
# Perform the `create` call, and return the collection of (possibly) created records.
def create_all!
create_data = self.get_create_params(bulk_mode: true)[:_json]
# Perform bulk create in a transaction.
return ActiveRecord::Base.transaction do
next self.get_create_from.create(create_data)
end
end
end
# Alias for convenience.
RESTFramework::BulkCreateModelMixin = RESTFramework::Mixins::BulkCreateModelMixin
# Mixin for updating records in bulk.
module RESTFramework::Mixins::BulkUpdateModelMixin
def update_all
records = self.update_all!
serialized_records = self.bulk_serialize(records)
return api_response(serialized_records)
end
# Perform the `update` call and return the collection of (possibly) updated records.
def update_all!
pk = self.class.get_model.primary_key
update_data = if params[:_json].is_a?(Array)
self.get_create_params(bulk_mode: :update)[:_json].index_by { |r| r[pk] }
else
create_params = self.get_create_params
{create_params[pk] => create_params}
end
# Perform bulk update in a transaction.
return ActiveRecord::Base.transaction do
next self.get_recordset.update(update_data.keys, update_data.values)
end
end
end
# Alias for convenience.
RESTFramework::BulkUpdateModelMixin = RESTFramework::Mixins::BulkUpdateModelMixin
# Mixin for destroying records in bulk.
module RESTFramework::Mixins::BulkDestroyModelMixin
def destroy_all
if params[:_json].is_a?(Array)
records = self.destroy_all!
serialized_records = self.bulk_serialize(records)
return api_response(serialized_records)
end
return api_response(
{message: "Bulk destroy requires an array of primary keys as input."},
status: 400,
)
end
# Perform the `destroy!` call and return the destroyed (and frozen) record.
def destroy_all!
pk = self.class.get_model.primary_key
destroy_data = self.request.request_parameters[:_json]
# Perform bulk destroy in a transaction.
return ActiveRecord::Base.transaction do
next self.get_recordset.where(pk => destroy_data).destroy_all
end
end
end
# Alias for convenience.
RESTFramework::BulkDestroyModelMixin = RESTFramework::Mixins::BulkDestroyModelMixin
# Mixin that includes all the CRUD bulk mixins.
module RESTFramework::Mixins::BulkModelControllerMixin
include RESTFramework::ModelControllerMixin
include RESTFramework::BulkCreateModelMixin
include RESTFramework::BulkUpdateModelMixin
include RESTFramework::BulkDestroyModelMixin
def self.included(base)
RESTFramework::ModelControllerMixin.included(base)
end
end
# Alias for convenience.
RESTFramework::BulkModelControllerMixin = RESTFramework::Mixins::BulkModelControllerMixin