mongoid-api-base 0.1.5 → 0.1.8
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +3 -1
- data/lib/mongoid-api-base.rb +79 -5
- data/lib/mongoid-api-base/actions.rb +54 -0
- data/lib/mongoid-api-base/base_helpers.rb +115 -0
- data/lib/mongoid-api-base/version.rb +1 -1
- data/lib/swagger/generator.rb +182 -0
- data/mongoid-api-base.gemspec +4 -2
- metadata +19 -3
- data/lib/mongoid-api-base/concern.rb +0 -216
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1e92a91674850278d42ca43d2c4dec1425072229
|
4
|
+
data.tar.gz: 44814b2ad35b90e4eba9e709f23550c8906be74c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7abc8f9633476d5c8cc23e3fa937ddd5c14bdf48fd273599a5aaeba15fafaa45266bf99da3f0f09d3fa6fab072825798d1bd0dc0c461a1e1ad9eb6708f1a2d8e
|
7
|
+
data.tar.gz: e76fff77fbad9db30d6fd63e92eab0c91d637dc39d672d1016ce139b3d32e48d93131589e75b97ec2e8882a9793466c0fb900873b786528367a1d6be8b8193fe
|
data/Gemfile.lock
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
mongoid-api-base (0.1.
|
4
|
+
mongoid-api-base (0.1.6)
|
5
5
|
kaminari
|
6
6
|
mongoid (~> 5.0)
|
7
|
+
swagger-blocks
|
7
8
|
|
8
9
|
GEM
|
9
10
|
remote: http://rubygems.org/
|
@@ -63,6 +64,7 @@ GEM
|
|
63
64
|
rails-deprecated_sanitizer (>= 1.0.1)
|
64
65
|
rails-html-sanitizer (1.0.3)
|
65
66
|
loofah (~> 2.0)
|
67
|
+
swagger-blocks (1.3.2)
|
66
68
|
thread_safe (0.3.5)
|
67
69
|
tzinfo (1.2.2)
|
68
70
|
thread_safe (~> 0.1)
|
data/lib/mongoid-api-base.rb
CHANGED
@@ -1,5 +1,79 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
# =============================================================================
|
2
|
+
# MongoidApiBase
|
3
|
+
# Rails concern to implement API controllers for Mongoid models.
|
4
|
+
# -----------------------------------------------------------------------------
|
5
|
+
# Usage Example:
|
6
|
+
#
|
7
|
+
# include MongoidApiBase
|
8
|
+
#
|
9
|
+
# defaults resource_class: Journal::JournalPost,
|
10
|
+
# per_page: 30
|
11
|
+
#
|
12
|
+
# has_scope :by_category
|
13
|
+
# has_scope :hidden, type: :boolean
|
14
|
+
# has_scope :not_hidden, type: :boolean
|
15
|
+
#
|
16
|
+
# json_config methods: %w(hex slug sorted_categories opengraph_image_url meta_title meta_description),
|
17
|
+
# index: {
|
18
|
+
# except: %w(body_markdown body_html),
|
19
|
+
# methods: %w(hex slug)
|
20
|
+
# }
|
21
|
+
# -----------------------------------------------------------------------------
|
22
|
+
# Some more ideas for future improvements can be pulled from here:
|
23
|
+
# - https://github.com/jamesgolick/resource_controller
|
24
|
+
# =============================================================================
|
25
|
+
|
26
|
+
require 'kaminari'
|
27
|
+
require 'csv'
|
28
|
+
require 'action_controller/metal/renderers'
|
29
|
+
require 'renderers/csv'
|
30
|
+
require 'swagger/blocks'
|
31
|
+
require 'swagger/generator'
|
32
|
+
require 'mongoid-api-base/actions'
|
33
|
+
require 'mongoid-api-base/base_helpers'
|
34
|
+
require 'mongoid-api-base/version'
|
35
|
+
|
36
|
+
module MongoidApiBase
|
37
|
+
extend ActiveSupport::Concern
|
38
|
+
included do
|
39
|
+
respond_to :json
|
40
|
+
respond_to :csv, only: %w(index)
|
41
|
+
|
42
|
+
class_attribute :resource_class
|
43
|
+
class_attribute :per_page
|
44
|
+
class_attribute :csv_options
|
45
|
+
class_attribute :json_options
|
46
|
+
|
47
|
+
JSON_DEFAULT_ATTRIBUTES = [ :created_at,
|
48
|
+
:updated_at,
|
49
|
+
:slug,
|
50
|
+
:_position,
|
51
|
+
:_list_item_title,
|
52
|
+
:_list_item_subtitle,
|
53
|
+
:_list_item_thumbnail,
|
54
|
+
:_document_versions ].freeze
|
55
|
+
|
56
|
+
include Actions
|
57
|
+
include BaseHelpers
|
58
|
+
end
|
59
|
+
|
60
|
+
class_methods do
|
61
|
+
def defaults(options)
|
62
|
+
if options.key?(:resource_class)
|
63
|
+
self.resource_class = options[:resource_class]
|
64
|
+
end
|
65
|
+
|
66
|
+
if options.key?(:per_page)
|
67
|
+
self.per_page = options[:per_page]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def csv_config(options={})
|
72
|
+
self.csv_options = options
|
73
|
+
end
|
74
|
+
|
75
|
+
def json_config(options)
|
76
|
+
self.json_options = options
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# Holds all default actions for MongoidApiBase.
|
2
|
+
module MongoidApiBase
|
3
|
+
module Actions
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
included do
|
6
|
+
def index
|
7
|
+
@chain = resource_class
|
8
|
+
|
9
|
+
apply_scopes_to_chain!
|
10
|
+
search_filter_chain!
|
11
|
+
paginate_chain!
|
12
|
+
set_total_count_header!
|
13
|
+
|
14
|
+
respond_to do |format|
|
15
|
+
format.json { render json: @chain.as_json(json_config(:index)) }
|
16
|
+
format.csv { render csv: @chain }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def show
|
21
|
+
object = find_object
|
22
|
+
object = get_object_version(object)
|
23
|
+
render json: object.as_json(json_config(:show))
|
24
|
+
end
|
25
|
+
|
26
|
+
def create
|
27
|
+
object = build_object
|
28
|
+
if object.save
|
29
|
+
render json: object.as_json(json_config(:create))
|
30
|
+
else
|
31
|
+
render json: object.errors, status: :unprocessable_entity
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def update
|
36
|
+
object = find_object
|
37
|
+
if object.update_attributes(resource_params)
|
38
|
+
render json: object.as_json(json_config(:update))
|
39
|
+
else
|
40
|
+
render json: object.errors, status: :unprocessable_entity
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def destroy
|
45
|
+
object = find_object
|
46
|
+
if object.destroy
|
47
|
+
render nothing: true, status: 204
|
48
|
+
else
|
49
|
+
render json: object.errors, status: :unprocessable_entity
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# Base helpers for MongoidApiBase work. Some methods here can be overwritten and
|
2
|
+
# you will need to do that to customize your controllers.
|
3
|
+
module MongoidApiBase
|
4
|
+
module BaseHelpers
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
included do
|
7
|
+
def find_object
|
8
|
+
resource_class.find(params[:id])
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_object_version(object)
|
12
|
+
version = params[:version]
|
13
|
+
if object.respond_to?(:undo, true)
|
14
|
+
if version && version.to_i != object.version
|
15
|
+
object.undo(nil, from: version.to_i + 1, to: object.version)
|
16
|
+
object.version = version
|
17
|
+
end
|
18
|
+
end
|
19
|
+
object
|
20
|
+
end
|
21
|
+
|
22
|
+
def build_object
|
23
|
+
resource_class.new(resource_params)
|
24
|
+
end
|
25
|
+
|
26
|
+
def apply_scopes_to_chain!
|
27
|
+
if respond_to?(:apply_scopes, true)
|
28
|
+
@chain = apply_scopes(@chain)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def search_filter_chain!
|
33
|
+
query = params[:search]
|
34
|
+
if query
|
35
|
+
normalized_query = query.to_s.downcase
|
36
|
+
@chain = @chain.search(normalized_query, match: :all)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def page
|
41
|
+
@page ||= params[:page] || false
|
42
|
+
end
|
43
|
+
|
44
|
+
def per_page
|
45
|
+
@per_page ||= params[:perPage] || self.class.per_page || 20
|
46
|
+
end
|
47
|
+
|
48
|
+
def paginate_chain!
|
49
|
+
@chain = begin
|
50
|
+
if page
|
51
|
+
@chain.page(page).per(per_page)
|
52
|
+
else
|
53
|
+
@chain.all
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def set_total_count_header!
|
59
|
+
if page
|
60
|
+
response.headers['X-Total-Count'] = @chain.total_count
|
61
|
+
else
|
62
|
+
response.headers['X-Total-Count'] = @chain.size
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def resource_class
|
67
|
+
@resource_class ||= self.class.resource_class
|
68
|
+
@resource_class ||= begin
|
69
|
+
namespaced_class = self.class.to_s.split("::").last.
|
70
|
+
sub(/Controller$/, "").singularize
|
71
|
+
namespaced_class.constantize
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def resource_request_name
|
76
|
+
resource_class.to_s.underscore.gsub("/", "_").gsub("::", "_")
|
77
|
+
end
|
78
|
+
|
79
|
+
def resource_params
|
80
|
+
permitted_params
|
81
|
+
end
|
82
|
+
|
83
|
+
def permitted_params
|
84
|
+
params.require(resource_request_name).permit!
|
85
|
+
end
|
86
|
+
|
87
|
+
def json_default_options
|
88
|
+
@json_default_options ||= begin
|
89
|
+
default_options = {}
|
90
|
+
json_options = self.class.json_options || {}
|
91
|
+
[:only, :except, :methods].each do |name|
|
92
|
+
if json_options.key? name
|
93
|
+
default_options[name] = json_options[name]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
default_options[:methods] ||= []
|
97
|
+
default_options[:methods].concat(JSON_DEFAULT_ATTRIBUTES).uniq!
|
98
|
+
default_options
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def json_config(action)
|
103
|
+
json_options = self.class.json_options
|
104
|
+
if json_options && json_options.key?(action)
|
105
|
+
json_options = json_options[action]
|
106
|
+
json_options[:methods] ||= []
|
107
|
+
json_options[:methods].concat(JSON_DEFAULT_ATTRIBUTES).uniq!
|
108
|
+
json_options
|
109
|
+
else
|
110
|
+
json_default_options
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,182 @@
|
|
1
|
+
# EXTRA LINKS:
|
2
|
+
# - https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md
|
3
|
+
# - https://github.com/fotinakis/swagger-blocks
|
4
|
+
# - https://github.com/westfieldlabs/apivore
|
5
|
+
# - https://github.com/notonthehighstreet/svelte
|
6
|
+
|
7
|
+
module SwaggerGenerator
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
included do
|
11
|
+
include Swagger::Blocks
|
12
|
+
end
|
13
|
+
|
14
|
+
class_methods do
|
15
|
+
REJECT_NAMES = %w(_id _keywords created_at updated_at).freeze
|
16
|
+
ALLOW_TYPES = %w(Object String)
|
17
|
+
|
18
|
+
def generate_swagger
|
19
|
+
generate_swagger_schemas
|
20
|
+
generate_swagger_paths
|
21
|
+
end
|
22
|
+
|
23
|
+
def collection_name
|
24
|
+
@collection_name ||= to_s.split("::").last.sub(/Controller$/, '')
|
25
|
+
end
|
26
|
+
|
27
|
+
def resource_name
|
28
|
+
@resource_name ||= collection_name.singularize
|
29
|
+
end
|
30
|
+
|
31
|
+
def generate_swagger_schemas
|
32
|
+
name = resource_name
|
33
|
+
|
34
|
+
if resource_class
|
35
|
+
# TODO: add support for resource class option
|
36
|
+
else
|
37
|
+
resource_class = name.constantize
|
38
|
+
end
|
39
|
+
|
40
|
+
swagger_schema name do
|
41
|
+
# TODO: autogenerate list of required fields
|
42
|
+
# key :required, %w(name email)
|
43
|
+
|
44
|
+
resource_class.fields.each do |name, options|
|
45
|
+
type = options.type.to_s
|
46
|
+
if ALLOW_TYPES.include? type
|
47
|
+
unless REJECT_NAMES.include? name
|
48
|
+
property name do
|
49
|
+
key :type, :string
|
50
|
+
# TODO: autodetect property type
|
51
|
+
# key :format, 'date-time'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def generate_swagger_paths
|
60
|
+
name = resource_name
|
61
|
+
plural = collection_name
|
62
|
+
path = plural.underscore
|
63
|
+
tags = [ plural ]
|
64
|
+
|
65
|
+
swagger_path "/#{ path }" do
|
66
|
+
operation :get do
|
67
|
+
key :tags, tags
|
68
|
+
key :operationId, "index#{ plural }"
|
69
|
+
key :produces, %w(application/json text/csv)
|
70
|
+
|
71
|
+
parameter do
|
72
|
+
key :name, :page
|
73
|
+
key :in, :query
|
74
|
+
key :required, false
|
75
|
+
key :type, :integer
|
76
|
+
key :format, :int32
|
77
|
+
end
|
78
|
+
|
79
|
+
parameter do
|
80
|
+
key :name, :perPage
|
81
|
+
key :in, :query
|
82
|
+
key :required, false
|
83
|
+
key :type, :integer
|
84
|
+
key :format, :int32
|
85
|
+
end
|
86
|
+
|
87
|
+
parameter do
|
88
|
+
key :name, :search
|
89
|
+
key :in, :query
|
90
|
+
key :required, false
|
91
|
+
key :type, :string
|
92
|
+
end
|
93
|
+
|
94
|
+
response 200 do
|
95
|
+
schema type: :array do
|
96
|
+
items do
|
97
|
+
key :'$ref', name
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
operation :post do
|
104
|
+
key :tags, tags
|
105
|
+
key :operationId, "create#{ plural }"
|
106
|
+
key :produces, %w(application/json)
|
107
|
+
parameter do
|
108
|
+
key :name, name.underscore.to_sym
|
109
|
+
key :in, :form
|
110
|
+
key :required, true
|
111
|
+
schema do
|
112
|
+
key :'$ref', name # input
|
113
|
+
end
|
114
|
+
end
|
115
|
+
response 200 do
|
116
|
+
schema do
|
117
|
+
key :'$ref', name
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
swagger_path "/#{ path }/{id}" do
|
124
|
+
operation :get do
|
125
|
+
key :tags, tags
|
126
|
+
key :operationId, "show#{ name }ById"
|
127
|
+
key :produces, %w(application/json)
|
128
|
+
parameter do
|
129
|
+
key :name, :id
|
130
|
+
key :in, :path
|
131
|
+
key :required, true
|
132
|
+
key :type, :string
|
133
|
+
end
|
134
|
+
response 200 do
|
135
|
+
schema do
|
136
|
+
key :'$ref', name
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
operation :put do
|
142
|
+
key :tags, tags
|
143
|
+
key :operationId, "update#{ name }"
|
144
|
+
key :produces, %w(application/json)
|
145
|
+
parameter do
|
146
|
+
key :name, :id
|
147
|
+
key :in, :path
|
148
|
+
key :required, true
|
149
|
+
key :type, :string
|
150
|
+
end
|
151
|
+
parameter do
|
152
|
+
key :name, name.underscore.to_sym
|
153
|
+
key :in, :form
|
154
|
+
key :required, true
|
155
|
+
schema do
|
156
|
+
key :'$ref', name # input
|
157
|
+
end
|
158
|
+
end
|
159
|
+
response 200 do
|
160
|
+
schema do
|
161
|
+
key :'$ref', name
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
operation :delete do
|
167
|
+
key :tags, tags
|
168
|
+
key :operationId, "delete#{ name }"
|
169
|
+
parameter do
|
170
|
+
key :name, :id
|
171
|
+
key :in, :path
|
172
|
+
key :required, true
|
173
|
+
key :type, :string
|
174
|
+
end
|
175
|
+
response 204 do
|
176
|
+
key :description, "#{ name } deleted"
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
data/mongoid-api-base.gemspec
CHANGED
@@ -19,7 +19,9 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.platform = Gem::Platform::RUBY
|
20
20
|
|
21
21
|
# Ruby ODM framework for MongoDB
|
22
|
-
s.add_dependency
|
22
|
+
s.add_dependency 'mongoid', '~> 5.0'
|
23
23
|
# Clean, powerful, customizable and sophisticated paginator
|
24
|
-
s.add_dependency
|
24
|
+
s.add_dependency 'kaminari'
|
25
|
+
# DSL for pure Ruby code blocks that can be turned into JSON
|
26
|
+
s.add_dependency 'swagger-blocks'
|
25
27
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid-api-base
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander Kravets
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-04-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mongoid
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: swagger-blocks
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
description:
|
42
56
|
email: alex@slatestudio.com
|
43
57
|
executables: []
|
@@ -52,9 +66,11 @@ files:
|
|
52
66
|
- README.md
|
53
67
|
- Rakefile
|
54
68
|
- lib/mongoid-api-base.rb
|
55
|
-
- lib/mongoid-api-base/
|
69
|
+
- lib/mongoid-api-base/actions.rb
|
70
|
+
- lib/mongoid-api-base/base_helpers.rb
|
56
71
|
- lib/mongoid-api-base/version.rb
|
57
72
|
- lib/renderers/csv.rb
|
73
|
+
- lib/swagger/generator.rb
|
58
74
|
- mongoid-api-base.gemspec
|
59
75
|
homepage: http://github.com/slate-studio/mongoid-api-base
|
60
76
|
licenses:
|
@@ -1,216 +0,0 @@
|
|
1
|
-
# =============================================================================
|
2
|
-
# MongoidApiBase
|
3
|
-
# Rails concern to implement API controllers for Mongoid models.
|
4
|
-
# -----------------------------------------------------------------------------
|
5
|
-
# Usage Example:
|
6
|
-
#
|
7
|
-
# include MongoidApiBase
|
8
|
-
#
|
9
|
-
# defaults resource_class: Journal::JournalPost,
|
10
|
-
# per_page: 30
|
11
|
-
#
|
12
|
-
# has_scope :by_category
|
13
|
-
# has_scope :hidden, type: :boolean
|
14
|
-
# has_scope :not_hidden, type: :boolean
|
15
|
-
#
|
16
|
-
# json_config methods: %w(hex slug sorted_categories opengraph_image_url meta_title meta_description),
|
17
|
-
# index: {
|
18
|
-
# except: %w(body_markdown body_html),
|
19
|
-
# methods: %w(hex slug)
|
20
|
-
# }
|
21
|
-
# =============================================================================
|
22
|
-
module MongoidApiBase
|
23
|
-
extend ActiveSupport::Concern
|
24
|
-
included do
|
25
|
-
respond_to :json
|
26
|
-
respond_to :csv, only: %w(index)
|
27
|
-
|
28
|
-
class_attribute :resource_class
|
29
|
-
class_attribute :per_page
|
30
|
-
class_attribute :csv_options
|
31
|
-
class_attribute :json_options
|
32
|
-
|
33
|
-
def index
|
34
|
-
@chain = resource_class
|
35
|
-
|
36
|
-
apply_scopes_to_chain!
|
37
|
-
search_filter_chain!
|
38
|
-
paginate_chain!
|
39
|
-
set_total_count_header!
|
40
|
-
|
41
|
-
respond_to do |format|
|
42
|
-
format.json { render json: @chain.as_json(json_config(:index)) }
|
43
|
-
format.csv { render csv: @chain }
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def show
|
48
|
-
object = find_object
|
49
|
-
object = get_object_version(object)
|
50
|
-
render json: object.as_json(json_config(:show))
|
51
|
-
end
|
52
|
-
|
53
|
-
def create
|
54
|
-
object = build_object
|
55
|
-
if object.save
|
56
|
-
render json: object.as_json(json_config(:create))
|
57
|
-
else
|
58
|
-
render json: object.errors, status: :unprocessable_entity
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def update
|
63
|
-
object = find_object
|
64
|
-
if object.update_attributes(resource_params)
|
65
|
-
render json: object.as_json(json_config(:update))
|
66
|
-
else
|
67
|
-
render json: object.errors, status: :unprocessable_entity
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def destroy
|
72
|
-
object = find_object
|
73
|
-
if object.destroy
|
74
|
-
render nothing: true
|
75
|
-
else
|
76
|
-
render json: object.errors, status: :unprocessable_entity
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def find_object
|
81
|
-
resource_class.find(params[:id])
|
82
|
-
end
|
83
|
-
|
84
|
-
def get_object_version(object)
|
85
|
-
version = params[:version]
|
86
|
-
if version && object.respond_to?(:undo, true)
|
87
|
-
object.undo(nil, from: version.to_i + 1, to: object.version)
|
88
|
-
object.version = version
|
89
|
-
end
|
90
|
-
object
|
91
|
-
end
|
92
|
-
|
93
|
-
def build_object
|
94
|
-
resource_class.new(resource_params)
|
95
|
-
end
|
96
|
-
|
97
|
-
def apply_scopes_to_chain!
|
98
|
-
if respond_to?(:apply_scopes, true)
|
99
|
-
@chain = apply_scopes(@chain)
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def search_filter_chain!
|
104
|
-
query = params[:search]
|
105
|
-
if query
|
106
|
-
normalized_query = query.to_s.downcase
|
107
|
-
@chain = @chain.search(normalized_query, match: :all)
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
def page
|
112
|
-
@page ||= params[:page] || false
|
113
|
-
end
|
114
|
-
|
115
|
-
def per_page
|
116
|
-
@per_page ||= params[:perPage] || self.class.per_page || 20
|
117
|
-
end
|
118
|
-
|
119
|
-
def paginate_chain!
|
120
|
-
@chain = begin
|
121
|
-
if page
|
122
|
-
@chain.page(page).per(per_page)
|
123
|
-
else
|
124
|
-
@chain.all
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
def set_total_count_header!
|
130
|
-
if page
|
131
|
-
response.headers['X-Total-Count'] = @chain.total_count
|
132
|
-
else
|
133
|
-
response.headers['X-Total-Count'] = @chain.size
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
def resource_class
|
138
|
-
@resource_class ||= self.class.resource_class
|
139
|
-
@resource_class ||= begin
|
140
|
-
namespaced_class = self.class.to_s.split("::").last.
|
141
|
-
sub(/Controller$/, "").singularize
|
142
|
-
namespaced_class.constantize
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
def resource_request_name
|
147
|
-
resource_class.to_s.underscore.gsub("/", "_").gsub("::", "_")
|
148
|
-
end
|
149
|
-
|
150
|
-
def resource_params
|
151
|
-
permitted_params
|
152
|
-
end
|
153
|
-
|
154
|
-
def permitted_params
|
155
|
-
params.require(resource_request_name).permit!
|
156
|
-
end
|
157
|
-
|
158
|
-
def json_default_methods
|
159
|
-
[ :created_at,
|
160
|
-
:updated_at,
|
161
|
-
:slug,
|
162
|
-
:_position,
|
163
|
-
:_list_item_title,
|
164
|
-
:_list_item_subtitle,
|
165
|
-
:_list_item_thumbnail,
|
166
|
-
:_document_versions ]
|
167
|
-
end
|
168
|
-
|
169
|
-
def json_default_options
|
170
|
-
@json_default_options ||= begin
|
171
|
-
default_options = {}
|
172
|
-
json_options = self.class.json_options || {}
|
173
|
-
[:only, :except, :methods].each do |name|
|
174
|
-
if json_options.key? name
|
175
|
-
default_options[name] = json_options[name]
|
176
|
-
end
|
177
|
-
end
|
178
|
-
default_options[:methods] ||= []
|
179
|
-
default_options[:methods].concat(json_default_methods).uniq!
|
180
|
-
default_options
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
def json_config(action)
|
185
|
-
json_options = self.class.json_options
|
186
|
-
if json_options && json_options.key?(action)
|
187
|
-
json_options = json_options[action]
|
188
|
-
json_options[:methods] ||= []
|
189
|
-
json_options[:methods].concat(json_default_methods).uniq!
|
190
|
-
json_options
|
191
|
-
else
|
192
|
-
json_default_options
|
193
|
-
end
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
class_methods do
|
198
|
-
def defaults(options)
|
199
|
-
if options.key?(:resource_class)
|
200
|
-
self.resource_class = options[:resource_class]
|
201
|
-
end
|
202
|
-
|
203
|
-
if options.key?(:per_page)
|
204
|
-
self.resource_class = options[:per_page]
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
def csv_config(options={})
|
209
|
-
self.csv_options = options
|
210
|
-
end
|
211
|
-
|
212
|
-
def json_config(options)
|
213
|
-
self.json_options = options
|
214
|
-
end
|
215
|
-
end
|
216
|
-
end
|