dry-rails 0.2.0
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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +28 -0
- data/LICENSE +20 -0
- data/README.md +30 -0
- data/dry-rails.gemspec +38 -0
- data/lib/dry-rails.rb +3 -0
- data/lib/dry/rails.rb +56 -0
- data/lib/dry/rails/auto_registrars/app.rb +31 -0
- data/lib/dry/rails/boot/application_contract.rb +18 -0
- data/lib/dry/rails/boot/controller_helpers.rb +11 -0
- data/lib/dry/rails/boot/safe_params.rb +11 -0
- data/lib/dry/rails/components.rb +8 -0
- data/lib/dry/rails/container.rb +168 -0
- data/lib/dry/rails/features/application_contract.rb +38 -0
- data/lib/dry/rails/features/controller_helpers.rb +40 -0
- data/lib/dry/rails/features/safe_params.rb +82 -0
- data/lib/dry/rails/railtie.rb +141 -0
- data/lib/dry/rails/version.rb +7 -0
- metadata +149 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c3503a4784fff4602afd40a4617ec013c95a69b71308dabd5c2e8daf90901337
|
4
|
+
data.tar.gz: 271597c911b36d298bc741350abf4ae8c8f78e2c41f6ae2a0bfe467fb2666eba
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 801d04d9a2d3860c790ff3a5e7f8f0573bb9432c7d26ba62e833915b85f46021930ad08821c04271c51ee2c1cd82a8fe7031fbe27053e15c8df81fe4d84e4232
|
7
|
+
data.tar.gz: 9bbb63b8b0f50ceef021dd2dbc5a0d65dae979c9f239a39e68215619c85cf18a6445db8f0f618c8c2c7f48b1de2a344a547e763009dc9ebf32e1c3c411c5b904
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
## unreleased
|
2
|
+
|
3
|
+
|
4
|
+
### Added
|
5
|
+
|
6
|
+
- You can now configure auto_inject constant name via `config.auto_inject_constant` - previously it was hardcoded as `"Import"`, now it's configured as `"Deps"` by default (issue #18 closed via #29) (@diegotoral)
|
7
|
+
|
8
|
+
### Fixed
|
9
|
+
|
10
|
+
- Resolving `Container` constant looks it up only within the application namespace (see #22 for more information) (@jandudulski)
|
11
|
+
- [safe_params] defining multiple schemas works as expected (issue #23 fixed via 24) (@gotar)
|
12
|
+
|
13
|
+
### Changed
|
14
|
+
|
15
|
+
- The `:env` dry-system plugin is now enabled by default (fixes #28 via #30) (@solnic)
|
16
|
+
|
17
|
+
[Compare v0.1.0...master](https://github.com/dry-rb/dry-rails/compare/v0.1.0...master)
|
18
|
+
|
19
|
+
## 0.1.0 2020-03-30
|
20
|
+
|
21
|
+
This is based on dry-system-rails that dry-rails replaces.
|
22
|
+
|
23
|
+
### Added
|
24
|
+
|
25
|
+
- `config.features` setting which is an array with feature identifiers that you want the railtie to boot (@solnic)
|
26
|
+
- `:application_contract` feature which defines `ApplicationContract` within the application namespace and configured to work with `I18n` (@solnic)
|
27
|
+
- `:safe_params` feature which extends `ApplicationController` with `schema` DSL and exposes `safe_params` controller helper (@solnic)
|
28
|
+
- `:controller_helpers` feature which adds `ApplicationController#{resolve,container}` shortcuts (@solnic)
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015-2020 dry-rb team
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
[gem]: https://rubygems.org/gems/dry-rails
|
2
|
+
[actions]: https://github.com/dry-rb/dry-rails/actions
|
3
|
+
[codacy]: https://www.codacy.com/gh/dry-rb/dry-rails
|
4
|
+
[chat]: https://dry-rb.zulipchat.com
|
5
|
+
[inchpages]: http://inch-ci.org/github/dry-rb/dry-rails
|
6
|
+
|
7
|
+
# dry-rails [][chat]
|
8
|
+
|
9
|
+
[][gem]
|
10
|
+
[][actions]
|
11
|
+
[][codacy]
|
12
|
+
[][codacy]
|
13
|
+
[][inchpages]
|
14
|
+
|
15
|
+
dry-rails provides the official integration of dry-rb gems with Ruby on Rails framework.
|
16
|
+
## Links
|
17
|
+
|
18
|
+
* [User documentation](http://dry-rb.org/gems/dry-rails)
|
19
|
+
* [API documentation](http://rubydoc.info/gems/dry-rails)
|
20
|
+
|
21
|
+
## Supported Ruby versions
|
22
|
+
|
23
|
+
This library officially supports the following Ruby versions:
|
24
|
+
|
25
|
+
* MRI >= `2.4`
|
26
|
+
* jruby >= `9.2`
|
27
|
+
|
28
|
+
## License
|
29
|
+
|
30
|
+
See `LICENSE` file.
|
data/dry-rails.gemspec
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# this file is managed by dry-rb/devtools project
|
3
|
+
|
4
|
+
lib = File.expand_path('lib', __dir__)
|
5
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
6
|
+
require 'dry/rails/version'
|
7
|
+
|
8
|
+
Gem::Specification.new do |spec|
|
9
|
+
spec.name = 'dry-rails'
|
10
|
+
spec.authors = ["Piotr Solnica"]
|
11
|
+
spec.email = ["piotr.solnica@gmail.com"]
|
12
|
+
spec.license = 'MIT'
|
13
|
+
spec.version = Dry::Rails::VERSION.dup
|
14
|
+
|
15
|
+
spec.summary = "The official dry-rb railtie for Ruby on Rails"
|
16
|
+
spec.description = "dry-rails provides the official integration of dry-rb gems with Ruby on Rails framework."
|
17
|
+
spec.homepage = 'https://dry-rb.org/gems/dry-rails'
|
18
|
+
spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-rails.gemspec", "lib/**/*"]
|
19
|
+
spec.bindir = 'bin'
|
20
|
+
spec.executables = []
|
21
|
+
spec.require_paths = ['lib']
|
22
|
+
|
23
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
24
|
+
spec.metadata['changelog_uri'] = 'https://github.com/dry-rb/dry-rails/blob/master/CHANGELOG.md'
|
25
|
+
spec.metadata['source_code_uri'] = 'https://github.com/dry-rb/dry-rails'
|
26
|
+
spec.metadata['bug_tracker_uri'] = 'https://github.com/dry-rb/dry-rails/issues'
|
27
|
+
|
28
|
+
spec.required_ruby_version = ">= 2.4.0"
|
29
|
+
|
30
|
+
# to update dependencies edit project.yml
|
31
|
+
spec.add_runtime_dependency "dry-schema", "~> 1.5"
|
32
|
+
spec.add_runtime_dependency "dry-system", "~> 0.17"
|
33
|
+
spec.add_runtime_dependency "dry-validation", "~> 1.5"
|
34
|
+
|
35
|
+
spec.add_development_dependency "bundler"
|
36
|
+
spec.add_development_dependency "rake"
|
37
|
+
spec.add_development_dependency "rspec"
|
38
|
+
end
|
data/lib/dry-rails.rb
ADDED
data/lib/dry/rails.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/rails/railtie"
|
4
|
+
require "dry/rails/container"
|
5
|
+
require "dry/rails/components"
|
6
|
+
|
7
|
+
module Dry
|
8
|
+
# Initializer interface
|
9
|
+
#
|
10
|
+
# @example set up a container with auto-registration paths
|
11
|
+
# # config/initializer/system.rb
|
12
|
+
#
|
13
|
+
# Dry::Rails.container do
|
14
|
+
# auto_register!("lib", "app/operations")
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# @see Dry::Rails::Container.auto_register!
|
18
|
+
#
|
19
|
+
# @api public
|
20
|
+
module Rails
|
21
|
+
# Set container block that will be evaluated in the context of the container
|
22
|
+
#
|
23
|
+
# @return [self]
|
24
|
+
#
|
25
|
+
# @api public
|
26
|
+
def self.container(&block)
|
27
|
+
_container_blocks << block
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
# Create a new container class
|
32
|
+
#
|
33
|
+
# This is used during booting and reloading
|
34
|
+
#
|
35
|
+
# @param options [Hash] Container configuration settings
|
36
|
+
#
|
37
|
+
# @return [Class]
|
38
|
+
#
|
39
|
+
# @api private
|
40
|
+
def self.create_container(options = {})
|
41
|
+
Class.new(Container) { config.update(options) }
|
42
|
+
end
|
43
|
+
|
44
|
+
# @api private
|
45
|
+
def self.evaluate_initializer(container)
|
46
|
+
_container_blocks.each do |block|
|
47
|
+
container.class_eval(&block)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# @api private
|
52
|
+
def self._container_blocks
|
53
|
+
@_container_blocks ||= []
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/system/auto_registrar"
|
4
|
+
|
5
|
+
module Dry
|
6
|
+
module Rails
|
7
|
+
module AutoRegistrars
|
8
|
+
# This is the default auto-registrar configured in the Container
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
class App < System::AutoRegistrar
|
12
|
+
# Resolve a path relative to the system root
|
13
|
+
#
|
14
|
+
# This works just like in `dry-system` except that it's app-dir aware. This means it will
|
15
|
+
# turn `app/operations/foo/bar` to `foo/bar` because app dirs are treated as root dirs.
|
16
|
+
#
|
17
|
+
# In a typical dry-system setup `app` would be the root and everything inside this path
|
18
|
+
# would indicate the constant hierachy, so `app/operations/foo/bar` => `Operations/Foo/Bar`
|
19
|
+
# but *this is not the Rails convention* so we need this special auto-registrar.
|
20
|
+
#
|
21
|
+
# @api private
|
22
|
+
def relative_path(dir, file_path)
|
23
|
+
path = super
|
24
|
+
return path unless dir.start_with?("app")
|
25
|
+
|
26
|
+
path.split("/")[1..-1].join("/")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Dry::System.register_component(:application_contract, provider: :rails) do
|
4
|
+
init do
|
5
|
+
require "dry/rails/features/application_contract"
|
6
|
+
end
|
7
|
+
|
8
|
+
start do
|
9
|
+
railtie.set_or_reload(
|
10
|
+
:ApplicationContract,
|
11
|
+
Class.new(Dry::Rails::Features::ApplicationContract).finalize!(railtie)
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
stop do
|
16
|
+
railtie.remove_constant(:ApplicationContract)
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Dry::System.register_component(:controller_helpers, provider: :rails) do
|
4
|
+
init do
|
5
|
+
require "dry/rails/features/controller_helpers"
|
6
|
+
end
|
7
|
+
|
8
|
+
start do
|
9
|
+
ApplicationController.include(Dry::Rails::Features::ControllerHelpers)
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/version"
|
4
|
+
|
5
|
+
require "dry/system/container"
|
6
|
+
require "dry/system/components"
|
7
|
+
|
8
|
+
require "dry/rails/auto_registrars/app"
|
9
|
+
|
10
|
+
module Dry
|
11
|
+
module Rails
|
12
|
+
# Customized Container class for Rails applications
|
13
|
+
#
|
14
|
+
# @api public
|
15
|
+
class Container < System::Container
|
16
|
+
# @!group Configuration
|
17
|
+
|
18
|
+
# @overload config.features=(features)
|
19
|
+
# Set an array of features that should be enabled by default
|
20
|
+
#
|
21
|
+
# Available values are:
|
22
|
+
# - application_contract
|
23
|
+
# - safe_params
|
24
|
+
# - controller_helpers
|
25
|
+
#
|
26
|
+
# @param features [Array<Symbol>]
|
27
|
+
#
|
28
|
+
# @api public
|
29
|
+
# @!scope class
|
30
|
+
setting :features, %i[application_contract safe_params controller_helpers], reader: true
|
31
|
+
|
32
|
+
# @overload config.auto_register_paths=(paths)
|
33
|
+
# Set an array of path/block pairs for auto-registration
|
34
|
+
#
|
35
|
+
# This is a low-level setting that typically should not be set explicitly,
|
36
|
+
# use `auto_register!` instead.
|
37
|
+
#
|
38
|
+
# @param paths [Array<Array>]
|
39
|
+
#
|
40
|
+
# @api public
|
41
|
+
# @!scope class
|
42
|
+
setting :auto_register_paths, [].freeze, reader: true
|
43
|
+
|
44
|
+
# @overload config.auto_inject_constant=(auto_inject_constant)
|
45
|
+
# Set a custom import constant name
|
46
|
+
#
|
47
|
+
# @param auto_inject_constant [String]
|
48
|
+
#
|
49
|
+
# @api public
|
50
|
+
# @!scope class
|
51
|
+
setting :auto_inject_constant, "Deps", reader: true
|
52
|
+
|
53
|
+
# @!endgroup
|
54
|
+
|
55
|
+
# The railtie has a rails-specific auto-registrar which is app-dir aware
|
56
|
+
config.auto_registrar = Rails::AutoRegistrars::App
|
57
|
+
|
58
|
+
class << self
|
59
|
+
# Set up auto-registration paths and optional a configuration block
|
60
|
+
#
|
61
|
+
# @example set up a single path
|
62
|
+
# Dry::Rails.container do
|
63
|
+
# auto_register!("app/operations")
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# @example set up a single path with a configuration block
|
67
|
+
# Dry::Rails.container do
|
68
|
+
# auto_register!("app/operations") do |config|
|
69
|
+
# config.exclude do |component|
|
70
|
+
# component.path.start_with?("concerns")
|
71
|
+
# end
|
72
|
+
# end
|
73
|
+
# end
|
74
|
+
#
|
75
|
+
# @example set up multiple paths
|
76
|
+
# Dry::Rails.container do
|
77
|
+
# auto_register!("lib", "app/operations")
|
78
|
+
# end
|
79
|
+
#
|
80
|
+
# @example set up multiple paths with a configuration block
|
81
|
+
# Dry::Rails.container do
|
82
|
+
# # in this case the config block will be applied to all paths
|
83
|
+
# auto_register!("lib", "app/operations") do |config|
|
84
|
+
# config.exclude do |component|
|
85
|
+
# component.path.start_with?("concerns")
|
86
|
+
# end
|
87
|
+
# end
|
88
|
+
# end
|
89
|
+
#
|
90
|
+
# @param paths [Array<String>] One or more paths relative to the root
|
91
|
+
# @param set_load_paths [Boolean] Whether the paths should be added to $LOAD_PATH
|
92
|
+
# @param load_files [Boolean] Whether files should be `required`-ed already
|
93
|
+
#
|
94
|
+
# @return [self]
|
95
|
+
#
|
96
|
+
# @api public
|
97
|
+
#
|
98
|
+
# TODO: this should be moved to dry-system
|
99
|
+
def auto_register!(*paths, set_load_paths: true, load_files: false, &block)
|
100
|
+
load_paths!(*paths) if set_load_paths
|
101
|
+
|
102
|
+
if load_files
|
103
|
+
paths.each { |path| super(path, &block) }
|
104
|
+
else
|
105
|
+
config.auto_register_paths.concat(paths.product([block]))
|
106
|
+
end
|
107
|
+
|
108
|
+
self
|
109
|
+
end
|
110
|
+
|
111
|
+
# Finalize the container
|
112
|
+
#
|
113
|
+
# This is called automatically via the railtie, so typically you won't be using this method
|
114
|
+
# directly
|
115
|
+
#
|
116
|
+
# @param freeze [Boolean] Whether the container should be frozen upon finalization
|
117
|
+
#
|
118
|
+
# @return [self]
|
119
|
+
#
|
120
|
+
# @api public
|
121
|
+
#
|
122
|
+
# TODO: just like auto_register!, this should be moved to dry-system
|
123
|
+
def finalize!(freeze: false, &block)
|
124
|
+
features.each do |feature|
|
125
|
+
start(feature)
|
126
|
+
end
|
127
|
+
|
128
|
+
auto_register_paths.each do |(path, path_block)|
|
129
|
+
auto_register!(path, set_load_paths: false, load_files: true, &path_block)
|
130
|
+
end
|
131
|
+
|
132
|
+
super
|
133
|
+
end
|
134
|
+
|
135
|
+
# Return if a given component was booted
|
136
|
+
#
|
137
|
+
# @return [Boolean]
|
138
|
+
#
|
139
|
+
# @api private
|
140
|
+
#
|
141
|
+
# TODO: this should be moved to dry-system
|
142
|
+
def booted?(name)
|
143
|
+
booter.booted.map(&:identifier).include?(name)
|
144
|
+
end
|
145
|
+
|
146
|
+
# TODO: confirm that this is really needed
|
147
|
+
if ::Rails.version.start_with?("5")
|
148
|
+
# @api private
|
149
|
+
def require_path(path)
|
150
|
+
require_dependency(path)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# This is called when reloading in dev mode
|
155
|
+
#
|
156
|
+
# @return [self]
|
157
|
+
#
|
158
|
+
# @api private
|
159
|
+
def refresh_boot_files
|
160
|
+
booter.boot_files.each do |boot_file|
|
161
|
+
load(boot_file)
|
162
|
+
end
|
163
|
+
self
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/validation/contract"
|
4
|
+
|
5
|
+
module Dry
|
6
|
+
module Rails
|
7
|
+
module Features
|
8
|
+
# Abstract application contract class used by the `:application_contract` feature
|
9
|
+
#
|
10
|
+
# This is an abstract class that's pre-configured during booting process to serve as the base
|
11
|
+
# class that the ApplicationContract class inherits from.
|
12
|
+
#
|
13
|
+
# @see https://dry-rb.org/gems/dry-validation/1.5/configuration/
|
14
|
+
#
|
15
|
+
# @abstract
|
16
|
+
#
|
17
|
+
# @api public
|
18
|
+
class ApplicationContract < Dry::Validation::Contract
|
19
|
+
# This is called during the booting process of the `:application_contract` feature
|
20
|
+
#
|
21
|
+
# @param railtie [Dry::Rails::Railtie]
|
22
|
+
#
|
23
|
+
# @return [Class]
|
24
|
+
#
|
25
|
+
# @api private
|
26
|
+
def self.finalize!(railtie)
|
27
|
+
load_paths = Dir[railtie.container.root.join("config/locales/*.yml")]
|
28
|
+
|
29
|
+
config.messages.top_namespace = :contracts
|
30
|
+
config.messages.backend = :i18n
|
31
|
+
config.messages.load_paths += load_paths
|
32
|
+
|
33
|
+
self
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dry
|
4
|
+
module Rails
|
5
|
+
module Features
|
6
|
+
# Controller helpers
|
7
|
+
#
|
8
|
+
# @api public
|
9
|
+
module ControllerHelpers
|
10
|
+
# Return a component from the application container
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# def index
|
14
|
+
# users = resolve("users.index").(safe_params[:query])
|
15
|
+
# render json: users
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# @param key [Symbol, String] The component key
|
19
|
+
#
|
20
|
+
# @return [Object]
|
21
|
+
#
|
22
|
+
# @raise Dry::Container::Error
|
23
|
+
#
|
24
|
+
# @api public
|
25
|
+
def resolve(key)
|
26
|
+
container[key]
|
27
|
+
end
|
28
|
+
|
29
|
+
# Return the application container
|
30
|
+
#
|
31
|
+
# @return [Dry::Rails::Container]
|
32
|
+
#
|
33
|
+
# @api public
|
34
|
+
def container
|
35
|
+
Railtie.container
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/schema/params"
|
4
|
+
|
5
|
+
module Dry
|
6
|
+
module Rails
|
7
|
+
module Features
|
8
|
+
# SafeParams controller feature
|
9
|
+
#
|
10
|
+
# @api public
|
11
|
+
module SafeParams
|
12
|
+
# @api private
|
13
|
+
def self.included(klass)
|
14
|
+
super
|
15
|
+
klass.extend(ClassMethods)
|
16
|
+
|
17
|
+
klass.class_eval do
|
18
|
+
before_action(:set_safe_params, prepend: true)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# ApplicationController methods
|
23
|
+
#
|
24
|
+
# @api public
|
25
|
+
module ClassMethods
|
26
|
+
# Define a schema for controller action(s)
|
27
|
+
#
|
28
|
+
# @param actions [Array<Symbol>]
|
29
|
+
#
|
30
|
+
# @return [self]
|
31
|
+
#
|
32
|
+
# @api public
|
33
|
+
def schema(*actions, &block)
|
34
|
+
schema = Dry::Schema.Params(&block)
|
35
|
+
|
36
|
+
actions.each do |name|
|
37
|
+
schemas[name] = schema
|
38
|
+
end
|
39
|
+
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
# Return registered schemas
|
44
|
+
#
|
45
|
+
# @api private
|
46
|
+
def schemas
|
47
|
+
@schemas ||= {}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Return schema result
|
52
|
+
#
|
53
|
+
# @return [Dry::Schema::Result]
|
54
|
+
#
|
55
|
+
# @api public
|
56
|
+
def safe_params
|
57
|
+
@safe_params
|
58
|
+
end
|
59
|
+
|
60
|
+
# Return registered action schemas
|
61
|
+
#
|
62
|
+
# @return [Hash<Symbol => Dry::Schema::Params]
|
63
|
+
#
|
64
|
+
# @api public
|
65
|
+
def schemas
|
66
|
+
self.class.schemas
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
# @api private
|
72
|
+
def set_safe_params
|
73
|
+
schema = schemas[action_name.to_sym]
|
74
|
+
|
75
|
+
return unless schema
|
76
|
+
|
77
|
+
@safe_params = schema.(request.params)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/railtie"
|
4
|
+
|
5
|
+
module Dry
|
6
|
+
module Rails
|
7
|
+
# The railtie is responsible for setting up a container and handling reloading in dev mode
|
8
|
+
#
|
9
|
+
# @api public
|
10
|
+
class Railtie < ::Rails::Railtie
|
11
|
+
# This is needed because `finalize!` can reload code and this hook is called every-time
|
12
|
+
# in development env upon a request (in production it's called just once during booting)
|
13
|
+
config.to_prepare do
|
14
|
+
Railtie.finalize!
|
15
|
+
end
|
16
|
+
|
17
|
+
# Code-reloading-aware finalization process
|
18
|
+
#
|
19
|
+
# This sets up `Container` and `Deps` constants, reloads them if this is in reloading mode,
|
20
|
+
# and registers default components like the railtie itself or the inflector
|
21
|
+
#
|
22
|
+
# @api public
|
23
|
+
#
|
24
|
+
# rubocop:disable Metrics/AbcSize
|
25
|
+
def finalize!
|
26
|
+
stop_features if reloading?
|
27
|
+
|
28
|
+
root_path = ::Rails.root
|
29
|
+
|
30
|
+
container = Dry::Rails.create_container(
|
31
|
+
root: root_path,
|
32
|
+
name: name,
|
33
|
+
default_namespace: name.to_s,
|
34
|
+
inflector: default_inflector,
|
35
|
+
system_dir: root_path.join("config/system")
|
36
|
+
)
|
37
|
+
|
38
|
+
# Enable :env plugin by default because it is a very common requirement
|
39
|
+
container.use :env, inferrer: -> { ::Rails.env }
|
40
|
+
|
41
|
+
container.register(:railtie, self)
|
42
|
+
container.register(:inflector, default_inflector)
|
43
|
+
|
44
|
+
set_or_reload(:Container, container)
|
45
|
+
|
46
|
+
Dry::Rails.evaluate_initializer(container)
|
47
|
+
|
48
|
+
set_or_reload(container.auto_inject_constant, container.injector)
|
49
|
+
|
50
|
+
container.features.each do |feature|
|
51
|
+
container.boot(feature, from: :rails)
|
52
|
+
end
|
53
|
+
|
54
|
+
container.refresh_boot_files if reloading?
|
55
|
+
|
56
|
+
container.finalize!(freeze: !::Rails.env.test?)
|
57
|
+
end
|
58
|
+
# rubocop:enable Metrics/AbcSize
|
59
|
+
alias_method :reload, :finalize!
|
60
|
+
|
61
|
+
# Stops all configured features (bootable components)
|
62
|
+
#
|
63
|
+
# This is *crucial* when reloading code in development mode. Every bootable component
|
64
|
+
# should be able to clear the runtime from any constants that it created in its `stop`
|
65
|
+
# lifecycle step
|
66
|
+
#
|
67
|
+
# @api public
|
68
|
+
def stop_features
|
69
|
+
container.features.each do |feature|
|
70
|
+
container.stop(feature) if container.booted?(feature)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Exposes the container constant
|
75
|
+
#
|
76
|
+
# @return [Dry::Rails::Container]
|
77
|
+
#
|
78
|
+
# @api public
|
79
|
+
def container
|
80
|
+
app_namespace.const_get(:Container, false)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Return true if we're in code-reloading mode
|
84
|
+
#
|
85
|
+
# @api private
|
86
|
+
def reloading?
|
87
|
+
app_namespace.const_defined?(:Container, false)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Return the default system name
|
91
|
+
#
|
92
|
+
# In the dry-system world containers are explicitly named using symbols, so that you can
|
93
|
+
# refer to them easily when ie importing one container into another
|
94
|
+
#
|
95
|
+
# @return [Symbol]
|
96
|
+
#
|
97
|
+
# @api private
|
98
|
+
def name
|
99
|
+
app_namespace.name.underscore.to_sym
|
100
|
+
end
|
101
|
+
|
102
|
+
# Infer the default application namespace
|
103
|
+
#
|
104
|
+
# TODO: we had to rename namespace=>app_namespace because
|
105
|
+
# Rake::DSL's Kernel#namespace *sometimes* breaks things.
|
106
|
+
# Currently we are missing specs verifying that rake tasks work
|
107
|
+
# correctly and those must be added!
|
108
|
+
#
|
109
|
+
# @return [Module]
|
110
|
+
#
|
111
|
+
# @api public
|
112
|
+
def app_namespace
|
113
|
+
@app_namespace ||= begin
|
114
|
+
top_level_namespace = ::Rails.application.class.to_s.split("::").first
|
115
|
+
Object.const_get(top_level_namespace)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# Sets or reloads a constant within the application namespace
|
120
|
+
#
|
121
|
+
# @api private
|
122
|
+
def default_inflector
|
123
|
+
ActiveSupport::Inflector
|
124
|
+
end
|
125
|
+
|
126
|
+
# @api private
|
127
|
+
def set_or_reload(const_name, const)
|
128
|
+
if app_namespace.const_defined?(const_name, false)
|
129
|
+
app_namespace.__send__(:remove_const, const_name)
|
130
|
+
end
|
131
|
+
|
132
|
+
app_namespace.const_set(const_name, const)
|
133
|
+
end
|
134
|
+
|
135
|
+
# @api private
|
136
|
+
def remove_constant(const_name)
|
137
|
+
app_namespace.__send__(:remove_const, const_name)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
metadata
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dry-rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Piotr Solnica
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-07-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: dry-schema
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.5'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: dry-system
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.17'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.17'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: dry-validation
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.5'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.5'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: dry-rails provides the official integration of dry-rb gems with Ruby
|
98
|
+
on Rails framework.
|
99
|
+
email:
|
100
|
+
- piotr.solnica@gmail.com
|
101
|
+
executables: []
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- CHANGELOG.md
|
106
|
+
- LICENSE
|
107
|
+
- README.md
|
108
|
+
- dry-rails.gemspec
|
109
|
+
- lib/dry-rails.rb
|
110
|
+
- lib/dry/rails.rb
|
111
|
+
- lib/dry/rails/auto_registrars/app.rb
|
112
|
+
- lib/dry/rails/boot/application_contract.rb
|
113
|
+
- lib/dry/rails/boot/controller_helpers.rb
|
114
|
+
- lib/dry/rails/boot/safe_params.rb
|
115
|
+
- lib/dry/rails/components.rb
|
116
|
+
- lib/dry/rails/container.rb
|
117
|
+
- lib/dry/rails/features/application_contract.rb
|
118
|
+
- lib/dry/rails/features/controller_helpers.rb
|
119
|
+
- lib/dry/rails/features/safe_params.rb
|
120
|
+
- lib/dry/rails/railtie.rb
|
121
|
+
- lib/dry/rails/version.rb
|
122
|
+
homepage: https://dry-rb.org/gems/dry-rails
|
123
|
+
licenses:
|
124
|
+
- MIT
|
125
|
+
metadata:
|
126
|
+
allowed_push_host: https://rubygems.org
|
127
|
+
changelog_uri: https://github.com/dry-rb/dry-rails/blob/master/CHANGELOG.md
|
128
|
+
source_code_uri: https://github.com/dry-rb/dry-rails
|
129
|
+
bug_tracker_uri: https://github.com/dry-rb/dry-rails/issues
|
130
|
+
post_install_message:
|
131
|
+
rdoc_options: []
|
132
|
+
require_paths:
|
133
|
+
- lib
|
134
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 2.4.0
|
139
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
|
+
requirements:
|
141
|
+
- - ">="
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: '0'
|
144
|
+
requirements: []
|
145
|
+
rubygems_version: 3.0.3
|
146
|
+
signing_key:
|
147
|
+
specification_version: 4
|
148
|
+
summary: The official dry-rb railtie for Ruby on Rails
|
149
|
+
test_files: []
|