plutonium 0.15.4 → 0.15.6

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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/plutonium.css +1 -1
  3. data/app/assets/plutonium.ico +0 -0
  4. data/app/assets/plutonium.png +0 -0
  5. data/app/views/components/table_search_input/table_search_input_component.html.erb +3 -3
  6. data/app/views/resource/_resource_table.html.erb +0 -321
  7. data/docs/.vitepress/config.ts +61 -0
  8. data/docs/.vitepress/theme/custom.css +61 -0
  9. data/docs/.vitepress/theme/index.ts +4 -0
  10. data/docs/api-examples.md +49 -0
  11. data/docs/guide/getting-started/authorization.md +296 -0
  12. data/docs/guide/getting-started/core-concepts.md +432 -0
  13. data/docs/guide/getting-started/index.md +18 -0
  14. data/docs/guide/getting-started/installation.md +269 -0
  15. data/docs/guide/getting-started/resources.md +254 -0
  16. data/docs/guide/what-is-plutonium.md +211 -0
  17. data/docs/index.md +43 -0
  18. data/docs/markdown-examples.md +85 -0
  19. data/docs/public/android-chrome-192x192.png +0 -0
  20. data/docs/public/android-chrome-512x512.png +0 -0
  21. data/docs/public/apple-touch-icon.png +0 -0
  22. data/docs/public/favicon-16x16.png +0 -0
  23. data/docs/public/favicon-32x32.png +0 -0
  24. data/docs/public/favicon.ico +0 -0
  25. data/docs/public/plutonium.png +0 -0
  26. data/docs/public/site.webmanifest +1 -0
  27. data/docs/public/templates/plutonium.rb +21 -0
  28. data/lib/generators/pu/core/assets/assets_generator.rb +2 -3
  29. data/lib/generators/pu/core/assets/templates/tailwind.config.js +2 -2
  30. data/lib/generators/pu/core/install/install_generator.rb +9 -1
  31. data/lib/generators/pu/core/install/templates/config/initializers/plutonium.rb +0 -1
  32. data/lib/plutonium/core/controllers/authorizable.rb +1 -1
  33. data/lib/plutonium/definition/base.rb +8 -0
  34. data/lib/plutonium/definition/defineable_props.rb +1 -1
  35. data/lib/plutonium/definition/presentable.rb +71 -0
  36. data/lib/plutonium/interaction/README.md +1 -1
  37. data/lib/plutonium/interaction/base.rb +6 -6
  38. data/lib/plutonium/lib/deep_freezer.rb +31 -0
  39. data/lib/plutonium/query/adhoc_block.rb +19 -0
  40. data/lib/plutonium/query/base.rb +29 -0
  41. data/lib/plutonium/query/filter.rb +12 -0
  42. data/lib/plutonium/query/filters/text.rb +77 -0
  43. data/lib/plutonium/query/model_scope.rb +19 -0
  44. data/lib/plutonium/railtie.rb +0 -10
  45. data/lib/plutonium/resource/controller.rb +0 -3
  46. data/lib/plutonium/resource/controllers/crud_actions/index_action.rb +26 -0
  47. data/lib/plutonium/resource/controllers/crud_actions.rb +3 -6
  48. data/lib/plutonium/resource/controllers/defineable.rb +0 -2
  49. data/lib/plutonium/resource/controllers/queryable.rb +36 -20
  50. data/lib/plutonium/resource/policy.rb +5 -6
  51. data/lib/plutonium/resource/query_object.rb +61 -147
  52. data/lib/plutonium/resource/register.rb +3 -0
  53. data/lib/plutonium/{refinements/parameter_refinements.rb → support/parameters.rb} +5 -7
  54. data/lib/plutonium/ui/action_button.rb +34 -19
  55. data/lib/plutonium/ui/component/methods.rb +1 -1
  56. data/lib/plutonium/ui/display/resource.rb +19 -15
  57. data/lib/plutonium/ui/form/query.rb +171 -0
  58. data/lib/plutonium/ui/form/resource.rb +22 -17
  59. data/lib/plutonium/ui/table/components/scopes_bar.rb +1 -1
  60. data/lib/plutonium/ui/table/components/search_bar.rb +6 -139
  61. data/lib/plutonium/ui/table/resource.rb +10 -9
  62. data/lib/plutonium/version.rb +1 -1
  63. data/package-lock.json +5769 -1853
  64. data/package.json +11 -5
  65. data/src/js/core.js +0 -1
  66. data/tailwind.options.js +89 -11
  67. metadata +37 -13
  68. data/app/assets/plutonium-original.png +0 -0
  69. data/app/assets/plutonium-white.png +0 -0
  70. data/lib/plutonium/interaction/concerns/presentable.rb +0 -73
  71. data/public/plutonium-assets/fonts/bootstrap-icons.woff +0 -0
  72. data/public/plutonium-assets/fonts/bootstrap-icons.woff2 +0 -0
  73. /data/{templates → docs/public/templates}/base.rb +0 -0
@@ -0,0 +1,211 @@
1
+ # What is Plutonium?
2
+
3
+ Plutonium is a Rapid Application Development (RAD) toolkit that extends Rails with powerful conventions, patterns, and tools to accelerate application development while maintaining flexibility and maintainability.
4
+
5
+ It acts as a higher-level abstraction on top of Rails, providing ready-to-use solutions for common application needs while preserving Rails' elegance.
6
+
7
+ ## Core Architecture
8
+
9
+ ### Rails-Native Design
10
+
11
+ Plutonium integrates seamlessly with Rails, extending its conventions rather than replacing them:
12
+
13
+ ```ruby
14
+ # Plutonium controllers inherit from your ApplicationController
15
+ class ResourceController < ApplicationController
16
+ include Plutonium::Resource::Controller
17
+ end
18
+
19
+ # Plutonium controllers are Rails controllers
20
+ class ProductsController < ResourceController
21
+ # Enhanced with resource capabilities
22
+ def custom_action
23
+ # Regular Rails code works just fine
24
+ respond_to do |format|
25
+ format.html
26
+ format.json
27
+ end
28
+ end
29
+ end
30
+ ```
31
+
32
+ ### Resource-Oriented Architecture
33
+
34
+ Resources are the building blocks of Plutonium applications:
35
+
36
+ ```ruby
37
+ class ProductDefinition < ResourceDefinition
38
+ # Declarative field definitions
39
+ field :name, as: :string
40
+ field :description, as: :markdown
41
+ field :price_cents, as: :money
42
+
43
+ # Resource-level search
44
+ search do |scope, query|
45
+ scope.where("name LIKE ?", "%#{query}%")
46
+ end
47
+
48
+ # Business actions
49
+ action :publish, interaction: PublishProduct
50
+ action :archive, interaction: ArchiveProduct
51
+ end
52
+ ```
53
+
54
+ ### Modular by Design
55
+
56
+ Plutonium's packaging system helps organize code into focused, reusable modules:
57
+
58
+ ```ruby
59
+ # Generate different types of packages
60
+ rails generate pu:pkg:portal admin
61
+ rails generate pu:pkg:package inventory
62
+
63
+ # Packages are isolated and focused
64
+ module AdminPortal
65
+ class Engine < Rails::Engine
66
+ include Plutonium::Portal::Engine
67
+ end
68
+ end
69
+
70
+ AdminPortal::Engine.routes.draw do
71
+ register_resource ::Product
72
+ end
73
+ ```
74
+
75
+ ### Progressive Enhancement
76
+
77
+ Built on modern web technologies like Hotwire, delivering rich interactivity without sacrificing simplicity:
78
+
79
+ ```ruby
80
+ class PublishProduct < ResourceInteraction
81
+ attribute :schedule_for, :datetime
82
+ attribute :notify_users, :boolean
83
+
84
+ def execute
85
+ resource.publish!(schedule_for:)
86
+ notify_users! if notify_users
87
+
88
+ success(resource)
89
+ .with_message("Product scheduled for publishing")
90
+ .with_render_response(NotificationComponent.new)
91
+ end
92
+ end
93
+ ```
94
+
95
+ ## Use Cases
96
+
97
+ ### Business Applications
98
+
99
+ ::: details Enterprise Resource Planning (ERP)
100
+ ```ruby
101
+ class InvoiceDefinition < ResourceDefinition
102
+ # Rich field handling
103
+ field :line_items, as: :nested, limit: 20
104
+ field :attachments, as: :document, multiple: true
105
+
106
+ # Business actions
107
+ action :submit_for_approval, interaction: SubmitForApproval
108
+ action :approve, interaction: ApproveInvoice
109
+ action :reject, interaction: RejectInvoice
110
+
111
+ # Workflow states
112
+ scope :draft
113
+ scope :pending_approval
114
+ scope :approved
115
+ end
116
+ ```
117
+ :::
118
+
119
+ ::: details Multi-tenant SaaS
120
+ ```ruby
121
+ module CustomerPortal
122
+ class Engine < Rails::Engine
123
+ include Plutonium::Package::Engine
124
+ # Automatic tenant isolation
125
+ scope_to_entity Organization
126
+ end
127
+ end
128
+ ```
129
+ :::
130
+
131
+ ### Administrative Systems
132
+
133
+ ::: details Back-office Applications
134
+ ```ruby
135
+ class OrderDefinition < ResourceDefinition
136
+ # Advanced filtering
137
+ filter :status, with: SelectFilter, choices: Order.statuses
138
+ filter :created_at, with: DateRangeFilter
139
+
140
+ # Bulk actions
141
+ action :process_batch, interaction: ProcessPendingOrders
142
+ action :export_to_csv, interaction: ExportOrders
143
+
144
+ # Complex displays
145
+ display :summary do |field|
146
+ OrderSummaryComponent.new(field)
147
+ end
148
+ end
149
+ ```
150
+ :::
151
+
152
+ ::: details Content Management
153
+ ```ruby
154
+ class ArticleDefinition < ResourceDefinition
155
+ field :content, as: :markdown
156
+ field :featured_image, as: :image
157
+
158
+ # Publishing workflow
159
+ action :publish, interaction: PublishArticle
160
+ action :schedule, interaction: ScheduleArticle
161
+
162
+ # Content organization
163
+ scope :draft
164
+ scope :published
165
+ scope :scheduled
166
+ end
167
+ ```
168
+ :::
169
+
170
+ ## Key Benefits
171
+
172
+ ### Accelerated Development
173
+ - Pre-built components for common functionality
174
+ - Smart generators for boilerplate code
175
+ - Convention-based resource handling
176
+ - Integrated authentication and authorization
177
+
178
+ ### Maintainable Architecture
179
+ - Clear separation of concerns through packages
180
+ - Consistent patterns across the application
181
+ - Deep Rails integration
182
+ - Progressive enhancement
183
+
184
+ ### Enterprise Ready
185
+ - Flexible and robust access control
186
+ - Multi-tenancy support
187
+ - Extensible component system
188
+ - Mobile-friendly by default
189
+
190
+ ## Best For
191
+
192
+ ::: tip IDEAL USE CASES
193
+ - Complex business applications
194
+ - Multi-tenant SaaS platforms
195
+ - Administrative systems
196
+ - Content management systems
197
+ - Resource management systems
198
+ :::
199
+
200
+ ::: warning MIGHT NOT BE THE BEST FIT
201
+ - Simple blogs or brochure sites
202
+ - Basic CRUD applications
203
+ - Pure API-only services
204
+ :::
205
+
206
+ ## Prerequisites
207
+
208
+ - Ruby 3.2.2 or higher
209
+ - Rails 7.1 or higher
210
+ - Node.js and Yarn
211
+ - Basic understanding of Ruby on Rails
data/docs/index.md ADDED
@@ -0,0 +1,43 @@
1
+ ---
2
+ # https://vitepress.dev/reference/default-theme-home-page
3
+ layout: home
4
+
5
+ hero:
6
+ name: Plutonium RADKit
7
+ tagline: The Ultimate Rapid Application Development Toolkit (RADKit) for Rails
8
+ image:
9
+ src: /plutonium.png
10
+ alt: Plutonium
11
+ actions:
12
+ - theme: brand
13
+ text: Get started
14
+ link: /guide/getting-started/
15
+ - theme: alt
16
+ text: Learn more
17
+ link: /guide/what-is-plutonium
18
+
19
+ features:
20
+ - title: Pro-Grade CRUD UI
21
+ details: Stunning, modern interface with rich field types to build powerful admin panels in minutes
22
+
23
+ - title: Intelligent Fields
24
+ details: Zero-config field detection that matches your Rails models out of the box
25
+
26
+ - title: Seamless Authentication
27
+ details: Use your existing auth or our Rodauth integration - get setup in seconds
28
+
29
+ - title: Enterprise Authorization
30
+ details: Industrial-strength access control powered by Action Policy's proven framework
31
+
32
+ - title: Built-in Multitenancy
33
+ details: Row-level multitenancy that just works - perfect for SaaS and enterprise apps
34
+
35
+ - title: Advanced Nested Resources
36
+ details: Complex resource relationships made simple with zero extra configuration
37
+
38
+ - title: Custom Actions
39
+ details: Extend your admin panel with incredibly simple custom actions and workflows
40
+
41
+ - title: Complete Builder Control
42
+ details: Total flexibility to customize every aspect of your admin UI with elegant builder APIs
43
+ ---
@@ -0,0 +1,85 @@
1
+ # Markdown Extension Examples
2
+
3
+ This page demonstrates some of the built-in markdown extensions provided by VitePress.
4
+
5
+ ## Syntax Highlighting
6
+
7
+ VitePress provides Syntax Highlighting powered by [Shiki](https://github.com/shikijs/shiki), with additional features like line-highlighting:
8
+
9
+ **Input**
10
+
11
+ ````md
12
+ ```js{4}
13
+ export default {
14
+ data () {
15
+ return {
16
+ msg: 'Highlighted!'
17
+ }
18
+ }
19
+ }
20
+ ```
21
+ ````
22
+
23
+ **Output**
24
+
25
+ ```js{4}
26
+ export default {
27
+ data () {
28
+ return {
29
+ msg: 'Highlighted!'
30
+ }
31
+ }
32
+ }
33
+ ```
34
+
35
+ ## Custom Containers
36
+
37
+ **Input**
38
+
39
+ ```md
40
+ ::: info
41
+ This is an info box.
42
+ :::
43
+
44
+ ::: tip
45
+ This is a tip.
46
+ :::
47
+
48
+ ::: warning
49
+ This is a warning.
50
+ :::
51
+
52
+ ::: danger
53
+ This is a dangerous warning.
54
+ :::
55
+
56
+ ::: details
57
+ This is a details block.
58
+ :::
59
+ ```
60
+
61
+ **Output**
62
+
63
+ ::: info
64
+ This is an info box.
65
+ :::
66
+
67
+ ::: tip
68
+ This is a tip.
69
+ :::
70
+
71
+ ::: warning
72
+ This is a warning.
73
+ :::
74
+
75
+ ::: danger
76
+ This is a dangerous warning.
77
+ :::
78
+
79
+ ::: details
80
+ This is a details block.
81
+ :::
82
+
83
+ ## More
84
+
85
+ Check out the documentation for the [full list of markdown extensions](https://vitepress.dev/guide/markdown).
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1 @@
1
+ {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
@@ -0,0 +1,21 @@
1
+ after_bundle do
2
+ # We just installed Rails, let's create a commit
3
+ git add: "."
4
+ git commit: %( -m 'initial commit' )
5
+
6
+ # Run the base install
7
+ rails_command "app:template LOCATION=https://radioactive-labs.github.io/plutonium-core/templates/base.rb"
8
+
9
+ # Add development tools
10
+ generate "pu:gem:dotenv"
11
+ git add: "."
12
+ git commit: %( -m 'add dotenv' )
13
+
14
+ generate "pu:gem:annotate"
15
+ git add: "."
16
+ git commit: %( -m 'add annotate' )
17
+
18
+ generate "pu:core:assets"
19
+ git add: "."
20
+ git commit: %( -m 'integrate assets' )
21
+ end
@@ -22,12 +22,11 @@ module Pu
22
22
  private
23
23
 
24
24
  def copy_tailwind_config
25
- copy_file "tailwind.config.js"
25
+ copy_file "tailwind.config.js", force: true
26
26
  end
27
27
 
28
28
  def install_dependencies
29
- `yarn add @radioactive-labs/plutonium`
30
- `yarn add flowbite @tailwindcss/forms`
29
+ run "npm install @radioactive-labs/plutonium flowbite @tailwindcss/forms"
31
30
  end
32
31
 
33
32
  def configure_application
@@ -9,12 +9,12 @@ module.exports = {
9
9
  ].concat(plutoniumTailwindConfig.plugins.map((plugin) => require(plugin))),
10
10
  theme: plutoniumTailwindConfig.theme,
11
11
  content: [
12
+ `${__dirname}/app/**/*.rb`,
12
13
  `${__dirname}/app/views/**/*.html.erb`,
13
14
  `${__dirname}/app/helpers/**/*.rb`,
14
15
  `${__dirname}/app/assets/stylesheets/**/*.css`,
15
16
  `${__dirname}/app/javascript/**/*.js`,
16
- `${__dirname}/app/plutonium/**/*.rb`,
17
- `${__dirname}/packages/**/app/plutonium/**/*.rb`,
17
+ `${__dirname}/packages/**/app/**/*.rb`,
18
18
  `${__dirname}/packages/**/app/views/**/*.html.erb`,
19
19
  ].concat(plutoniumTailwindConfig.content),
20
20
  }
@@ -15,6 +15,7 @@ module Pu
15
15
  setup_packages
16
16
  setup_app
17
17
  eject_views
18
+ setup_active_record
18
19
  rescue => e
19
20
  exception "#{self.class} failed:", e
20
21
  end
@@ -25,7 +26,6 @@ module Pu
25
26
  copy_file "config/packages.rb"
26
27
  create_file "packages/.keep"
27
28
  insert_into_file "config/application.rb", "\nrequire_relative \"packages\"\n", after: /Bundler\.require.*\n/
28
- # insert_into_file "config/application.rb", indent("Plutonium.configure_rails config\n\n", 4), after: /.*< Rails::Application\n/
29
29
  end
30
30
 
31
31
  def setup_app
@@ -38,6 +38,14 @@ module Pu
38
38
  force: options[:force],
39
39
  skip: options[:skip]
40
40
  end
41
+
42
+ def setup_active_record
43
+ inject_into_class(
44
+ "app/models/application_record.rb",
45
+ "ApplicationRecord",
46
+ " include Plutonium::Resource::Record\n"
47
+ )
48
+ end
41
49
  end
42
50
  end
43
51
  end
@@ -3,6 +3,5 @@
3
3
  Plutonium.configure do |config|
4
4
  config.load_defaults 1.0
5
5
 
6
- # config.assets.logo = "logo.png"
7
6
  # Configure plutonium above.
8
7
  end
@@ -9,7 +9,7 @@ module Plutonium
9
9
 
10
10
  included do
11
11
  authorize :user, through: :current_user
12
- authorize :scope, through: :entity_scope_for_authorize
12
+ authorize :entity_scope, through: :entity_scope_for_authorize
13
13
 
14
14
  helper_method :policy_for, :authorized_resource_scope
15
15
  end
@@ -46,6 +46,10 @@ module Plutonium
46
46
 
47
47
  class Display < Plutonium::UI::Display::Resource; end
48
48
 
49
+ class QueryForm < Plutonium::UI::Form::Query; end
50
+
51
+ class TextFilter < Plutonium::Query::Filters::Text; end
52
+
49
53
  # fields
50
54
  defineable_props :field, :input, :display, :column
51
55
 
@@ -94,6 +98,10 @@ module Plutonium
94
98
  def detail_class
95
99
  self.class::Display
96
100
  end
101
+
102
+ def query_form
103
+ self.class::QueryForm
104
+ end
97
105
  end
98
106
  end
99
107
  end
@@ -67,7 +67,7 @@ module Plutonium
67
67
  end
68
68
  # merged[name].compact!
69
69
  end
70
- merged
70
+ Plutonium::Lib::DeepFreezer.freeze(merged)
71
71
  end
72
72
  end
73
73
 
@@ -0,0 +1,71 @@
1
+ module Plutonium
2
+ module Definition
3
+ # Provides presentation-related functionality for interactions.
4
+ #
5
+ # This module allows interactions to define metadata such as labels, icons,
6
+ # and descriptions, which can be used for UI generation or documentation.
7
+ #
8
+ # @example
9
+ # class MyInteraction < Plutonium::Interaction::Base
10
+ # include Plutonium::Definition::Presentable
11
+ #
12
+ # presents label: "My Interaction",
13
+ # icon: "star",
14
+ # description: "Does something awesome"
15
+ #
16
+ # # ... rest of the interaction
17
+ # end
18
+ module Presentable
19
+ extend ActiveSupport::Concern
20
+
21
+ included do
22
+ class_attribute :presentation_metadata, default: {}
23
+ end
24
+
25
+ class_methods do
26
+ # Defines presentation metadata for the interaction.
27
+ #
28
+ # @param options [Hash] The presentation options.
29
+ # @option options [String] :label The label for the interaction.
30
+ # @option options [String] :icon The icon for the interaction.
31
+ # @option options [String] :description The description of the interaction.
32
+ def presents(**options)
33
+ self.presentation_metadata = options
34
+ end
35
+
36
+ # Returns the label for the interaction.
37
+ #
38
+ # @return [String] The label defined in the presentation metadata or a default generated from the class name.
39
+ def label
40
+ presentation_metadata[:label] || name.demodulize.titleize
41
+ end
42
+
43
+ # Returns the icon for the interaction.
44
+ #
45
+ # @return [String, nil] The icon defined in the presentation metadata.
46
+ def icon
47
+ presentation_metadata[:icon]
48
+ end
49
+
50
+ # Returns the description for the interaction.
51
+ #
52
+ # @return [String, nil] The description defined in the presentation metadata.
53
+ def description
54
+ presentation_metadata[:description]
55
+ end
56
+ end
57
+
58
+ def label
59
+ self.class.label
60
+ end
61
+
62
+ def icon
63
+ self.class.icon
64
+ end
65
+
66
+ def description
67
+ self.class.description
68
+ end
69
+ end
70
+ end
71
+ end
@@ -252,7 +252,7 @@ The `Presentable` concern allows you to add metadata to your interactions, which
252
252
 
253
253
  ```ruby
254
254
  class MyInteraction < Plutonium::Interaction::Base
255
- include Plutonium::Interaction::Concerns::Presentable
255
+ include Plutonium::Definition::Presentable
256
256
 
257
257
  presents label: "My Interaction",
258
258
  icon: Phlex::TablerIcons::Activate,
@@ -22,10 +22,10 @@ module Plutonium
22
22
  class Base
23
23
  include ActiveModel::Model
24
24
  include ActiveModel::Attributes
25
- include Concerns::Presentable
26
25
  include Plutonium::Definition::DefineableProps
27
26
  include Plutonium::Definition::ConfigAttr
28
- # include Concerns::WorkflowDSL
27
+ include Plutonium::Definition::Presentable
28
+ # include Plutonium::Interaction::Concerns::WorkflowDSL
29
29
 
30
30
  class Form < Plutonium::UI::Form::Interaction; end
31
31
 
@@ -44,6 +44,10 @@ module Plutonium
44
44
  self::Form.new(instance || new)
45
45
  end
46
46
 
47
+ def build_form
48
+ self.class.build_form(self)
49
+ end
50
+
47
51
  # Executes the interaction.
48
52
  #
49
53
  # @return [Plutonium::Interaction::Outcome] The result of the interaction.
@@ -60,10 +64,6 @@ module Plutonium
60
64
  end
61
65
  end
62
66
 
63
- def build_form
64
- self.class.build_form(self)
65
- end
66
-
67
67
  private
68
68
 
69
69
  # Implement the main logic of the interaction.
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Plutonium
4
+ module Lib
5
+ class DeepFreezer
6
+ def self.freeze(object)
7
+ # Recursive calling #deep_freeze for enumerable objects.
8
+ if object.respond_to? :each
9
+ if object.instance_of?(Hash)
10
+ object.each { |key, val| freeze(val) }
11
+ else
12
+ object.each { |val| freeze(val) }
13
+ end
14
+ end
15
+
16
+ # # Freezing of all instance variable values.
17
+ # object.instance_variables.each do |var|
18
+ # frozen_val = instance_variable_get(var)
19
+ # frozen_val.deep_freeze
20
+ # instance_variable_set(var, frozen_val)
21
+ # end
22
+
23
+ if object.frozen?
24
+ object
25
+ else
26
+ object.freeze
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,19 @@
1
+ module Plutonium
2
+ module Query
3
+ class AdhocBlock < Base
4
+ attr_reader :body
5
+
6
+ # Initializes a AdhocBlock with a given block of code.
7
+ #
8
+ # @param body [Proc] The block of code for the query.
9
+ def initialize(body)
10
+ super()
11
+ @body = body
12
+ end
13
+
14
+ def apply(scope, **)
15
+ body.call(scope, **)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,29 @@
1
+ module Plutonium
2
+ module Query
3
+ class Base
4
+ include Plutonium::Definition::DefineableProps
5
+ include Plutonium::Definition::ConfigAttr
6
+ include Plutonium::Definition::Presentable
7
+
8
+ defineable_props :field, :input
9
+
10
+ # Applies a parameterized query to modify the given scope.
11
+ #
12
+ # @param scope [Object] The initial scope that will be filtered, sorted, or otherwise modified
13
+ # by applying this query. This is typically an ActiveRecord::Relation or similar query object.
14
+ #
15
+ # @param params [Hash] Optional parameters that configure how the query is applied.
16
+ # The specific parameters accepted depend on the implementing class.
17
+ #
18
+ # @return [Object] The modified scope with this query's conditions applied. Returns the same
19
+ # type as the input scope parameter.
20
+ #
21
+ # @example Basic usage
22
+ # query.apply(User.all, status: 'active')
23
+ #
24
+ def apply(scope, **params)
25
+ raise NotImplementedError, "#{self.class}#apply(scope, **params)"
26
+ end
27
+ end
28
+ end
29
+ end