plutonium 0.10.0 → 0.10.2
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/README.md +2 -0
- data/app/assets/javascripts/turbo/index.js +1 -1
- data/app/views/application/_resource_header.html.erb +12 -12
- data/app/views/layouts/resource.html.erb +1 -0
- data/app/views/layouts/rodauth.html.erb +4 -4
- data/app/views/resource/_nav_user.html.erb +1 -1
- data/app/views/resource/index.rabl +1 -1
- data/brakeman.ignore +1 -1
- data/config/initializers/rabl.rb +2 -0
- data/css.manifest +1 -1
- data/js.manifest +2 -2
- data/lib/generators/pu/core/install/templates/config/initializers/plutonium.rb +0 -3
- data/lib/generators/pu/gen/pug/pug_generator.rb +6 -0
- data/lib/generators/pu/gen/pug/templates/pug.rb.tt +1 -1
- data/lib/generators/pu/pkg/app/templates/config/routes.rb.tt +3 -3
- data/lib/plutonium/config.rb +1 -11
- data/lib/plutonium/core/autodiscovery/input_discoverer.rb +1 -1
- data/lib/plutonium/core/autodiscovery/renderer_discoverer.rb +1 -1
- data/lib/plutonium/core/controllers/base.rb +13 -3
- data/lib/plutonium/core/controllers/queryable.rb +3 -1
- data/lib/plutonium/pkg/app.rb +6 -0
- data/lib/plutonium/railtie.rb +15 -0
- data/lib/plutonium/reloader.rb +99 -0
- data/lib/plutonium/resource/controller.rb +61 -22
- data/lib/plutonium/resource/policy.rb +56 -9
- data/lib/plutonium/resource/presenter.rb +44 -12
- data/lib/plutonium/resource/query_object.rb +186 -73
- data/lib/plutonium/resource/record.rb +213 -119
- data/lib/plutonium/rodauth/controller_methods.rb +7 -0
- data/lib/plutonium/version.rb +1 -1
- data/lib/plutonium.rb +50 -12
- data/package-lock.json +174 -0
- data/package.json +2 -0
- data/public/plutonium-assets/plutonium-app-6WILQCTT.js +39 -0
- data/public/plutonium-assets/plutonium-app-6WILQCTT.js.map +7 -0
- data/public/plutonium-assets/plutonium-logo-original.png +0 -0
- data/public/plutonium-assets/plutonium-logo-white.png +0 -0
- data/public/plutonium-assets/plutonium-logo.png +0 -0
- data/public/plutonium-assets/plutonium.2d4f0c333cd000051d3b.css +3424 -0
- data/public/plutonium-assets/plutonium.ico +0 -0
- metadata +10 -4
- data/lib/plutonium/reactor/core.rb +0 -78
- data/public/plutonium-assets/logo.png +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d56979564e5b0903e39197ae70e304de7848c38c02edcc039a74f9e76093931
|
4
|
+
data.tar.gz: 19a28e7518edcce1ee883b65bb13d5f4ad97b3eb4820dd00a5ebdb4eeeb1ebf6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4177cf2f8f722f19d843961f155286bee3f0bdbf5536233f1850aa8917cb8fd18aae685584747779101024bc761bc3fdfb14a396f537fcee2ec080fcf02acff
|
7
|
+
data.tar.gz: 6ae52cb87299fb2050416fbcb6dce8fe56412b16ca8c570b77a856bfd08fd8eda1ce5c1b4517fbb56583b4d2312f86adbe3c7837fcca77cc1a29765407dd1ff5
|
data/README.md
CHANGED
@@ -56,6 +56,8 @@ TODO: Write usage instructions here
|
|
56
56
|
|
57
57
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
58
58
|
|
59
|
+
To build assets, run `npm dev`
|
60
|
+
|
59
61
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
60
62
|
|
61
63
|
## Contributing
|
@@ -35,13 +35,15 @@
|
|
35
35
|
</svg>
|
36
36
|
<span class="sr-only">Toggle sidebar</span>
|
37
37
|
</button>
|
38
|
-
<a href="
|
38
|
+
<a href="<%= root_path %>" class="flex items-center justify-between mr-4">
|
39
39
|
<img
|
40
|
-
src="
|
41
|
-
class="mr-3 h-
|
42
|
-
alt="
|
40
|
+
src="<%= Plutonium.logo_link %>"
|
41
|
+
class="mr-3 h-10"
|
42
|
+
alt="<%= application_name %> Logo"
|
43
43
|
/>
|
44
|
-
<span class="self-center text-2xl font-semibold whitespace-nowrap dark:text-white hidden xs:block">
|
44
|
+
<span class="self-center text-2xl font-semibold whitespace-nowrap dark:text-white hidden xs:block">
|
45
|
+
<%= application_name %>
|
46
|
+
</span>
|
45
47
|
</a>
|
46
48
|
<%# <form action="#" method="GET" class="hidden md:block md:pl-2">
|
47
49
|
<label for="topbar-search" class="sr-only">Search</label>
|
@@ -704,18 +706,16 @@
|
|
704
706
|
</a>
|
705
707
|
</li>
|
706
708
|
</ul>
|
709
|
+
|
710
|
+
<% if respond_to? :logout_url -%>
|
707
711
|
<ul
|
708
712
|
class="py-1 text-gray-700 dark:text-gray-300"
|
709
|
-
aria-labelledby="dropdown"
|
710
|
-
>
|
713
|
+
aria-labelledby="dropdown">
|
711
714
|
<li>
|
712
|
-
|
713
|
-
href="#"
|
714
|
-
class="block py-2 px-4 text-sm hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"
|
715
|
-
>Sign out</a
|
716
|
-
>
|
715
|
+
<%= link_to "Sign out", logout_url, class: "block py-2 px-4 text-sm hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white", data: { turbo: false } %>
|
717
716
|
</li>
|
718
717
|
</ul>
|
718
|
+
<% end -%>
|
719
719
|
</div>
|
720
720
|
</div>
|
721
721
|
</div>
|
@@ -7,6 +7,7 @@
|
|
7
7
|
<meta name="turbo-cache-control" content="no-cache">
|
8
8
|
<meta name="turbo-refresh-method" content="morph">
|
9
9
|
<meta name="turbo-refresh-scroll" content="preserve">
|
10
|
+
<link rel="icon" type="image/x-icon" href="<%= Plutonium.favicon_link %>">
|
10
11
|
<%= csrf_meta_tags %>
|
11
12
|
<%= csp_meta_tag %>
|
12
13
|
<%= yield(:meta) %>
|
@@ -17,10 +17,10 @@
|
|
17
17
|
</head>
|
18
18
|
<body class="antialiased bg-gray-50 dark:bg-gray-900">
|
19
19
|
<main div class="flex flex-col items-center justify-center px-6 py-8 mx-auto md:h-screen lg:py-0">
|
20
|
-
<
|
21
|
-
<img class="w-
|
22
|
-
|
23
|
-
</
|
20
|
+
<p class="flex items-center mb-6 text-2xl font-semibold text-gray-900 dark:text-white">
|
21
|
+
<img class="w-16 h-16 mr-2" src="<%= Plutonium.logo_link %>" alt="logo">
|
22
|
+
<%= application_name %>
|
23
|
+
</p>
|
24
24
|
<div class="w-full bg-white rounded-lg shadow dark:border md:mt-0 sm:max-w-md xl:p-0 dark:bg-gray-800 dark:border-gray-700">
|
25
25
|
<div class="p-6 space-y-4 md:space-y-6 sm:p-8">
|
26
26
|
<%= yield %>
|
@@ -1,4 +1,4 @@
|
|
1
1
|
<%= display_name_of current_user %>
|
2
2
|
<% if respond_to? :logout_url -%>
|
3
|
-
<%= link_to "Sign out",
|
3
|
+
<%= link_to "Sign out", logout_url, class: "btn btn-outline-primary", data: { turbo: false } %>
|
4
4
|
<% end -%>
|
data/brakeman.ignore
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
"fingerprint": "1cb8570b8c91f38317cdf909e01e7016359846174f427e86011633c344d30fc3",
|
7
7
|
"check_name": "ForgerySetting",
|
8
8
|
"message": "`protect_from_forgery` should be called in `Plutonium::Resource::Controller`",
|
9
|
-
"file": "lib/plutonium/
|
9
|
+
"file": "lib/plutonium/resource/controller.rb",
|
10
10
|
"line": 10,
|
11
11
|
"link": "https://brakemanscanner.org/docs/warning_types/cross-site_request_forgery/",
|
12
12
|
"code": null,
|
data/config/initializers/rabl.rb
CHANGED
data/css.manifest
CHANGED
data/js.manifest
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
<%= package_name %>::Engine.
|
2
|
-
|
1
|
+
<%= package_name %>::Engine.draw_custom_routes do
|
2
|
+
# draw custom routes here
|
3
3
|
|
4
|
-
|
4
|
+
root to: "dashboard#index"
|
5
5
|
end
|
6
6
|
|
7
7
|
# draw routes for registered resources
|
data/lib/plutonium/config.rb
CHANGED
@@ -1,18 +1,8 @@
|
|
1
1
|
require "active_support"
|
2
|
+
require "active_model"
|
2
3
|
|
3
4
|
module Plutonium
|
4
5
|
module Config
|
5
|
-
# @return [Boolean] Are we developing plutonium? This is separate from Rails development.
|
6
|
-
mattr_accessor :development
|
7
|
-
@@development = defined?(Rails.env) && Rails.env.development?
|
8
|
-
|
9
|
-
# @return [Boolean] Should hotreload be enabled? Enabled by default in Rails development.
|
10
|
-
mattr_accessor :enable_hotreload
|
11
|
-
@@enable_hotreload = defined?(Rails.env) && Rails.env.development?
|
12
|
-
|
13
|
-
mattr_accessor :cache_discovery
|
14
|
-
@@cache_discovery = defined?(Rails.env) && !Rails.env.development?
|
15
|
-
|
16
6
|
mattr_accessor :stylesheet_tag
|
17
7
|
@@stylesheet_tag = ->(view_context) {
|
18
8
|
"<link rel=\"stylesheet\" href=\"#{Plutonium.stylesheet_link}\" />"
|
@@ -14,7 +14,7 @@ module Plutonium
|
|
14
14
|
# If cache_discovery is enabled, use the class level cache that persists
|
15
15
|
# between requests, otherwise use the instance one.
|
16
16
|
def autodiscovery_input_cache
|
17
|
-
if
|
17
|
+
if Rails.application.config.plutonium.cache_discovery
|
18
18
|
self.class.autodiscovery_input_cache
|
19
19
|
else
|
20
20
|
@autodiscovery_input_cache ||= {}
|
@@ -14,7 +14,7 @@ module Plutonium
|
|
14
14
|
# If cache_discovery is enabled, use the class level cache that persists
|
15
15
|
# between requests, otherwise use the instance one.
|
16
16
|
def autodiscovery_renderer_cache
|
17
|
-
if
|
17
|
+
if Rails.application.config.plutonium.cache_discovery
|
18
18
|
self.class.autodiscovery_renderer_cache
|
19
19
|
else
|
20
20
|
@autodiscovery_renderer_cache ||= {}
|
@@ -18,7 +18,7 @@ module Plutonium
|
|
18
18
|
end
|
19
19
|
|
20
20
|
helper Plutonium::Helpers
|
21
|
-
helper_method :page_title, :resource_url_for, :resource_url_args_for
|
21
|
+
helper_method :page_title, :resource_url_for, :resource_url_args_for, :root_path, :application_name
|
22
22
|
|
23
23
|
append_view_path File.expand_path("app/views", Plutonium.root)
|
24
24
|
layout -> { turbo_frame_request? ? false : "resource" }
|
@@ -27,11 +27,15 @@ module Plutonium
|
|
27
27
|
private
|
28
28
|
|
29
29
|
def set_page_title
|
30
|
-
@page_title =
|
30
|
+
@page_title = nil
|
31
31
|
end
|
32
32
|
|
33
33
|
def page_title(title)
|
34
|
-
[title.presence,
|
34
|
+
[title.presence, application_name].compact.join(" | ")
|
35
|
+
end
|
36
|
+
|
37
|
+
def application_name
|
38
|
+
Rails.application.class.module_parent.name
|
35
39
|
end
|
36
40
|
|
37
41
|
#
|
@@ -80,6 +84,12 @@ module Plutonium
|
|
80
84
|
def resource_url_for(...)
|
81
85
|
send(current_package.name.underscore.to_sym).url_for(resource_url_args_for(...))
|
82
86
|
end
|
87
|
+
|
88
|
+
def root_path(*)
|
89
|
+
return send(:"#{scoped_entity_param_key}_root_path", *) if scoped_to_entity? && scoped_entity_strategy == :path
|
90
|
+
|
91
|
+
super(*)
|
92
|
+
end
|
83
93
|
end
|
84
94
|
end
|
85
95
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
using Plutonium::Refinements::ParameterRefinements
|
2
|
+
|
1
3
|
module Plutonium
|
2
4
|
module Core
|
3
5
|
module Controllers
|
@@ -18,7 +20,7 @@ module Plutonium
|
|
18
20
|
end
|
19
21
|
|
20
22
|
def resource_query_params
|
21
|
-
(params[:q]&.to_unsafe_h || {}).with_indifferent_access
|
23
|
+
(params[:q]&.nilify&.to_unsafe_h || {}).with_indifferent_access
|
22
24
|
end
|
23
25
|
end
|
24
26
|
end
|
data/lib/plutonium/pkg/app.rb
CHANGED
@@ -44,7 +44,12 @@ module Plutonium
|
|
44
44
|
}.to_h
|
45
45
|
end
|
46
46
|
|
47
|
+
def draw_custom_routes(&block)
|
48
|
+
@custom_routes_block = block
|
49
|
+
end
|
50
|
+
|
47
51
|
def draw_resource_routes
|
52
|
+
custom_routes_block = @custom_routes_block
|
48
53
|
registered_resources = resource_register
|
49
54
|
scoped_entity_param_key = self.scoped_entity_param_key if scoped_entity_strategy == :path
|
50
55
|
routes.draw do
|
@@ -111,6 +116,7 @@ module Plutonium
|
|
111
116
|
scope_options = scoped_entity_param_key.present? ? {as: scoped_entity_param_key} : {}
|
112
117
|
|
113
118
|
scope scope_name, scope_options do
|
119
|
+
instance_exec(&custom_routes_block) if custom_routes_block.present?
|
114
120
|
# we have to reverse sort our resource routes in order to prevent routing conflicts
|
115
121
|
# e.g. /blogs/1 and blogs/comments cause an issue if Blog is registered before Blogs::Comment
|
116
122
|
# attempting to load blogs/comments routes to blogs/:id which fails with a 404 since BlogsController
|
data/lib/plutonium/railtie.rb
CHANGED
@@ -3,6 +3,8 @@ require "view_component"
|
|
3
3
|
module Plutonium
|
4
4
|
class Railtie < Rails::Railtie
|
5
5
|
config.plutonium = ActiveSupport::OrderedOptions.new
|
6
|
+
config.plutonium.cache_discovery = defined?(Rails.env) && !Rails.env.development?
|
7
|
+
config.plutonium.enable_hotreload = defined?(Rails.env) && Rails.env.development?
|
6
8
|
|
7
9
|
initializer "plutonium.append_assets_path" do |app|
|
8
10
|
config.to_prepare do
|
@@ -10,6 +12,14 @@ module Plutonium
|
|
10
12
|
end
|
11
13
|
end
|
12
14
|
|
15
|
+
initializer "plutonium.load_view_components" do
|
16
|
+
load Plutonium.root.join("app", "views", "components", "base.rb")
|
17
|
+
end
|
18
|
+
|
19
|
+
initializer "plutonium.load_initializers" do
|
20
|
+
Dir.glob(Plutonium.root.join("config", "initializers", "**", "*.rb")) { |file| load file }
|
21
|
+
end
|
22
|
+
|
13
23
|
initializer "plutonium.asset_server" do
|
14
24
|
# setup a middleware to serve our assets
|
15
25
|
config.app_middleware.insert_before(
|
@@ -28,5 +38,10 @@ module Plutonium
|
|
28
38
|
initializer "plutonium.view_components_capture_compat" do
|
29
39
|
config.view_component.capture_compatibility_patch_enabled = true
|
30
40
|
end
|
41
|
+
|
42
|
+
config.after_initialize do
|
43
|
+
Plutonium::Reloader.start! if Rails.application.config.plutonium.enable_hotreload
|
44
|
+
Plutonium::ZEITWERK_LOADER.eager_load if Rails.env.production?
|
45
|
+
end
|
31
46
|
end
|
32
47
|
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
# This is a glorified initializer
|
3
|
+
|
4
|
+
module Plutonium
|
5
|
+
class Reloader
|
6
|
+
class << self
|
7
|
+
def start!
|
8
|
+
puts "=> [plutonium] starting reloader"
|
9
|
+
|
10
|
+
@listener&.stop
|
11
|
+
@listener = initialize_listener
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def initialize_listener
|
17
|
+
require "listen"
|
18
|
+
|
19
|
+
reload_paths = gather_reload_paths
|
20
|
+
return unless reload_paths.any?
|
21
|
+
|
22
|
+
listener = Listen.to(*reload_paths, only: /\.rb$/) do |modified, added, removed|
|
23
|
+
handle_file_changes(modified, added, removed)
|
24
|
+
end
|
25
|
+
listener.start
|
26
|
+
listener
|
27
|
+
end
|
28
|
+
|
29
|
+
def gather_reload_paths
|
30
|
+
reload_paths = []
|
31
|
+
|
32
|
+
if Plutonium.development?
|
33
|
+
reload_paths << Plutonium.lib_root.to_s
|
34
|
+
reload_paths << Plutonium.root.join("app", "views", "components").to_s
|
35
|
+
reload_paths << Plutonium.root.join("config", "initializers").to_s
|
36
|
+
end
|
37
|
+
|
38
|
+
packages_dir = Rails.root.join("packages/").to_s
|
39
|
+
reload_paths << packages_dir if File.directory?(packages_dir)
|
40
|
+
|
41
|
+
reload_paths
|
42
|
+
end
|
43
|
+
|
44
|
+
def handle_file_changes(modified, added, removed)
|
45
|
+
(modified + added).each do |file|
|
46
|
+
Plutonium.logger.debug "[plutonium] change detected: #{file}"
|
47
|
+
|
48
|
+
if file == __FILE__
|
49
|
+
reload_file(file)
|
50
|
+
start!
|
51
|
+
elsif file_starts_with_packages_dir?(file)
|
52
|
+
handle_package_file_changes(file, added)
|
53
|
+
else
|
54
|
+
reload_framework_and_file(file)
|
55
|
+
end
|
56
|
+
rescue => e
|
57
|
+
log_reload_failure(file, e)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def file_starts_with_packages_dir?(file)
|
62
|
+
packages_dir = Rails.root.join("packages/").to_s
|
63
|
+
file.starts_with?(packages_dir)
|
64
|
+
end
|
65
|
+
|
66
|
+
def handle_package_file_changes(file, added)
|
67
|
+
return if added.include?(file)
|
68
|
+
|
69
|
+
case File.basename(file)
|
70
|
+
when "engine.rb"
|
71
|
+
reload_engine_and_routes(file)
|
72
|
+
else
|
73
|
+
# Non-engine package files are reloaded by Rails automatically
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def reload_engine_and_routes(file)
|
78
|
+
Plutonium.logger.debug "[plutonium] reloading #{file}"
|
79
|
+
load file
|
80
|
+
Rails.application.reload_routes!
|
81
|
+
end
|
82
|
+
|
83
|
+
def reload_framework_and_file(file)
|
84
|
+
Plutonium.logger.debug "[plutonium] reloading framework"
|
85
|
+
Plutonium::ZEITWERK_LOADER.reload
|
86
|
+
load Plutonium.root.join("app", "views", "components", "base.rb")
|
87
|
+
load file # Ensure files that do not contain constants are loaded
|
88
|
+
end
|
89
|
+
|
90
|
+
def reload_file(file)
|
91
|
+
load file
|
92
|
+
end
|
93
|
+
|
94
|
+
def log_reload_failure(file, error)
|
95
|
+
Plutonium.logger.error "\n[plutonium] reload failed #{file}\n\n#{error}\n"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -6,6 +6,7 @@ using Plutonium::Refinements::ParameterRefinements
|
|
6
6
|
|
7
7
|
module Plutonium
|
8
8
|
module Resource
|
9
|
+
# Controller module to handle resource actions and concerns
|
9
10
|
module Controller
|
10
11
|
extend ActiveSupport::Concern
|
11
12
|
include Pagy::Backend
|
@@ -17,7 +18,6 @@ module Plutonium
|
|
17
18
|
include Plutonium::Core::Controllers::InteractiveActions
|
18
19
|
|
19
20
|
included do
|
20
|
-
# we use class attribute since we want this value inherited
|
21
21
|
class_attribute :resource_class, instance_writer: false, instance_predicate: false
|
22
22
|
|
23
23
|
# https://github.com/ddnexus/pagy/blob/master/docs/extras/headers.md#headers
|
@@ -27,6 +27,8 @@ module Plutonium
|
|
27
27
|
end
|
28
28
|
|
29
29
|
class_methods do
|
30
|
+
# Sets the resource class for the controller
|
31
|
+
# @param [Class] resource_class The resource class
|
30
32
|
def controller_for(resource_class)
|
31
33
|
self.resource_class = resource_class
|
32
34
|
end
|
@@ -34,6 +36,8 @@ module Plutonium
|
|
34
36
|
|
35
37
|
private
|
36
38
|
|
39
|
+
# Creates a policy context
|
40
|
+
# @return [Plutonium::Resource::PolicyContext] The policy context
|
37
41
|
def policy_context
|
38
42
|
Plutonium::Resource::PolicyContext.new(
|
39
43
|
user: current_user,
|
@@ -41,10 +45,14 @@ module Plutonium
|
|
41
45
|
)
|
42
46
|
end
|
43
47
|
|
48
|
+
# Returns the resource record based on path parameters
|
49
|
+
# @return [ActiveRecord::Base, nil] The resource record
|
44
50
|
def resource_record
|
45
|
-
@resource_record ||=
|
51
|
+
@resource_record ||= policy_scope(resource_class).from_path_param(params[:id]).first! if params[:id].present?
|
46
52
|
end
|
47
53
|
|
54
|
+
# Returns the submitted resource parameters
|
55
|
+
# @return [Hash] The submitted resource parameters
|
48
56
|
def submitted_resource_params
|
49
57
|
@submitted_resource_params ||= begin
|
50
58
|
strong_parameters = resource_class.strong_parameters_for(*permitted_attributes)
|
@@ -52,24 +60,25 @@ module Plutonium
|
|
52
60
|
end
|
53
61
|
end
|
54
62
|
|
63
|
+
# Returns the resource parameters, including scoped and parent parameters
|
64
|
+
# @return [Hash] The resource parameters
|
55
65
|
def resource_params
|
56
66
|
input_params = submitted_resource_params.dup
|
57
67
|
|
58
|
-
|
59
|
-
input_params
|
60
|
-
input_params[:"#{scoped_entity_param_key}_id"] = current_scoped_entity.id if scoped_to_entity?
|
61
|
-
# Override any parent params
|
62
|
-
input_params[parent_input_param] = current_parent if current_parent.present?
|
63
|
-
input_params[:"#{parent_input_param}_id"] = current_parent.id if current_parent.present?
|
68
|
+
override_entity_scoping_params(input_params)
|
69
|
+
override_parent_params(input_params)
|
64
70
|
|
65
|
-
# additionally filter our input_params through our inputs
|
66
71
|
current_presenter.defined_inputs_for(*permitted_attributes).collect_all(input_params)
|
67
72
|
end
|
68
73
|
|
74
|
+
# Returns the resource parameter key
|
75
|
+
# @return [Symbol] The resource parameter key
|
69
76
|
def resource_param_key
|
70
77
|
resource_class.model_name.singular_route_key
|
71
78
|
end
|
72
79
|
|
80
|
+
# Creates a resource context
|
81
|
+
# @return [Plutonium::Resource::Context] The resource context
|
73
82
|
def resource_context
|
74
83
|
Plutonium::Resource::Context.new(
|
75
84
|
resource_class:,
|
@@ -78,29 +87,32 @@ module Plutonium
|
|
78
87
|
)
|
79
88
|
end
|
80
89
|
|
90
|
+
# Creates a resource presenter
|
91
|
+
# @param [Class] resource_class The resource class
|
92
|
+
# @param [ActiveRecord::Base] resource_record The resource record
|
93
|
+
# @return [Object] The resource presenter
|
81
94
|
def resource_presenter(resource_class, resource_record)
|
82
95
|
presenter_class = "#{current_package}::#{resource_class}Presenter".constantize
|
83
96
|
presenter_class.new resource_context, resource_record
|
84
97
|
end
|
85
98
|
|
99
|
+
# Creates a resource query object
|
100
|
+
# @param [Class] resource_class The resource class
|
101
|
+
# @param [ActionController::Parameters] params The request parameters
|
102
|
+
# @return [Object] The resource query object
|
86
103
|
def resource_query_object(resource_class, params)
|
87
104
|
query_object_class = "#{current_package}::#{resource_class}QueryObject".constantize
|
88
105
|
query_object_class.new resource_context, params
|
89
106
|
end
|
90
107
|
|
91
|
-
#
|
108
|
+
# Applies submitted resource params if they have been passed
|
92
109
|
def maybe_apply_submitted_resource_params!
|
93
|
-
|
94
|
-
# we need to ensure that this is being called from get because
|
95
|
-
# it is potentially unsafe since we don't apply the input filter. see #resource_params
|
96
|
-
# would have been nice to be able to, but we can't until we have the presenter, and the presenter
|
97
|
-
# requires the resource_record for our dynamic forms
|
98
|
-
# is this perfect? no. but it works.
|
99
|
-
raise "🚨🚨🚨 this should be called from actions that are not persisting this data" unless request.method == "GET"
|
100
|
-
|
110
|
+
ensure_get_request
|
101
111
|
resource_record.attributes = submitted_resource_params if params[resource_param_key].present?
|
102
112
|
end
|
103
113
|
|
114
|
+
# Returns the current parent based on path parameters
|
115
|
+
# @return [ActiveRecord::Base, nil] The current parent
|
104
116
|
def current_parent
|
105
117
|
return unless parent_route_param.present?
|
106
118
|
|
@@ -113,22 +125,49 @@ module Plutonium
|
|
113
125
|
end
|
114
126
|
end
|
115
127
|
|
128
|
+
# Returns the parent route parameter
|
129
|
+
# @return [Symbol, nil] The parent route parameter
|
116
130
|
def parent_route_param
|
117
131
|
@parent_route_param ||= request.path_parameters.keys.reverse.find { |key| /_id$/.match? key }
|
118
132
|
end
|
119
133
|
|
134
|
+
# Returns the parent input parameter
|
135
|
+
# @return [Symbol, nil] The parent input parameter
|
120
136
|
def parent_input_param
|
121
137
|
return unless current_parent.present?
|
122
138
|
|
123
139
|
resource_class.reflect_on_all_associations(:belongs_to).find { |assoc| assoc.klass.name == current_parent.class.name }&.name&.to_sym
|
124
140
|
end
|
125
141
|
|
126
|
-
|
142
|
+
# Ensures the method is a GET request
|
143
|
+
def ensure_get_request
|
144
|
+
unless request.method == "GET"
|
145
|
+
raise "🚨🚨🚨 This should be called from actions that are not persisting this data"
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# Overrides entity scoping parameters
|
150
|
+
# @param [Hash] input_params The input parameters
|
151
|
+
def override_entity_scoping_params(input_params)
|
152
|
+
if scoped_to_entity?
|
153
|
+
input_params[scoped_entity_param_key] = current_scoped_entity
|
154
|
+
input_params[:"#{scoped_entity_param_key}_id"] = current_scoped_entity.id
|
155
|
+
end
|
156
|
+
end
|
127
157
|
|
128
|
-
#
|
129
|
-
#
|
130
|
-
|
158
|
+
# Overrides parent parameters
|
159
|
+
# @param [Hash] input_params The input parameters
|
160
|
+
def override_parent_params(input_params)
|
161
|
+
if current_parent.present?
|
162
|
+
input_params[parent_input_param] = current_parent
|
163
|
+
input_params[:"#{parent_input_param}_id"] = current_parent.id
|
164
|
+
end
|
165
|
+
end
|
131
166
|
|
167
|
+
# Constructs resource URL arguments
|
168
|
+
# @param [Array] args The URL arguments
|
169
|
+
# @param [Hash] kwargs The keyword arguments
|
170
|
+
# @return [Array] The URL arguments
|
132
171
|
def resource_url_args_for(*args, **kwargs)
|
133
172
|
kwargs[:parent] = current_parent unless kwargs.key?(:parent)
|
134
173
|
super(*args, **kwargs)
|