power_api 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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