plutonium 0.10.1 → 0.10.2

Sign up to get free protection for your applications and to get access to all the features.
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 +0 -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: 62776ccdb807ad168a6e61bcea935268d749a932018c1064c6df354d125e06c2
4
- data.tar.gz: 1bbce05f7591948984c31d1a662b55a098248323e93f0c4e171aac107e132bf6
3
+ metadata.gz: 6d56979564e5b0903e39197ae70e304de7848c38c02edcc039a74f9e76093931
4
+ data.tar.gz: 19a28e7518edcce1ee883b65bb13d5f4ad97b3eb4820dd00a5ebdb4eeeb1ebf6
5
5
  SHA512:
6
- metadata.gz: 66844257f2a1b0cbeb59cbdfaa211ec87c176389a2e8058cf679d133b31f7f09d3fb21b98cea25b5856b5e43ed0572d3fb8872189464d0fbeedf7c0ce5d96cd4
7
- data.tar.gz: 1220dded69fae0946c2df3120f2c89db1262a38a481d461410dbac2b6dd76139805612fe3a1e470c2e5951684e401f98a38ef6ebce0b6040a7222e0129b88d3f
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
@@ -3,17 +3,6 @@ require "active_model"
3
3
 
4
4
  module Plutonium
5
5
  module Config
6
- # @return [Boolean] Are we developing plutonium? This is separate from Rails development.
7
- mattr_accessor :development
8
- @@development = ActiveModel::Type::Boolean.new.cast(ENV["PLUTONIUM_DEV"]).present?
9
-
10
- # @return [Boolean] Should hotreload be enabled? Enabled by default in Rails development.
11
- mattr_accessor :enable_hotreload
12
- @@enable_hotreload = defined?(Rails.env) && Rails.env.development?
13
-
14
- mattr_accessor :cache_discovery
15
- @@cache_discovery = defined?(Rails.env) && !Rails.env.development?
16
-
17
6
  mattr_accessor :stylesheet_tag
18
7
  @@stylesheet_tag = ->(view_context) {
19
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)