power_api 0.1.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.
Files changed (138) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +9 -0
  4. data/.hound.yml +4 -0
  5. data/.rspec +3 -0
  6. data/.rubocop.yml +479 -0
  7. data/.ruby-version +1 -0
  8. data/.travis.yml +15 -0
  9. data/CHANGELOG.md +7 -0
  10. data/Gemfile +18 -0
  11. data/Gemfile.lock +310 -0
  12. data/Guardfile +15 -0
  13. data/LICENSE.txt +21 -0
  14. data/README.md +904 -0
  15. data/Rakefile +10 -0
  16. data/app/assets/config/power_api_manifest.js +2 -0
  17. data/app/assets/images/power_api/.keep +0 -0
  18. data/app/assets/javascripts/power_api/application.js +13 -0
  19. data/app/assets/stylesheets/power_api/application.css +15 -0
  20. data/app/controllers/concerns/api/deprecated.rb +23 -0
  21. data/app/controllers/concerns/api/error.rb +37 -0
  22. data/app/controllers/concerns/api/filtered.rb +15 -0
  23. data/app/controllers/concerns/api/versioned.rb +36 -0
  24. data/app/controllers/power_api/base_controller.rb +14 -0
  25. data/app/helpers/power_api/application_helper.rb +4 -0
  26. data/app/jobs/power_api/application_job.rb +4 -0
  27. data/app/mailers/power_api/application_mailer.rb +6 -0
  28. data/app/models/power_api/application_record.rb +5 -0
  29. data/app/responders/api_responder.rb +13 -0
  30. data/app/views/layouts/power_api/application.html.erb +14 -0
  31. data/bin/rails +14 -0
  32. data/config/routes.rb +2 -0
  33. data/lib/generators/power_api/controller/USAGE +5 -0
  34. data/lib/generators/power_api/controller/controller_generator.rb +152 -0
  35. data/lib/generators/power_api/install/USAGE +5 -0
  36. data/lib/generators/power_api/install/install_generator.rb +67 -0
  37. data/lib/generators/power_api/version/USAGE +5 -0
  38. data/lib/generators/power_api/version/version_generator.rb +54 -0
  39. data/lib/power_api.rb +35 -0
  40. data/lib/power_api/engine.rb +28 -0
  41. data/lib/power_api/errors.rb +4 -0
  42. data/lib/power_api/generator_helper/active_record_resource.rb +192 -0
  43. data/lib/power_api/generator_helper/ams_helper.rb +43 -0
  44. data/lib/power_api/generator_helper/controller_helper.rb +184 -0
  45. data/lib/power_api/generator_helper/pagination_helper.rb +48 -0
  46. data/lib/power_api/generator_helper/resource_helper.rb +33 -0
  47. data/lib/power_api/generator_helper/routes_helper.rb +91 -0
  48. data/lib/power_api/generator_helper/rubocop_helper.rb +11 -0
  49. data/lib/power_api/generator_helper/simple_token_auth_helper.rb +124 -0
  50. data/lib/power_api/generator_helper/swagger_helper.rb +463 -0
  51. data/lib/power_api/generator_helper/template_builder_helper.rb +23 -0
  52. data/lib/power_api/generator_helper/version_helper.rb +16 -0
  53. data/lib/power_api/generator_helpers.rb +25 -0
  54. data/lib/power_api/version.rb +3 -0
  55. data/lib/tasks/power_api_tasks.rake +4 -0
  56. data/power_api.gemspec +44 -0
  57. data/spec/dummy/Rakefile +6 -0
  58. data/spec/dummy/app/assets/config/manifest.js +5 -0
  59. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  60. data/spec/dummy/app/assets/javascripts/cable.js +13 -0
  61. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  62. data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
  63. data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
  64. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  65. data/spec/dummy/app/controllers/concerns/api/deprecated_spec.rb +37 -0
  66. data/spec/dummy/app/controllers/concerns/api/error_spec.rb +97 -0
  67. data/spec/dummy/app/controllers/concerns/api/filtered_spec.rb +42 -0
  68. data/spec/dummy/app/controllers/concerns/api/versioned_spec.rb +64 -0
  69. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  70. data/spec/dummy/app/jobs/application_job.rb +2 -0
  71. data/spec/dummy/app/mailers/application_mailer.rb +4 -0
  72. data/spec/dummy/app/models/application_record.rb +3 -0
  73. data/spec/dummy/app/models/blog.rb +5 -0
  74. data/spec/dummy/app/models/portfolio.rb +5 -0
  75. data/spec/dummy/app/models/user.rb +3 -0
  76. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  77. data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
  78. data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
  79. data/spec/dummy/bin/bundle +3 -0
  80. data/spec/dummy/bin/rails +4 -0
  81. data/spec/dummy/bin/rake +4 -0
  82. data/spec/dummy/bin/setup +38 -0
  83. data/spec/dummy/bin/update +29 -0
  84. data/spec/dummy/bin/yarn +11 -0
  85. data/spec/dummy/config.ru +5 -0
  86. data/spec/dummy/config/application.rb +26 -0
  87. data/spec/dummy/config/boot.rb +5 -0
  88. data/spec/dummy/config/cable.yml +10 -0
  89. data/spec/dummy/config/database.yml +25 -0
  90. data/spec/dummy/config/environment.rb +5 -0
  91. data/spec/dummy/config/environments/development.rb +54 -0
  92. data/spec/dummy/config/environments/production.rb +91 -0
  93. data/spec/dummy/config/environments/test.rb +42 -0
  94. data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
  95. data/spec/dummy/config/initializers/assets.rb +14 -0
  96. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  97. data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
  98. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  99. data/spec/dummy/config/initializers/inflections.rb +16 -0
  100. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  101. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  102. data/spec/dummy/config/locales/en.yml +33 -0
  103. data/spec/dummy/config/puma.rb +56 -0
  104. data/spec/dummy/config/routes.rb +12 -0
  105. data/spec/dummy/config/secrets.yml +32 -0
  106. data/spec/dummy/config/spring.rb +6 -0
  107. data/spec/dummy/db/migrate/20190322205209_create_blogs.rb +10 -0
  108. data/spec/dummy/db/migrate/20200215225917_create_users.rb +9 -0
  109. data/spec/dummy/db/migrate/20200227150449_create_portfolios.rb +10 -0
  110. data/spec/dummy/db/migrate/20200227150548_add_portfolio_id_blogs.rb +5 -0
  111. data/spec/dummy/db/schema.rb +38 -0
  112. data/spec/dummy/package.json +5 -0
  113. data/spec/dummy/public/404.html +67 -0
  114. data/spec/dummy/public/422.html +67 -0
  115. data/spec/dummy/public/500.html +66 -0
  116. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  117. data/spec/dummy/public/apple-touch-icon.png +0 -0
  118. data/spec/dummy/public/favicon.ico +0 -0
  119. data/spec/dummy/spec/assets/image.png +0 -0
  120. data/spec/dummy/spec/assets/video.mp4 +0 -0
  121. data/spec/dummy/spec/factories/blogs.rb +7 -0
  122. data/spec/dummy/spec/factories/portfolios.rb +6 -0
  123. data/spec/dummy/spec/factories/users.rb +5 -0
  124. data/spec/dummy/spec/lib/power_api/generator_helper/ams_helper_spec.rb +87 -0
  125. data/spec/dummy/spec/lib/power_api/generator_helper/controller_helper_spec.rb +361 -0
  126. data/spec/dummy/spec/lib/power_api/generator_helper/pagination_helper_spec.rb +56 -0
  127. data/spec/dummy/spec/lib/power_api/generator_helper/resource_helper_spec.rb +31 -0
  128. data/spec/dummy/spec/lib/power_api/generator_helper/routes_helper_spec.rb +179 -0
  129. data/spec/dummy/spec/lib/power_api/generator_helper/simple_token_auth_helper_spec.rb +164 -0
  130. data/spec/dummy/spec/lib/power_api/generator_helper/swagger_helper_spec.rb +451 -0
  131. data/spec/dummy/spec/lib/power_api/generator_helper/version_helper_spec.rb +55 -0
  132. data/spec/dummy/spec/support/shared_examples/active_record_resource.rb +101 -0
  133. data/spec/dummy/spec/support/shared_examples/active_record_resource_atrributes.rb +164 -0
  134. data/spec/dummy/spec/support/test_generator_helpers.rb +29 -0
  135. data/spec/dummy/spec/support/test_helpers.rb +11 -0
  136. data/spec/rails_helper.rb +49 -0
  137. data/spec/spec_helper.rb +9 -0
  138. metadata +602 -0
@@ -0,0 +1,5 @@
1
+ Description:
2
+ Creates new API version
3
+
4
+ Example:
5
+ rails generate power_api:version 1
@@ -0,0 +1,54 @@
1
+ class PowerApi::VersionGenerator < Rails::Generators::NamedBase
2
+ source_root File.expand_path('templates', __dir__)
3
+
4
+ def modify_routes
5
+ insert_into_file(
6
+ helper.routes_path,
7
+ after: helper.routes_line_to_inject_new_version
8
+ ) do
9
+ helper.version_route_tpl
10
+ end
11
+
12
+ helper.format_ruby_file(helper.routes_path)
13
+ end
14
+
15
+ def add_base_controller
16
+ create_file(
17
+ helper.base_controller_path,
18
+ helper.base_controller_tpl
19
+ )
20
+ end
21
+
22
+ def add_serializers_directory
23
+ create_file(helper.ams_serializers_path)
24
+ end
25
+
26
+ def add_swagger_related
27
+ create_file(helper.swagger_schemas_path)
28
+
29
+ create_file(
30
+ helper.swagger_version_definition_path,
31
+ helper.swagger_definition_tpl
32
+ )
33
+
34
+ insert_into_file(
35
+ helper.rswag_ui_initializer_path,
36
+ after: helper.rswag_ui_configure_line
37
+ ) do
38
+ helper.rswag_ui_swagger_endpoint
39
+ end
40
+
41
+ insert_into_file(
42
+ helper.swagger_helper_path,
43
+ after: helper.swagger_helper_api_definition_line
44
+ ) do
45
+ helper.swagger_helper_api_definition
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ def helper
52
+ @helper ||= PowerApi::GeneratorHelpers.new(version_number: file_name)
53
+ end
54
+ end
data/lib/power_api.rb ADDED
@@ -0,0 +1,35 @@
1
+ require "active_model_serializers"
2
+ require "api-pagination"
3
+ require "kaminari"
4
+ require "ransack"
5
+ require "responders"
6
+ require "rswag/api"
7
+ require "rswag/ui"
8
+ require "simple_token_authentication"
9
+ require "versionist"
10
+
11
+ require "power_api/engine"
12
+
13
+ module PowerApi
14
+ extend self
15
+
16
+ # You can add, in this module, your own configuration options as in the example below...
17
+ #
18
+ # attr_writer :my_option
19
+ #
20
+ # def my_option
21
+ # return "Default Value" unless @my_option
22
+ # @my_option
23
+ # end
24
+ #
25
+ # Then, you can customize the default behaviour (typically in a Rails initializer) like this:
26
+ #
27
+ # PowerApi.setup do |config|
28
+ # config.root_url = "Another value"
29
+ # end
30
+
31
+ def setup
32
+ yield self
33
+ require "power_api"
34
+ end
35
+ end
@@ -0,0 +1,28 @@
1
+ module PowerApi
2
+ module GeneratorHelper; end
3
+
4
+ class Engine < ::Rails::Engine
5
+ isolate_namespace PowerApi
6
+
7
+ config.generators do |g|
8
+ g.test_framework :rspec, fixture: false
9
+ g.fixture_replacement :factory_bot, dir: "spec/factories"
10
+ end
11
+
12
+ initializer "initialize" do
13
+ require_relative "./errors"
14
+ require_relative "./generator_helper/active_record_resource"
15
+ require_relative "./generator_helper/version_helper"
16
+ require_relative "./generator_helper/resource_helper"
17
+ require_relative "./generator_helper/swagger_helper"
18
+ require_relative "./generator_helper/ams_helper"
19
+ require_relative "./generator_helper/controller_helper"
20
+ require_relative "./generator_helper/routes_helper"
21
+ require_relative "./generator_helper/pagination_helper"
22
+ require_relative "./generator_helper/simple_token_auth_helper"
23
+ require_relative "./generator_helper/rubocop_helper"
24
+ require_relative "./generator_helper/template_builder_helper"
25
+ require_relative "./generator_helpers"
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,4 @@
1
+ module PowerApi
2
+ class GeneratorError < StandardError; end
3
+ class InvalidVersion < StandardError; end
4
+ end
@@ -0,0 +1,192 @@
1
+ # rubocop:disable Metrics/ModuleLength
2
+ module PowerApi::GeneratorHelper::ActiveRecordResource
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ attr_reader :resource_attributes
7
+ end
8
+
9
+ def resource_name=(value)
10
+ @resource_name = value
11
+
12
+ if !resource_class
13
+ raise PowerApi::GeneratorError.new(
14
+ "Invalid resource name. Must be the snake_case representation of a ruby class"
15
+ )
16
+ end
17
+
18
+ if !resource_is_active_record_model?
19
+ raise PowerApi::GeneratorError.new("resource is not an active record model")
20
+ end
21
+ end
22
+
23
+ def resource_attributes=(collection)
24
+ attributes = format_attributes(collection)
25
+ raise PowerApi::GeneratorError.new("at least one attribute must be added") if attributes.none?
26
+
27
+ @resource_attributes = attributes
28
+ end
29
+
30
+ def id
31
+ "#{snake_case}_id"
32
+ end
33
+
34
+ def upcase
35
+ snake_case.upcase
36
+ end
37
+
38
+ def upcase_plural
39
+ plural.upcase
40
+ end
41
+
42
+ def camel
43
+ resource_name.camelize
44
+ end
45
+
46
+ def camel_plural
47
+ camel.pluralize
48
+ end
49
+
50
+ def plural
51
+ snake_case.pluralize
52
+ end
53
+
54
+ def snake_case
55
+ resource_name.underscore
56
+ end
57
+
58
+ def titleized
59
+ resource_name.titleize
60
+ end
61
+
62
+ def plural_titleized
63
+ plural.titleize
64
+ end
65
+
66
+ def path
67
+ "app/models/#{snake_case}.rb"
68
+ end
69
+
70
+ def class_definition_line
71
+ "class #{camel} < ApplicationRecord\n"
72
+ end
73
+
74
+ def attributes_names
75
+ extract_attrs_names(resource_attributes)
76
+ end
77
+
78
+ def required_attributes_names
79
+ extract_attrs_names(required_resource_attributes)
80
+ end
81
+
82
+ def permitted_attributes_names
83
+ extract_attrs_names(permitted_attributes)
84
+ end
85
+
86
+ def permitted_attributes
87
+ resource_attributes.reject do |attr|
88
+ [:created_at, :updated_at].include?(attr[:name])
89
+ end
90
+ end
91
+
92
+ def required_resource_attributes
93
+ permitted_attributes.select { |attr| attr[:required] }
94
+ end
95
+
96
+ def optional_resource_attributes
97
+ permitted_attributes.reject { |attr| attr[:required] }
98
+ end
99
+
100
+ def attributes_symbols_text_list
101
+ attrs_to_symobls_text_list(attributes_names)
102
+ end
103
+
104
+ def permitted_attributes_symbols_text_list
105
+ attrs_to_symobls_text_list(permitted_attributes_names)
106
+ end
107
+
108
+ private
109
+
110
+ def resource_name
111
+ @resource_name
112
+ end
113
+
114
+ def extract_attrs_names(attrs)
115
+ attrs.map { |attr| attr[:name] }
116
+ end
117
+
118
+ def attrs_to_symobls_text_list(attrs)
119
+ attrs.map { |a| ":#{a}" }.join(",\n") + "\n"
120
+ end
121
+
122
+ def format_attributes(attrs)
123
+ columns = resource_class.columns.inject([]) do |memo, col|
124
+ col_name = col.name.to_sym
125
+ next memo if col_name == :id
126
+
127
+ memo << {
128
+ name: col_name,
129
+ type: col.type,
130
+ swagger_type: get_swagger_type(col.type),
131
+ required: required_attribute?(col_name),
132
+ example: get_attribute_example(col.type, col_name)
133
+ }
134
+
135
+ memo
136
+ end
137
+
138
+ return columns if attrs.blank?
139
+
140
+ attrs = attrs.map(&:to_sym)
141
+ columns.select { |col| attrs.include?(col[:name]) }
142
+ end
143
+
144
+ def get_swagger_type(data_type)
145
+ case data_type
146
+ when :integer
147
+ :integer
148
+ when :float, :decimal
149
+ :float
150
+ when :boolean
151
+ :boolean
152
+ else
153
+ :string
154
+ end
155
+ end
156
+
157
+ def get_attribute_example(data_type, col_name)
158
+ case data_type
159
+ when :date
160
+ "'1984-06-04'"
161
+ when :datetime
162
+ "'1984-06-04 09:00'"
163
+ when :integer
164
+ 666
165
+ when :float, :decimal
166
+ 6.66
167
+ when :boolean
168
+ true
169
+ else
170
+ "'Some #{col_name}'"
171
+ end
172
+ end
173
+
174
+ def required_attribute?(col_name)
175
+ validator_names = resource_class.validators_on(col_name).map do |validator|
176
+ validator.class.name
177
+ end
178
+
179
+ validator_names.include?("ActiveRecord::Validations::PresenceValidator")
180
+ end
181
+
182
+ def resource_class
183
+ resource_name.classify.constantize
184
+ rescue NameError
185
+ false
186
+ end
187
+
188
+ def resource_is_active_record_model?
189
+ !!ActiveRecord::Base.descendants.find { |model_class| model_class == resource_class }
190
+ end
191
+ end
192
+ # rubocop:enable Metrics/ModuleLength
@@ -0,0 +1,43 @@
1
+ module PowerApi::GeneratorHelper::AmsHelper
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ include PowerApi::GeneratorHelper::VersionHelper
6
+ include PowerApi::GeneratorHelper::ResourceHelper
7
+ end
8
+
9
+ def ams_initializer_path
10
+ "config/initializers/active_model_serializers.rb"
11
+ end
12
+
13
+ def ams_serializer_path
14
+ "app/serializers/api/v#{version_number}/#{resource.snake_case}_serializer.rb"
15
+ end
16
+
17
+ def ams_serializers_path
18
+ "app/serializers/api/v#{version_number}/.gitkeep"
19
+ end
20
+
21
+ def ams_initializer_tpl
22
+ <<~INITIALIZER
23
+ class ActiveModelSerializers::Adapter::JsonApi
24
+ def self.default_key_transform
25
+ :unaltered
26
+ end
27
+ end
28
+
29
+ ActiveModelSerializers.config.adapter = :json_api
30
+ INITIALIZER
31
+ end
32
+
33
+ def ams_serializer_tpl
34
+ <<~SERIALIZER
35
+ class Api::V#{version_number}::#{resource.camel}Serializer < ActiveModel::Serializer
36
+ type :#{resource.snake_case}
37
+
38
+ attributes(
39
+ #{resource.attributes_symbols_text_list})
40
+ end
41
+ SERIALIZER
42
+ end
43
+ end
@@ -0,0 +1,184 @@
1
+ # rubocop:disable Metrics/ModuleLength
2
+ module PowerApi::GeneratorHelper::ControllerHelper
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ include PowerApi::GeneratorHelper::VersionHelper
7
+ include PowerApi::GeneratorHelper::ResourceHelper
8
+ include PowerApi::GeneratorHelper::PaginationHelper
9
+ include PowerApi::GeneratorHelper::SimpleTokenAuthHelper
10
+ include PowerApi::GeneratorHelper::TemplateBuilderHelper
11
+
12
+ attr_accessor :allow_filters
13
+ end
14
+
15
+ def api_base_controller_path
16
+ "app/controllers/api/base_controller.rb"
17
+ end
18
+
19
+ def base_controller_path
20
+ "app/controllers/api/v#{version_number}/base_controller.rb"
21
+ end
22
+
23
+ def resource_controller_path
24
+ "app/controllers/api/v#{version_number}/#{resource.plural}_controller.rb"
25
+ end
26
+
27
+ def api_base_controller_tpl
28
+ <<~CONTROLLER
29
+ class Api::BaseController < PowerApi::BaseController
30
+ end
31
+ CONTROLLER
32
+ end
33
+
34
+ def base_controller_tpl
35
+ <<~CONTROLLER
36
+ class Api::V#{version_number}::BaseController < Api::BaseController
37
+ before_action do
38
+ self.namespace_for_serializer = ::Api::V#{version_number}
39
+ end
40
+ end
41
+ CONTROLLER
42
+ end
43
+
44
+ def resource_controller_tpl
45
+ tpl_class(
46
+ ctrl_tpl_class_definition_line,
47
+ ctrl_tpl_acts_as_token_authentication_handler,
48
+ ctrl_tpl_index,
49
+ ctrl_tpl_show,
50
+ ctrl_tpl_create,
51
+ ctrl_tpl_update,
52
+ ctrl_tpl_destroy,
53
+ "private",
54
+ ctrl_tpl_resource,
55
+ ctrl_tpl_resources_from_authenticated_resource,
56
+ ctrl_tpl_find_parent_resource,
57
+ ctrl_tpl_permitted_params
58
+ )
59
+ end
60
+
61
+ private
62
+
63
+ def ctrl_tpl_class_definition_line
64
+ "Api::V#{version_number}::#{resource.camel_plural}Controller < \
65
+ Api::V#{version_number}::BaseController"
66
+ end
67
+
68
+ def ctrl_tpl_acts_as_token_authentication_handler
69
+ return unless authenticated_resource?
70
+
71
+ "acts_as_token_authentication_handler_for #{authenticated_resource.camel}, \
72
+ fallback: :exception\n"
73
+ end
74
+
75
+ def ctrl_tpl_index
76
+ concat_tpl_method("index", "respond_with #{ctrl_tpl_index_resources}")
77
+ end
78
+
79
+ def ctrl_tpl_show
80
+ concat_tpl_method("show", "respond_with #{resource.snake_case}")
81
+ end
82
+
83
+ def ctrl_tpl_create
84
+ concat_tpl_method("create", "respond_with #{ctrl_tpl_create_resource}")
85
+ end
86
+
87
+ def ctrl_tpl_update
88
+ concat_tpl_method(
89
+ "update",
90
+ "respond_with #{resource.snake_case}.update!(#{resource.snake_case}_params)"
91
+ )
92
+ end
93
+
94
+ def ctrl_tpl_destroy
95
+ concat_tpl_method("destroy", "respond_with #{resource.snake_case}.destroy!")
96
+ end
97
+
98
+ def ctrl_tpl_resource
99
+ concat_tpl_method(resource.snake_case, "@#{resource.snake_case} ||= #{ctrl_tpl_find_resource}")
100
+ end
101
+
102
+ def ctrl_tpl_permitted_params
103
+ concat_tpl_method(
104
+ "#{resource.snake_case}_params",
105
+ "params.require(:#{resource.snake_case}).permit(",
106
+ "#{resource.permitted_attributes_symbols_text_list})"
107
+ )
108
+ end
109
+
110
+ def ctrl_tpl_find_resource
111
+ find_statement = "find_by!(id: params[:id])"
112
+ resource_source = if owned_by_authenticated_resource?
113
+ if parent_resource?
114
+ "#{resource.camel}.where(#{parent_resource.snake_case}: \
115
+ #{current_authenticated_resource}.#{parent_resource.plural})"
116
+ else
117
+ resource.plural
118
+ end
119
+ else
120
+ resource.camel
121
+ end
122
+
123
+ "#{resource_source}.#{find_statement}"
124
+ end
125
+
126
+ def ctrl_tpl_index_resources
127
+ return ctrl_tpl_index_collection unless use_paginator
128
+
129
+ "paginate(#{ctrl_tpl_index_collection})"
130
+ end
131
+
132
+ def ctrl_tpl_index_collection
133
+ collection = owned_resource? ? resource.plural : "#{resource.camel}.all"
134
+ return collection unless allow_filters
135
+
136
+ "filtered_collection(#{collection})"
137
+ end
138
+
139
+ def ctrl_tpl_create_resource
140
+ create_statement = "create!(#{resource.snake_case}_params)"
141
+
142
+ if owned_resource?
143
+ "#{resource.plural}.#{create_statement}"
144
+ else
145
+ "#{resource.camel}.#{create_statement}"
146
+ end
147
+ end
148
+
149
+ def ctrl_tpl_resources_from_authenticated_resource
150
+ return unless owned_resource?
151
+
152
+ resource_source = if owned_by_authenticated_resource? && !parent_resource?
153
+ current_authenticated_resource
154
+ else
155
+ parent_resource.snake_case
156
+ end
157
+
158
+ concat_tpl_method(
159
+ resource.plural,
160
+ "@#{resource.plural} ||= #{resource_source}.#{resource.plural}"
161
+ )
162
+ end
163
+
164
+ def ctrl_tpl_find_parent_resource
165
+ return unless parent_resource?
166
+
167
+ resource_source = if owned_by_authenticated_resource?
168
+ "#{current_authenticated_resource}.#{parent_resource.plural}"
169
+ else
170
+ parent_resource.camel
171
+ end
172
+
173
+ concat_tpl_method(
174
+ parent_resource.snake_case,
175
+ "@#{parent_resource.snake_case} ||= #{resource_source}.\
176
+ find_by!(id: params[:#{parent_resource.id}])"
177
+ )
178
+ end
179
+
180
+ def owned_resource?
181
+ owned_by_authenticated_resource? || parent_resource?
182
+ end
183
+ end
184
+ # rubocop:enable Metrics/ModuleLength