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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -0
  3. data/app/assets/javascripts/turbo/index.js +1 -1
  4. data/app/views/application/_resource_header.html.erb +12 -12
  5. data/app/views/layouts/resource.html.erb +1 -0
  6. data/app/views/layouts/rodauth.html.erb +4 -4
  7. data/app/views/resource/_nav_user.html.erb +1 -1
  8. data/app/views/resource/index.rabl +1 -1
  9. data/brakeman.ignore +1 -1
  10. data/config/initializers/rabl.rb +2 -0
  11. data/css.manifest +1 -1
  12. data/js.manifest +2 -2
  13. data/lib/generators/pu/core/install/templates/config/initializers/plutonium.rb +0 -3
  14. data/lib/generators/pu/gen/pug/pug_generator.rb +6 -0
  15. data/lib/generators/pu/gen/pug/templates/pug.rb.tt +1 -1
  16. data/lib/generators/pu/pkg/app/templates/config/routes.rb.tt +3 -3
  17. data/lib/plutonium/config.rb +1 -11
  18. data/lib/plutonium/core/autodiscovery/input_discoverer.rb +1 -1
  19. data/lib/plutonium/core/autodiscovery/renderer_discoverer.rb +1 -1
  20. data/lib/plutonium/core/controllers/base.rb +13 -3
  21. data/lib/plutonium/core/controllers/queryable.rb +3 -1
  22. data/lib/plutonium/pkg/app.rb +6 -0
  23. data/lib/plutonium/railtie.rb +15 -0
  24. data/lib/plutonium/reloader.rb +99 -0
  25. data/lib/plutonium/resource/controller.rb +61 -22
  26. data/lib/plutonium/resource/policy.rb +56 -9
  27. data/lib/plutonium/resource/presenter.rb +44 -12
  28. data/lib/plutonium/resource/query_object.rb +186 -73
  29. data/lib/plutonium/resource/record.rb +213 -119
  30. data/lib/plutonium/rodauth/controller_methods.rb +7 -0
  31. data/lib/plutonium/version.rb +1 -1
  32. data/lib/plutonium.rb +50 -12
  33. data/package-lock.json +174 -0
  34. data/package.json +2 -0
  35. data/public/plutonium-assets/plutonium-app-6WILQCTT.js +39 -0
  36. data/public/plutonium-assets/plutonium-app-6WILQCTT.js.map +7 -0
  37. data/public/plutonium-assets/plutonium-logo-original.png +0 -0
  38. data/public/plutonium-assets/plutonium-logo-white.png +0 -0
  39. data/public/plutonium-assets/plutonium-logo.png +0 -0
  40. data/public/plutonium-assets/plutonium.2d4f0c333cd000051d3b.css +3424 -0
  41. data/public/plutonium-assets/plutonium.ico +0 -0
  42. metadata +10 -4
  43. data/lib/plutonium/reactor/core.rb +0 -78
  44. data/public/plutonium-assets/logo.png +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2c06e317739b1f680a765c14d8cec25681b2a4ee8a2f28eb862d64acaab7c131
4
- data.tar.gz: 685ce9c385e2a344d2b67b05c548b9ecbbc9d34f528c610963cacf0f2b6b95cc
3
+ metadata.gz: 6d56979564e5b0903e39197ae70e304de7848c38c02edcc039a74f9e76093931
4
+ data.tar.gz: 19a28e7518edcce1ee883b65bb13d5f4ad97b3eb4820dd00a5ebdb4eeeb1ebf6
5
5
  SHA512:
6
- metadata.gz: 6bb7965e89acbbe4d79e9f2d75b9dddc2d5c8ea7ef55eb4a1d82a9df56f6bef23cba50f696366c651739f9f12afb7da909a904d06c2e4235e2947b680b066ce2
7
- data.tar.gz: 55e6762fd915065bd5f37ecb370196f44f774b19331b9ac42f526c599ed4fb6b1dd75e0a49d6d2330d945ef0058e38de48632990f2a221c02b339ef387d36633
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
@@ -1,4 +1,4 @@
1
- // import * as Turbo from "@hotwired/turbo"
1
+ import * as Turbo from "@hotwired/turbo"
2
2
 
3
3
  import "./turbo_debug"
4
4
  // import "./turbo_actions"
@@ -35,13 +35,15 @@
35
35
  </svg>
36
36
  <span class="sr-only">Toggle sidebar</span>
37
37
  </button>
38
- <a href="https://flowbite.com" class="flex items-center justify-between mr-4">
38
+ <a href="<%= root_path %>" class="flex items-center justify-between mr-4">
39
39
  <img
40
- src="https://flowbite.s3.amazonaws.com/logo.svg"
41
- class="mr-3 h-8"
42
- alt="Flowbite Logo"
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">Plutonium</span>
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
- <a
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
- <a href="#" class="flex items-center mb-6 text-2xl font-semibold text-gray-900 dark:text-white">
21
- <img class="w-8 h-8 mr-2" src="https://flowbite.s3.amazonaws.com/blocks/marketing-ui/logo.svg" alt="logo">
22
- Flowbite
23
- </a>
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", "/", class: "btn btn-outline-primary", data: { turbo: false } %>
3
+ <%= link_to "Sign out", logout_url, class: "btn btn-outline-primary", data: { turbo: false } %>
4
4
  <% end -%>
@@ -1,3 +1,3 @@
1
1
  collection @resource_records, root: resource_class.to_s.demodulize.underscore.pluralize.to_sym, object_root: false
2
2
 
3
- extends "_resource"
3
+ extends "_resource_details"
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/reactor/resource_controller.rb",
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,
@@ -58,3 +58,5 @@ module Rabl
58
58
  end
59
59
  end
60
60
  end
61
+
62
+ Rabl.register!
data/css.manifest CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "plutonium.css": "plutonium.50232e35b5495f5ad90d.css"
2
+ "plutonium.css": "plutonium.2d4f0c333cd000051d3b.css"
3
3
  }
data/js.manifest CHANGED
@@ -1,4 +1,4 @@
1
1
  {
2
- "plutonium-app.js.map": "plutonium-app-36KN5FVJ.js.map",
3
- "plutonium-app.js": "plutonium-app-36KN5FVJ.js"
2
+ "plutonium-app.js.map": "plutonium-app-6WILQCTT.js.map",
3
+ "plutonium-app.js": "plutonium-app-6WILQCTT.js"
4
4
  }
@@ -1,4 +1 @@
1
1
  # Configure plutonium
2
-
3
- # Spin up the reactor!
4
- Plutonium::Reactor::Core.achieve_criticality!
@@ -38,6 +38,12 @@ module Pu
38
38
  def pug_class
39
39
  "#{pug_name.demodulize}Generator"
40
40
  end
41
+
42
+ def lib_path
43
+ depth = name.split(":").count
44
+ base = ([".."] * depth).join "/"
45
+ "#{base}/lib/plutonium_generators"
46
+ end
41
47
  end
42
48
  end
43
49
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require File.expand_path('../../../../plutonium_generators', __dir__)
3
+ require_relative "<%= lib_path %>"
4
4
 
5
5
  module Pu
6
6
  module <%= pug_module %>
@@ -1,7 +1,7 @@
1
- <%= package_name %>::Engine.routes.draw do
2
- root to: "dashboard#index"
1
+ <%= package_name %>::Engine.draw_custom_routes do
2
+ # draw custom routes here
3
3
 
4
- # add custom app routes here
4
+ root to: "dashboard#index"
5
5
  end
6
6
 
7
7
  # draw routes for registered resources
@@ -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 Plutonium::Config.cache_discovery
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 Plutonium::Config.cache_discovery
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 = "Pluton8"
30
+ @page_title = nil
31
31
  end
32
32
 
33
33
  def page_title(title)
34
- [title.presence, Rails.application.class.module_parent.name].compact.join(" | ")
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
@@ -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
@@ -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 ||= (policy_scope(resource_class).from_path_param(params[:id]).first! if params[:id].present?)
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
- # Override any entity scoping params
59
- input_params[scoped_entity_param_key] = current_scoped_entity if scoped_to_entity?
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
- # sets params on submitted_resource_params if they have been passed
108
+ # Applies submitted resource params if they have been passed
92
109
  def maybe_apply_submitted_resource_params!
93
- # this is useful in dynamic forms as we can read the resource record to determine how to define our inputs
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
- # def current_package
129
- # @current_package ||= self.class.module_parents[-2]
130
- # end
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)