hanami 2.1.0 → 2.2.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
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