hanami 2.1.0 → 2.2.0.beta1

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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +30 -6
  3. data/FEATURES.md +1 -1
  4. data/README.md +7 -7
  5. data/hanami.gemspec +6 -6
  6. data/lib/hanami/app.rb +6 -2
  7. data/lib/hanami/config/actions.rb +1 -1
  8. data/lib/hanami/config/assets.rb +1 -1
  9. data/lib/hanami/config/db.rb +33 -0
  10. data/lib/hanami/config/logger.rb +2 -2
  11. data/lib/hanami/config.rb +37 -10
  12. data/lib/hanami/extensions/db/repo.rb +103 -0
  13. data/lib/hanami/extensions/view/context.rb +1 -1
  14. data/lib/hanami/extensions/view/part.rb +1 -1
  15. data/lib/hanami/extensions/view/slice_configured_helpers.rb +1 -1
  16. data/lib/hanami/extensions.rb +4 -0
  17. data/lib/hanami/helpers/assets_helper.rb +5 -5
  18. data/lib/hanami/helpers/form_helper/form_builder.rb +4 -6
  19. data/lib/hanami/middleware/public_errors_app.rb +2 -2
  20. data/lib/hanami/provider_registrar.rb +26 -0
  21. data/lib/hanami/providers/assets.rb +2 -20
  22. data/lib/hanami/providers/db/adapter.rb +68 -0
  23. data/lib/hanami/providers/db/adapters.rb +44 -0
  24. data/lib/hanami/providers/db/config.rb +66 -0
  25. data/lib/hanami/providers/db/sql_adapter.rb +80 -0
  26. data/lib/hanami/providers/db.rb +203 -0
  27. data/lib/hanami/providers/db_logging.rb +22 -0
  28. data/lib/hanami/providers/rack.rb +3 -3
  29. data/lib/hanami/providers/relations.rb +31 -0
  30. data/lib/hanami/providers/routes.rb +1 -13
  31. data/lib/hanami/rake_tasks.rb +9 -8
  32. data/lib/hanami/settings.rb +3 -3
  33. data/lib/hanami/slice.rb +90 -10
  34. data/lib/hanami/version.rb +1 -1
  35. data/lib/hanami/web/rack_logger.rb +3 -3
  36. data/lib/hanami.rb +3 -0
  37. data/spec/integration/container/provider_environment_spec.rb +52 -0
  38. data/spec/integration/db/auto_registration_spec.rb +39 -0
  39. data/spec/integration/db/db_inflector_spec.rb +57 -0
  40. data/spec/integration/db/db_slices_spec.rb +327 -0
  41. data/spec/integration/db/db_spec.rb +220 -0
  42. data/spec/integration/db/logging_spec.rb +238 -0
  43. data/spec/integration/db/provider_config_spec.rb +88 -0
  44. data/spec/integration/db/provider_spec.rb +35 -0
  45. data/spec/integration/db/repo_spec.rb +215 -0
  46. data/spec/integration/db/slices_importing_from_parent.rb +130 -0
  47. data/spec/integration/slices/slice_configuration_spec.rb +4 -4
  48. data/spec/integration/view/config/template_spec.rb +1 -1
  49. data/spec/integration/view/context/request_spec.rb +1 -1
  50. data/spec/support/app_integration.rb +3 -0
  51. data/spec/unit/hanami/config/db_spec.rb +38 -0
  52. data/spec/unit/hanami/config/router_spec.rb +1 -1
  53. data/spec/unit/hanami/helpers/form_helper_spec.rb +33 -2
  54. data/spec/unit/hanami/providers/db/config/default_config_spec.rb +107 -0
  55. data/spec/unit/hanami/providers/db/config_spec.rb +206 -0
  56. data/spec/unit/hanami/slice_spec.rb +33 -1
  57. data/spec/unit/hanami/version_spec.rb +1 -1
  58. metadata +62 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3f9161e98415778e746f9140d2ee9e23b7d8388eca678e7ddeb696c2bb8cdfee
4
- data.tar.gz: 7deffed8c1081258db7182306bf95bf484fa9e08dbd37193ca36659a06d45040
3
+ metadata.gz: ada7b19a9d5205199e825e57d41758bbc67c350f3d565b01cd4720b9ed8f3ad4
4
+ data.tar.gz: 2af8c539547dcbc78dde70db5e31fc72bafa9578dcf391178ec342b618ea6467
5
5
  SHA512:
6
- metadata.gz: 1acff67204a42604558bce5455d36454cc8c176a741906750a536ae72f3048a006c798db7192918d64f06cc4b1fce7ce5c4f46726d0a27b309c82a1263b3d72b
7
- data.tar.gz: aadb05898198c750f485f5a78f6d35f1e82c6b95ee052f749cfb0241b11f6706c367f7cfc01c31205664ff508853a3415884b7b729097e689d2f9f72c6bdf0fc
6
+ metadata.gz: ed3735c73b897db477ba35cd3d2f0aee79c98940eb4cba651590e5bedf74f34d3969a8dc8200fcae2cfda1a1f7345e873b9bcd075a3f3a627d81eef0ac36ac94
7
+ data.tar.gz: 65aebf467d397b29148dda81262550c528469adbd75759615415e89293cefd0cdb1444bd7fc1513c07d46da290ac2092f31752c4d3adeb856f709c04d540497f
data/CHANGELOG.md CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  The web, with simplicity.
4
4
 
5
+ ## v2.2.0.beta1 - 2024-07-16
6
+
7
+ ### Added
8
+
9
+ - [Tim Riley, Adam Lassek] Introduce database layer
10
+ - [Adam Lassek] Add `Hanami::Slice.app?`, returning false for slices and true for the app (#1399)
11
+ - [Tim Riley] Add `Slice#registered?`, an additional method delegating to the internal container. Returns true only if a component is already registered for the given, without triggering lazy loading (#1382)
12
+
13
+ ### Changed
14
+
15
+ - [Tim Riley] `target` inside providers is now the slice itself, instead of the slice's internal container (#1382)
16
+ - Drop support for Ruby 3.0
17
+
18
+ ### Fixed
19
+
20
+ - [Damian C. Rossney] Allow form `label` helper to receive a symbol (#1423)
21
+ - [Damian C. Rossney] Fix invalid input names generated when using form `fields_for_collection` helper (#1421)
22
+ - [Tim Riley] Fix dry-logger compatibility check for versions of dry-logger >= 1.0.4 (#1384)
23
+
24
+ ## v2.1.1 - 2024-05-12
25
+
26
+ ### Fixed
27
+
28
+ - [Tim Riley] Ensure Rack logging continues to work when upgrading to dry-logger 1.0.4 (#1384)
29
+
5
30
  ## v2.1.0 - 2024-02-27
6
31
 
7
32
  ### Changed
@@ -14,7 +39,7 @@ The web, with simplicity.
14
39
  ### Changed
15
40
 
16
41
  - [Tim Riley] Return `nil` when setting content via `#content_for` on the app's view context. This
17
- allows it to be used with tempalte output tags (such as ERB's `<%=`) that capture a block for the
42
+ allows it to be used with template output tags (such as ERB's `<%=`) that capture a block for the
18
43
  given content. (#1369)
19
44
 
20
45
  ### Fixed
@@ -52,7 +77,6 @@ The web, with simplicity.
52
77
  - Keep `video_tag` (remove `video` alias)
53
78
  - Keep `audio_tag` (remove `audio` alias)
54
79
 
55
-
56
80
  ## v2.1.0.beta2.1 - 2023-10-04
57
81
 
58
82
  ### Added
@@ -151,7 +175,7 @@ The web, with simplicity.
151
175
  ### Fixed
152
176
 
153
177
  - [Luca Guidi] Ensure to properly mount Rack middleware in routing scope and slice
154
- - [Tim Riley] Simplify and clarify usage of `Hanami::Config#enviroment`
178
+ - [Tim Riley] Simplify and clarify usage of `Hanami::Config#environment`
155
179
  - [Tim Riley] Improve error message for missing action class
156
180
  - [Tim Riley] Expect nested slices to use parent’s namespace
157
181
 
@@ -811,7 +835,7 @@ The web, with simplicity.
811
835
  - [Luca Guidi] Main configuration is available at `config/application.rb` instead of `config/enviroment.rb`
812
836
  - [Luca Guidi] Removed `Hanami.configure` in favor of main application configuration (e.g. `Bookshelf::Application.config`)
813
837
  - [Luca Guidi] Removed DSL syntax for main configuration (from `cookies max_age: 600` to `config.cookies = { max_age: 600 }`)
814
- - [Luca Guidi] Per enviroment settings must be wrapped in a block (e.g. `config.enviroment(:production) { |c| c.logger = {} }`)
838
+ - [Luca Guidi] Per environment settings must be wrapped in a block (e.g. `config.environment(:production) { |c| c.logger = {} }`)
815
839
  - [Luca Guidi] Concrete applications are no longer supported (e.g. `Web::Application` in `apps/web/application.rb`)
816
840
  - [Luca Guidi] Main routes must be configured at `config/routes.rb`:
817
841
 
@@ -1127,7 +1151,7 @@ end
1127
1151
  - [Mahesh] Fix destroy action for application architecture
1128
1152
  - [Karim Tarek & akhramov] Reference rendering errors in Rack env's `rack.exception` variable. This enables compatibility with exception reporting SaaS.
1129
1153
  - [Luca Guidi] Detect assets dependencies changes in development (Sass/SCSS)
1130
- - [Luca Guidi & Lucas Amorim] Make model generator not dependendent on the current directory name, but to the project name stored in `.hanamirc`
1154
+ - [Luca Guidi & Lucas Amorim] Make model generator not dependent on the current directory name, but to the project name stored in `.hanamirc`
1131
1155
 
1132
1156
  ### Changed
1133
1157
 
@@ -1382,7 +1406,7 @@ end
1382
1406
  - [Piotr Kurek] Allow to yield multiple configurations per application, according to the current environment
1383
1407
  - [David Celis] Allow to configure Rack middleware stack (`middleware` configuration)
1384
1408
  - [David Celis] Introduced `lotus console` command. It runs the REPL configured in `Gemfile` (eg. pry or ripl). Defaults to IRb.
1385
- - [Luca Guidi] Introduced `Lotus::Environment` which holds the informations about the current environment, and CLI arguments
1409
+ - [Luca Guidi] Introduced `Lotus::Environment` which holds the information about the current environment, and CLI arguments
1386
1410
  - [Luca Guidi] Introduced `Lotus::Application.load!` to load and configure an application without requiring user defined code (controllers, views, etc.)
1387
1411
  - [Leonard Garvey] Introduced `lotus server` command. It runs the application with the Rack server declared in `Gemfile` (eg. puma, thin, unicorn). It defaults to `WEBRick`.
1388
1412
  - [Luca Guidi] Official support for MRI 2.1 and 2.2
data/FEATURES.md CHANGED
@@ -122,7 +122,7 @@
122
122
 
123
123
  ### v0.6.0 - 2016-01-12
124
124
 
125
- - Assets preprocessors support (eg. Sass, ES6, Opal, Less, CoffeScript..)
125
+ - Assets preprocessors support (eg. Sass, ES6, Opal, Less, CoffeeScript..)
126
126
  - Assets compressors (eg. YUI, UglifyJS2, Google Closure Compiler, Sass..)
127
127
  - Assets helpers:
128
128
  - `javascript`
data/README.md CHANGED
@@ -4,7 +4,7 @@ The web, with simplicity.
4
4
 
5
5
  ## Version
6
6
 
7
- **This branch contains the code for `hanami` 2.0.x.**
7
+ **This branch contains the code for `hanami`: 2.2**
8
8
 
9
9
  ## Frameworks
10
10
 
@@ -14,9 +14,8 @@ This repository is for the full-stack framework, which provides the glue that ti
14
14
 
15
15
  * [**Hanami::Router**](https://github.com/hanami/router) - Rack compatible HTTP router for Ruby
16
16
  * [**Hanami::Controller**](https://github.com/hanami/controller) - Full featured, fast and testable actions for Rack
17
+ * [**Hanami::Validations**](https://github.com/hanami/validations) - Parameter validations & coercion for actions
17
18
  * [**Hanami::View**](https://github.com/hanami/view) - Presentation with a separation between views and templates
18
- * [**Hanami::Helpers**](https://github.com/hanami/helpers) - View helpers for Ruby applications
19
- * [**Hanami::Mailer**](https://github.com/hanami/mailer) - Mail for Ruby applications
20
19
  * [**Hanami::Assets**](https://github.com/hanami/assets) - Assets management for Ruby
21
20
 
22
21
  These components are designed to be used independently or together in a Hanami application.
@@ -24,12 +23,13 @@ These components are designed to be used independently or together in a Hanami a
24
23
  ## Status
25
24
 
26
25
  [![Gem Version](https://badge.fury.io/rb/hanami.svg)](https://badge.fury.io/rb/hanami)
27
- [![CI](https://github.com/hanami/hanami/workflows/ci/badge.svg?branch=main)](https://github.com/hanami/hanami/actions?query=workflow%3Aci+branch%3Amain)
26
+ [![CI](https://github.com/hanami/hanami/actions/workflows/ci.yml/badge.svg)](https://github.com/hanami/hanami/actions?query=workflow%3Aci+branch%3Amain)
27
+ [![Test Coverage](https://codecov.io/gh/hanami/hanami/branch/main/graph/badge.svg)](https://codecov.io/gh/hanami/hanami)
28
28
  [![Depfu](https://badges.depfu.com/badges/ba000e0f69e6ef1c44cd3038caaa1841/overview.svg)](https://depfu.com/github/hanami/hanami?project=Bundler)
29
29
 
30
30
  ## Installation
31
31
 
32
- __Hanami__ supports Ruby (MRI) 3.0+
32
+ __Hanami__ supports Ruby (MRI) 3.1+.
33
33
 
34
34
  ```shell
35
35
  gem install hanami
@@ -110,7 +110,7 @@ $ bundle exec rspec path/to/spec.rb
110
110
 
111
111
  ### Development Requirements
112
112
 
113
- * Ruby >= 3.0
113
+ * Ruby >= 3.1
114
114
  * Bundler
115
115
  * Node.js (MacOS)
116
116
 
@@ -120,4 +120,4 @@ __Hanami__ uses [Semantic Versioning 2.0.0](http://semver.org)
120
120
 
121
121
  ## Copyright
122
122
 
123
- Copyright © 2014 Hanami Team – Released under MIT License.
123
+ Copyright © 2014–2024 Hanami Team – Released under MIT License.
data/hanami.gemspec CHANGED
@@ -27,19 +27,19 @@ Gem::Specification.new do |spec|
27
27
  spec.test_files = Dir["spec/**/*"]
28
28
  spec.require_paths = ["lib"]
29
29
  spec.metadata["rubygems_mfa_required"] = "true"
30
- spec.required_ruby_version = ">= 3.0"
30
+ spec.required_ruby_version = ">= 3.1"
31
31
 
32
32
  spec.metadata["allowed_push_host"] = "https://rubygems.org"
33
33
 
34
34
  spec.add_dependency "bundler", ">= 1.16", "< 3"
35
- spec.add_dependency "dry-configurable", "~> 1.0", "< 2"
35
+ spec.add_dependency "dry-configurable", "~> 1.0", ">= 1.2.0", "< 2"
36
36
  spec.add_dependency "dry-core", "~> 1.0", "< 2"
37
- spec.add_dependency "dry-inflector", "~> 1.0", "< 2"
37
+ spec.add_dependency "dry-inflector", "~> 1.0", ">= 1.1.0", "< 2"
38
38
  spec.add_dependency "dry-monitor", "~> 1.0", ">= 1.0.1", "< 2"
39
- spec.add_dependency "dry-system", "~> 1.0", "< 2"
39
+ spec.add_dependency "dry-system", "= 1.1.0.beta1"
40
40
  spec.add_dependency "dry-logger", "~> 1.0", "< 2"
41
- spec.add_dependency "hanami-cli", "~> 2.1"
42
- spec.add_dependency "hanami-utils", "~> 2.1"
41
+ spec.add_dependency "hanami-cli", "= 2.2.0.beta1"
42
+ spec.add_dependency "hanami-utils", "~> 2.2.beta"
43
43
  spec.add_dependency "zeitwerk", "~> 2.6"
44
44
 
45
45
  spec.add_development_dependency "rspec", "~> 3.8"
data/lib/hanami/app.rb CHANGED
@@ -129,7 +129,7 @@ module Hanami
129
129
  end
130
130
  end
131
131
 
132
- # When auto-registering components in app/, ignore files in `app/lib/` (these will be
132
+ # When auto-registering components in `app/`, ignore files in `app/lib/` (these will be
133
133
  # auto-registered as above), as well as the configured no_auto_register_paths
134
134
  no_auto_register_paths = ([LIB_DIR] + config.no_auto_register_paths)
135
135
  .map { |path|
@@ -152,7 +152,7 @@ module Hanami
152
152
  register_provider(:inflector, source: Hanami::Providers::Inflector)
153
153
 
154
154
  # Allow logger to be replaced by users with a manual provider, for advanced cases
155
- unless container.providers.find_and_load_provider(:logger)
155
+ unless container.providers[:logger]
156
156
  require_relative "providers/logger"
157
157
  register_provider(:logger, source: Hanami::Providers::Logger)
158
158
  end
@@ -161,6 +161,10 @@ module Hanami
161
161
  require_relative "providers/rack"
162
162
  register_provider(:rack, source: Hanami::Providers::Rack, namespace: true)
163
163
  end
164
+
165
+ if Hanami.bundled?("hanami-db")
166
+ register_provider(:db_logging, source: Hanami::Providers::DBLogging)
167
+ end
164
168
  end
165
169
 
166
170
  def prepare_autoloader
@@ -159,7 +159,7 @@ module Hanami
159
159
  end
160
160
  end
161
161
 
162
- def respond_to_missing?(name, _incude_all = false)
162
+ def respond_to_missing?(name, _include_all = false)
163
163
  config.respond_to?(name) || base_config.respond_to?(name) || super
164
164
  end
165
165
  end
@@ -76,7 +76,7 @@ module Hanami
76
76
  end
77
77
  end
78
78
 
79
- def respond_to_missing?(name, _incude_all = false)
79
+ def respond_to_missing?(name, _include_all = false)
80
80
  config.respond_to?(name) || base_config.respond_to?(name) || super
81
81
  end
82
82
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/configurable"
4
+
5
+ module Hanami
6
+ class Config
7
+ # Hanami DB config
8
+ #
9
+ # @since 2.2.0
10
+ # @api public
11
+ class DB
12
+ include Dry::Configurable
13
+
14
+ setting :configure_from_parent, default: true
15
+
16
+ setting :import_from_parent, default: false
17
+
18
+ private
19
+
20
+ def method_missing(name, *args, &block)
21
+ if config.respond_to?(name)
22
+ config.public_send(name, *args, &block)
23
+ else
24
+ super
25
+ end
26
+ end
27
+
28
+ def respond_to_missing?(name, _include_all = false)
29
+ config.respond_to?(name) || super
30
+ end
31
+ end
32
+ end
33
+ end
@@ -25,7 +25,7 @@ module Hanami
25
25
  attr_reader :env
26
26
 
27
27
  # @!attribute [rw] level
28
- # Sets or returns the logger level.
28
+ # Sets or returns the logger's level.
29
29
  #
30
30
  # Defaults to `:info` for the production environment and `:debug` for all others.
31
31
  #
@@ -191,7 +191,7 @@ module Hanami
191
191
  end
192
192
 
193
193
  # @api private
194
- def respond_to_missing?(name, _incude_all = false)
194
+ def respond_to_missing?(name, _include_all = false)
195
195
  config.respond_to?(name) || super
196
196
  end
197
197
  end
data/lib/hanami/config.rb CHANGED
@@ -110,7 +110,12 @@ module Hanami
110
110
  #
111
111
  # @api public
112
112
  # @since 2.0.0
113
- setting :no_auto_register_paths, default: %w[entities]
113
+ setting :no_auto_register_paths, default: [
114
+ "db",
115
+ "entities",
116
+ "relations",
117
+ "structs"
118
+ ]
114
119
 
115
120
  # @!attribute [rw] base_url
116
121
  # Sets the base URL for app's web server.
@@ -216,6 +221,20 @@ module Hanami
216
221
  # @since 2.0.0
217
222
  attr_reader :actions
218
223
 
224
+ # Returns the app's db config, or a null config if hanami-db is not bundled.
225
+ #
226
+ # @example When hanami-db is bundled
227
+ # config.db.import_from_parent # => false
228
+ #
229
+ # @example When hanami-db is not bundle
230
+ # config.db.import_from_parent # => NoMethodError
231
+ #
232
+ # @return [Hanami::Config::DB, Hanami::Config::NullConfig]
233
+ #
234
+ # @api public
235
+ # @since 2.2.0
236
+ attr_reader :db
237
+
219
238
  # Returns the app's middleware stack, or nil if hanami-router is not bundled.
220
239
  #
221
240
  # Use this to configure middleware that should apply to all routes.
@@ -288,16 +307,27 @@ module Hanami
288
307
  self.render_detailed_errors = (env == :development)
289
308
  load_from_env
290
309
 
291
- @logger = Config::Logger.new(env: env, app_name: app_name)
292
310
 
293
311
  @actions = load_dependent_config("hanami-controller") {
294
312
  require_relative "config/actions"
295
313
  Actions.new
296
314
  }
297
315
 
316
+ @assets = load_dependent_config("hanami-assets") {
317
+ require_relative "config/assets"
318
+ Hanami::Config::Assets.new
319
+ }
320
+
321
+ @db = load_dependent_config("hanami-db") { DB.new }
322
+
323
+ @logger = Config::Logger.new(env: env, app_name: app_name)
324
+
325
+ @middleware = load_dependent_config("hanami-router") {
326
+ Slice::Routing::Middleware::Stack.new
327
+ }
328
+
298
329
  @router = load_dependent_config("hanami-router") {
299
330
  require_relative "config/router"
300
- @middleware = Slice::Routing::Middleware::Stack.new
301
331
  Router.new(self)
302
332
  }
303
333
 
@@ -306,11 +336,6 @@ module Hanami
306
336
  Views.new
307
337
  }
308
338
 
309
- @assets = load_dependent_config("hanami-assets") {
310
- require_relative "config/assets"
311
- Hanami::Config::Assets.new
312
- }
313
-
314
339
  yield self if block_given?
315
340
  end
316
341
  # rubocop:enable Metrics/AbcSize
@@ -321,8 +346,10 @@ module Hanami
321
346
 
322
347
  @app_name = app_name.dup
323
348
 
324
- @assets = source.assets.dup
325
349
  @actions = source.actions.dup
350
+ @assets = source.assets.dup
351
+ @db = source.db.dup
352
+ @logger = source.logger.dup
326
353
  @middleware = source.middleware.dup
327
354
  @router = source.router.dup.tap do |router|
328
355
  router.instance_variable_set(:@base_config, self)
@@ -481,7 +508,7 @@ module Hanami
481
508
  end
482
509
  end
483
510
 
484
- def respond_to_missing?(name, _incude_all = false)
511
+ def respond_to_missing?(name, _include_all = false)
485
512
  config.respond_to?(name) || super
486
513
  end
487
514
  end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "hanami/db"
4
+
5
+ module Hanami
6
+ module Extensions
7
+ # @api private
8
+ # @since 2.2.0
9
+ module DB
10
+ # @api private
11
+ # @since 2.2.0
12
+ module Repo
13
+ def self.included(repo_class)
14
+ super
15
+
16
+ repo_class.extend(Hanami::SliceConfigurable)
17
+ repo_class.extend(ClassMethods)
18
+ end
19
+
20
+ # @api private
21
+ # @since 2.2.0
22
+ module ClassMethods
23
+ def configure_for_slice(slice)
24
+ extend SliceConfiguredRepo.new(slice)
25
+ end
26
+ end
27
+ end
28
+
29
+ # @api private
30
+ # @since 2.2.0
31
+ class SliceConfiguredRepo < Module
32
+ attr_reader :slice
33
+
34
+ def initialize(slice)
35
+ super()
36
+ @slice = slice
37
+ end
38
+
39
+ def extended(repo_class)
40
+ define_inherited
41
+ configure_repo(repo_class)
42
+ define_new
43
+ end
44
+
45
+ def inspect
46
+ "#<#{self.class.name}[#{slice.name}]>"
47
+ end
48
+
49
+ private
50
+
51
+ def define_inherited
52
+ root_for_repo_class = method(:root_for_repo_class)
53
+
54
+ define_method(:inherited) do |subclass|
55
+ super(subclass)
56
+
57
+ unless subclass.root
58
+ root = root_for_repo_class.(subclass)
59
+ subclass.root root if root
60
+ end
61
+ end
62
+ end
63
+
64
+ def configure_repo(repo_class)
65
+ repo_class.struct_namespace struct_namespace
66
+ end
67
+
68
+ def define_new
69
+ resolve_rom = method(:resolve_rom)
70
+
71
+ define_method(:new) do |**kwargs|
72
+ super(container: kwargs.fetch(:container) { resolve_rom.() })
73
+ end
74
+ end
75
+
76
+ def resolve_rom
77
+ slice["db.rom"]
78
+ end
79
+
80
+ def root_for_repo_class(repo_class)
81
+ return unless repo_class.to_s.end_with?("Repo")
82
+
83
+ slice.inflector.demodulize(repo_class)
84
+ .then { slice.inflector.underscore(_1) }
85
+ .then { _1.gsub(/_repo$/, "") }
86
+ .then { slice.inflector.pluralize(_1) }
87
+ .then { _1.to_sym }
88
+ end
89
+
90
+ def struct_namespace
91
+ @struct_namespace ||=
92
+ if slice.namespace.const_defined?(:Structs)
93
+ slice.namespace.const_get(:Structs)
94
+ else
95
+ slice.namespace.const_set(:Structs, Module.new)
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ Hanami::DB::Repo.include(Hanami::Extensions::DB::Repo)
@@ -156,7 +156,7 @@ module Hanami
156
156
  @assets
157
157
  end
158
158
 
159
- # Returns the current request, if the view is rendered from within an action.
159
+ # Returns the current request, if the view is rendered from within an action.
160
160
  #
161
161
  # @return [Hanami::Action::Request] the request
162
162
  #
@@ -46,7 +46,7 @@ module Hanami
46
46
  # Standalone helpers class including both {StandardHelpers} as well as the user-defined
47
47
  # helpers for the slice.
48
48
  #
49
- # Used used where helpers should be addressed via an intermediary object (i.e. in parts),
49
+ # Used where helpers should be addressed via an intermediary object (i.e. in parts),
50
50
  # rather than mixed into a class directly.
51
51
  #
52
52
  # @api private
@@ -3,7 +3,7 @@
3
3
  module Hanami
4
4
  module Extensions
5
5
  module View
6
- # Provides slice-specific helper methods any view object requiring access to helpers.
6
+ # Provides slice-specific helper methods for any view object requiring access to helpers.
7
7
  #
8
8
  # @api public
9
9
  # @since 2.1.0
@@ -1,5 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ if Hanami.bundled?("hanami-db")
4
+ require_relative "extensions/db/repo"
5
+ end
6
+
3
7
  if Hanami.bundled?("hanami-controller")
4
8
  require_relative "extensions/action"
5
9
  end
@@ -81,7 +81,7 @@ module Hanami
81
81
  # If the "CDN mode" is on, the `src` is an absolute URL of the
82
82
  # application CDN.
83
83
  #
84
- # If the "subresource integrity mode" is on, `integriy` is the
84
+ # If the "subresource integrity mode" is on, `integrity` is the
85
85
  # name of the algorithm, then a hyphen, then the hash value of the file.
86
86
  # If more than one algorithm is used, they"ll be separated by a space.
87
87
  #
@@ -185,7 +185,7 @@ module Hanami
185
185
  # If the "CDN mode" is on, the `href` is an absolute URL of the
186
186
  # application CDN.
187
187
  #
188
- # If the "subresource integrity mode" is on, `integriy` is the
188
+ # If the "subresource integrity mode" is on, `integrity` is the
189
189
  # name of the algorithm, then a hyphen, then the hashed value of the file.
190
190
  # If more than one algorithm is used, they"ll be separated by a space.
191
191
  #
@@ -270,7 +270,7 @@ module Hanami
270
270
  # Generate `img` tag for given source
271
271
  #
272
272
  # It accepts one string representing the name of the asset, if it comes
273
- # from the application or third party gems. It also accepts string
273
+ # from the application or third party gems. It also accepts strings
274
274
  # representing absolute URLs in case of public CDN (eg. Bootstrap CDN).
275
275
  #
276
276
  # `alt` Attribute is auto generated from `src`.
@@ -412,7 +412,7 @@ module Hanami
412
412
  # Generate `video` tag for given source
413
413
  #
414
414
  # It accepts one string representing the name of the asset, if it comes
415
- # from the application or third party gems. It also accepts string
415
+ # from the application or third party gems. It also accepts strings
416
416
  # representing absolute URLs in case of public CDN (eg. Bootstrap CDN).
417
417
  #
418
418
  # Alternatively, it accepts a block that allows to specify one or more
@@ -514,7 +514,7 @@ module Hanami
514
514
  # Generate `audio` tag for given source
515
515
  #
516
516
  # It accepts one string representing the name of the asset, if it comes
517
- # from the application or third party gems. It also accepts string
517
+ # from the application or third party gems. It also accepts strings
518
518
  # representing absolute URLs in case of public CDN (eg. Bootstrap CDN).
519
519
  #
520
520
  # Alternatively, it accepts a block that allows to specify one or more
@@ -190,7 +190,7 @@ module Hanami
190
190
  # @param name [String] the input name, also used as the base input name for all fields
191
191
  # within the block
192
192
  # @yieldparam [FormBuilder] the form builder for the nested fields
193
- # @yieldparam [Integer] the index of the iteration over the colletion, starting from zero
193
+ # @yieldparam [Integer] the index of the iteration over the collection, starting from zero
194
194
  # @yieldparam [Object] the value of the element from the collection
195
195
  #
196
196
  # @example Basic usage
@@ -226,10 +226,8 @@ module Hanami
226
226
  # @api public
227
227
  # @since 2.1.0
228
228
  def fields_for_collection(name, &block)
229
- collection_base_name = [base_name, name.to_s].compact.join(INPUT_NAME_SEPARATOR)
230
-
231
229
  _value(name).each_with_index do |value, index|
232
- fields_for("#{collection_base_name}.#{index}", index, value, &block)
230
+ fields_for("#{name}.#{index}", index, value, &block)
233
231
  end
234
232
  end
235
233
 
@@ -295,7 +293,7 @@ module Hanami
295
293
  attributes[:for] = _input_id(attributes[:for] || content)
296
294
 
297
295
  if content && !for_attribute_given
298
- content = inflector.humanize(content.split(INPUT_NAME_SEPARATOR).last)
296
+ content = inflector.humanize(content.to_s.split(INPUT_NAME_SEPARATOR).last)
299
297
  end
300
298
 
301
299
  tag.label(content, **attributes, &block)
@@ -694,7 +692,7 @@ module Hanami
694
692
  #
695
693
  # @example Advanced attributes
696
694
  # f.number_field("book.percent_read", min: 1, max: 100, step: 1)
697
- # => <input type="number" name="book[percent_read]" id="book-precent-read" value="" min="1" max="100" step="1">
695
+ # => <input type="number" name="book[percent_read]" id="book-percent-read" value="" min="1" max="100" step="1">
698
696
  #
699
697
  # @api public
700
698
  # @since 2.1.0
@@ -4,8 +4,8 @@ require "rack"
4
4
 
5
5
  module Hanami
6
6
  module Middleware
7
- # The errors app given to {Hanami::Middleware::RenderErrors}, which renders a error responses
8
- # from HTML pages kept in `public/` or as simple JSON structures.
7
+ # The errors app given to {Hanami::Middleware::RenderErrors}, which renders error responses
8
+ # from HTML pages kept in `public/` as simple JSON structures.
9
9
  #
10
10
  # @see Hanami::Middleware::RenderErrors
11
11
  #
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 2.2.0
5
+ module Hanami
6
+ class ProviderRegistrar < Dry::System::ProviderRegistrar
7
+ def self.for_slice(slice)
8
+ Class.new(self) do
9
+ define_singleton_method(:new) do |container|
10
+ super(container, slice)
11
+ end
12
+ end
13
+ end
14
+
15
+ attr_reader :slice
16
+
17
+ def initialize(container, slice)
18
+ super(container)
19
+ @slice = slice
20
+ end
21
+
22
+ def target_container
23
+ slice
24
+ end
25
+ end
26
+ end