rails_ops 1.2.3 → 1.4.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 +4 -4
- data/.github/workflows/ruby.yml +2 -0
- data/.gitignore +2 -0
- data/CHANGELOG.md +23 -0
- data/README.md +41 -0
- data/VERSION +1 -1
- data/lib/rails_ops/mixins/model/nesting.rb +4 -4
- data/lib/rails_ops/model_mixins/marshalling.rb +2 -3
- data/lib/rails_ops/operation/model/destroy.rb +1 -0
- data/lib/rails_ops/operation/model/load.rb +54 -1
- data/lib/rails_ops/operation/model/update.rb +1 -0
- data/rails_ops.gemspec +6 -6
- data/test/dummy/app/models/computer.rb +3 -0
- data/test/dummy/app/models/cpu.rb +2 -0
- data/test/dummy/app/models/mainboard.rb +3 -0
- data/test/dummy/db/schema.rb +14 -0
- data/test/unit/rails_ops/mixins/model/deep_nesting_test.rb +144 -0
- metadata +17 -11
- data/test/unit/rails_ops/mixins/model/nesting.rb +0 -60
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f1937c4aa90d37d096b10168ebffa90a755be0e1c7a52dc250f95d66c2b6b7f0
|
4
|
+
data.tar.gz: 5cc13627f981463d58248762486a724cc3ae84a3e36a3ce0bf4f6edc72af7096
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f40e55561302426eea0c42554d9b2b9db3ed3806db11bc821cf14598244c1f0921343f3db138e7be366370d9d5011c3a1bf95f8a3868919dfe7bf96517e0e8a9
|
7
|
+
data.tar.gz: 9028d762c7ee9a9c6a515aaec868cea270bb970450c982038573ce83ff0f689f86e4721fe9b6487c7ad69560ec08bbfc879b2e19a97fd7a7c97eabf7e3c71d52
|
data/.github/workflows/ruby.yml
CHANGED
@@ -29,6 +29,8 @@ jobs:
|
|
29
29
|
ruby-version: '3.0.1'
|
30
30
|
- rails-version: '7.0'
|
31
31
|
ruby-version: '3.1.0'
|
32
|
+
- rails-version: '7.0'
|
33
|
+
ruby-version: '3.2.0'
|
32
34
|
name: Test against Ruby ${{ matrix.ruby-version }} / Rails ${{ matrix.rails-version }}
|
33
35
|
env:
|
34
36
|
BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/rails_${{ matrix.rails-version }}.gemfile
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,28 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 1.4.0 (2023-02-21)
|
4
|
+
|
5
|
+
### Changes
|
6
|
+
|
7
|
+
* #33: Improve resolving `param_key` in nested model operations.
|
8
|
+
|
9
|
+
### Upgrading
|
10
|
+
|
11
|
+
Please see #33 for more information on this change. If all of your operations
|
12
|
+
follow the standard naming conventions (e.g. `Operations::User::Update` for
|
13
|
+
updating a model named `User`), no changes will be necessary. If you don't, you
|
14
|
+
may need to manually specify a `param_key` when using nested model operations
|
15
|
+
(see [Model nesting](README.md#param-key) for more information).
|
16
|
+
|
17
|
+
## 1.3.0 (2023-01-23)
|
18
|
+
|
19
|
+
* Add `lock_mode` DSL method
|
20
|
+
* Set `Load` operations to use shared locking, and `Update` and `Destroy`
|
21
|
+
operations to use exclusive locking. Please make sure your operations
|
22
|
+
inherit from the correct parent operation, and change the locking mode
|
23
|
+
if it is not the correct one for your operation. More info can be found
|
24
|
+
in the section "Locking" in the Readme
|
25
|
+
|
3
26
|
## 1.2.3 (2023-01-04)
|
4
27
|
|
5
28
|
* Fix marshalling of operation models. This is especially useful for use in
|
data/README.md
CHANGED
@@ -1133,6 +1133,32 @@ class Operations::User::Update < RailsOps::Operation::Model::Update
|
|
1133
1133
|
end
|
1134
1134
|
```
|
1135
1135
|
|
1136
|
+
Please note that for performance reasons, the `Load` operation (and any
|
1137
|
+
operations inheriting from it) use a shared lock, i.e. it issues
|
1138
|
+
an `LOCK IN SHARE MODE` / `FOR SHARE` statement. The `Update` and `Destroy`
|
1139
|
+
operations (as well as operations inheriting from it) however use the default
|
1140
|
+
`lock` method of ActiveRecord, which will issue an exclusive lock.
|
1141
|
+
|
1142
|
+
If you want to change the mode, you can use the `lock_mode` DSL method, which
|
1143
|
+
has two possible modes:
|
1144
|
+
|
1145
|
+
* `:shared` for the shared lock mode
|
1146
|
+
* `:exclusive` for the exclusive lock mode
|
1147
|
+
|
1148
|
+
For example, if you have an operation loading a record which you'd want to
|
1149
|
+
lock exclusively, you'd need to write the following:
|
1150
|
+
|
1151
|
+
```ruby
|
1152
|
+
class Operations::User::Update < RailsOps::Operation::Model::Load
|
1153
|
+
model ::User
|
1154
|
+
lock_mode :exclusive
|
1155
|
+
end
|
1156
|
+
```
|
1157
|
+
|
1158
|
+
One caveat is, that shared locking is only supported for MySQl (MariaDB),
|
1159
|
+
Postgresql and Oracle DB databases, any other database will always use an
|
1160
|
+
exlusive lock.
|
1161
|
+
|
1136
1162
|
### Creating models
|
1137
1163
|
|
1138
1164
|
For creating models, you can use the base class
|
@@ -1354,6 +1380,21 @@ class User
|
|
1354
1380
|
end
|
1355
1381
|
```
|
1356
1382
|
|
1383
|
+
#### Param key
|
1384
|
+
|
1385
|
+
When nesting a model operation, the sub operation is called automatically by
|
1386
|
+
RailsOps. For this purpose, it needs to know which `param_key` to use for
|
1387
|
+
calling the sub operation, e.g. `user: { name: 'Jane Doe' }`. Normally, this is
|
1388
|
+
derived by calling `<sub-op-model-class>.model_name.param_key`. If your
|
1389
|
+
operation for some reason expects a different param key, you can specify it
|
1390
|
+
using the option `param_key`, e.g.:
|
1391
|
+
|
1392
|
+
```ruby
|
1393
|
+
# Operation Operations::Group::Create will receive the following params:
|
1394
|
+
# { my_custom_key: { ... } }
|
1395
|
+
nest_model_op :group, Operations::Group::Create, param_key: :my_custom_key
|
1396
|
+
```
|
1397
|
+
|
1357
1398
|
#### Custom parameters
|
1358
1399
|
|
1359
1400
|
In the above examples, all `group_attributes` are automatically passed to the
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.4.0
|
@@ -14,7 +14,7 @@ module RailsOps::Mixins::Model::Nesting
|
|
14
14
|
end
|
15
15
|
|
16
16
|
module ClassMethods
|
17
|
-
def nest_model_op(attribute, klass, lookup_via_id_on_update: true, allow_id: false, ¶ms_block)
|
17
|
+
def nest_model_op(attribute, klass, lookup_via_id_on_update: true, allow_id: false, param_key: nil, ¶ms_block)
|
18
18
|
# ---------------------------------------------------------------
|
19
19
|
# Make sure we're working with an extension / copy
|
20
20
|
# of the given model class
|
@@ -123,11 +123,11 @@ module RailsOps::Mixins::Model::Nesting
|
|
123
123
|
end
|
124
124
|
|
125
125
|
# Wrap parameters for nested model operation
|
126
|
-
|
126
|
+
param_key ||= config[:klass].model.model_name.param_key
|
127
127
|
|
128
128
|
if action == :create
|
129
129
|
wrapped_params = {
|
130
|
-
|
130
|
+
param_key => op_params
|
131
131
|
}
|
132
132
|
elsif action == :update
|
133
133
|
if config[:lookup_via_id_on_update]
|
@@ -139,7 +139,7 @@ module RailsOps::Mixins::Model::Nesting
|
|
139
139
|
|
140
140
|
wrapped_params = {
|
141
141
|
:id => id,
|
142
|
-
|
142
|
+
param_key => op_params
|
143
143
|
}
|
144
144
|
else
|
145
145
|
fail "Unsupported action #{action}."
|
@@ -5,14 +5,13 @@ module RailsOps
|
|
5
5
|
# with default procs which is not supported by `Marshal.dump`. This mixin
|
6
6
|
# therefore excludes this instance variable from being dumped and loaded.
|
7
7
|
module Marshalling
|
8
|
-
UNMARSHALED_VARIABLES = %i
|
8
|
+
UNMARSHALED_VARIABLES = %i(@parent_op).freeze
|
9
9
|
|
10
10
|
extend ActiveSupport::Concern
|
11
11
|
|
12
12
|
def marshal_dump
|
13
|
-
instance_variables.reject{|m| UNMARSHALED_VARIABLES.include? m}.
|
13
|
+
instance_variables.reject { |m| UNMARSHALED_VARIABLES.include? m }.each_with_object({}) do |attr, vars|
|
14
14
|
vars[attr] = instance_variable_get(attr)
|
15
|
-
vars
|
16
15
|
end
|
17
16
|
end
|
18
17
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
class RailsOps::Operation::Model::Load < RailsOps::Operation::Model
|
2
2
|
class_attribute :_lock_model_at_build
|
3
3
|
class_attribute :_load_model_authorization_action
|
4
|
+
class_attribute :_lock_mode
|
4
5
|
|
5
6
|
policy :on_init do
|
6
7
|
model_authorization
|
@@ -39,6 +40,24 @@ class RailsOps::Operation::Model::Load < RailsOps::Operation::Model
|
|
39
40
|
_lock_model_at_build.nil? ? RailsOps.config.lock_models_at_build? : _lock_model_at_build
|
40
41
|
end
|
41
42
|
|
43
|
+
# Method to set the lock mode, which can either be :exclusive to use
|
44
|
+
# an exclusive write lock, or :shared to use a shared lock. Please note
|
45
|
+
# that currently, :shared only works for MySql, Postgresql and Oracle DB,
|
46
|
+
# other adapters always use the exclusive lock.
|
47
|
+
def self.lock_mode(lock_mode)
|
48
|
+
fail "Unknown lock mode #{lock_mode}" unless %i(shared exclusive).include?(lock_mode)
|
49
|
+
|
50
|
+
self._lock_mode = lock_mode
|
51
|
+
end
|
52
|
+
|
53
|
+
# Get the lock_mode or the default of :exclusive
|
54
|
+
def self.lock_mode_or_default
|
55
|
+
_lock_mode.presence || :exclusive
|
56
|
+
end
|
57
|
+
|
58
|
+
# Set the lock mode for load operations (and it's children) to :shared
|
59
|
+
lock_mode :shared
|
60
|
+
|
42
61
|
def model_id_field
|
43
62
|
:id
|
44
63
|
end
|
@@ -52,7 +71,7 @@ class RailsOps::Operation::Model::Load < RailsOps::Operation::Model
|
|
52
71
|
relation = self.class.model
|
53
72
|
|
54
73
|
# Express intention to lock if required
|
55
|
-
relation = relation
|
74
|
+
relation = lock_relation(relation)
|
56
75
|
|
57
76
|
# Fetch (and possibly lock) model
|
58
77
|
return relation.find_by!(model_id_field => params[model_id_field])
|
@@ -69,4 +88,38 @@ class RailsOps::Operation::Model::Load < RailsOps::Operation::Model
|
|
69
88
|
def extract_id_from_params
|
70
89
|
params[model_id_field]
|
71
90
|
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def lock_relation(relation)
|
95
|
+
# Directly return the relation if we don't want to lock the relation
|
96
|
+
return relation unless self.class.lock_model_at_build?
|
97
|
+
|
98
|
+
if self.class.lock_mode_or_default == :shared
|
99
|
+
# Lock the relation in shared mode
|
100
|
+
return relation.lock(shared_lock_statement)
|
101
|
+
else
|
102
|
+
# Lock the relation in exclusive mode
|
103
|
+
return relation.lock
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def shared_lock_statement
|
108
|
+
adapter_type = ActiveRecord::Base.connection.adapter_name.downcase.to_sym
|
109
|
+
|
110
|
+
case adapter_type
|
111
|
+
when :mysql, :mysql2
|
112
|
+
return 'LOCK IN SHARE MODE'
|
113
|
+
when :postgresql
|
114
|
+
return 'FOR SHARE'
|
115
|
+
when :oracleenhanced
|
116
|
+
return 'LOCK IN SHARE MODE'
|
117
|
+
end
|
118
|
+
|
119
|
+
# Don't return anything, which will make the `lock` statement
|
120
|
+
# use the normal, exclusive lock. This might be suboptimal for other
|
121
|
+
# database adapters, but we'd rather lock too restrictive, such that
|
122
|
+
# no race-conditions may occur.
|
123
|
+
return nil
|
124
|
+
end
|
72
125
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
class RailsOps::Operation::Model::Update < RailsOps::Operation::Model::Load
|
2
2
|
model_authorization_action :update
|
3
|
+
lock_mode :exclusive
|
3
4
|
|
4
5
|
# As this operation might extend the model class, we need to make sure that
|
5
6
|
# the operation works using an extended 'copy' of the given model class.
|
data/rails_ops.gemspec
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
# stub: rails_ops 1.
|
2
|
+
# stub: rails_ops 1.4.0 ruby lib
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "rails_ops".freeze
|
6
|
-
s.version = "1.
|
6
|
+
s.version = "1.4.0"
|
7
7
|
|
8
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
9
9
|
s.require_paths = ["lib".freeze]
|
10
10
|
s.authors = ["Sitrox".freeze]
|
11
|
-
s.date = "2023-
|
12
|
-
s.files = [".github/workflows/rubocop.yml".freeze, ".github/workflows/ruby.yml".freeze, ".gitignore".freeze, ".releaser_config".freeze, ".rubocop.yml".freeze, "Appraisals".freeze, "CHANGELOG.md".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "gemfiles/rails_6.0.gemfile".freeze, "gemfiles/rails_6.1.gemfile".freeze, "gemfiles/rails_7.0.gemfile".freeze, "lib/generators/operation/USAGE".freeze, "lib/generators/operation/operation_generator.rb".freeze, "lib/generators/operation/templates/controller.erb".freeze, "lib/generators/operation/templates/create.erb".freeze, "lib/generators/operation/templates/destroy.erb".freeze, "lib/generators/operation/templates/load.erb".freeze, "lib/generators/operation/templates/update.erb".freeze, "lib/generators/operation/templates/view.erb".freeze, "lib/rails_ops.rb".freeze, "lib/rails_ops/authorization_backend/abstract.rb".freeze, "lib/rails_ops/authorization_backend/can_can_can.rb".freeze, "lib/rails_ops/configuration.rb".freeze, "lib/rails_ops/context.rb".freeze, "lib/rails_ops/controller_mixin.rb".freeze, "lib/rails_ops/exceptions.rb".freeze, "lib/rails_ops/hooked_job.rb".freeze, "lib/rails_ops/hookup.rb".freeze, "lib/rails_ops/hookup/dsl.rb".freeze, "lib/rails_ops/hookup/dsl_validator.rb".freeze, "lib/rails_ops/hookup/hook.rb".freeze, "lib/rails_ops/log_subscriber.rb".freeze, "lib/rails_ops/mixins.rb".freeze, "lib/rails_ops/mixins/authorization.rb".freeze, "lib/rails_ops/mixins/log_settings.rb".freeze, "lib/rails_ops/mixins/model.rb".freeze, "lib/rails_ops/mixins/model/authorization.rb".freeze, "lib/rails_ops/mixins/model/nesting.rb".freeze, "lib/rails_ops/mixins/param_authorization.rb".freeze, "lib/rails_ops/mixins/policies.rb".freeze, "lib/rails_ops/mixins/require_context.rb".freeze, "lib/rails_ops/mixins/routes.rb".freeze, "lib/rails_ops/mixins/schema_validation.rb".freeze, "lib/rails_ops/mixins/sub_ops.rb".freeze, "lib/rails_ops/model_mixins.rb".freeze, "lib/rails_ops/model_mixins/ar_extension.rb".freeze, "lib/rails_ops/model_mixins/marshalling.rb".freeze, "lib/rails_ops/model_mixins/parent_op.rb".freeze, "lib/rails_ops/model_mixins/sti_fixes.rb".freeze, "lib/rails_ops/model_mixins/virtual_attributes.rb".freeze, "lib/rails_ops/model_mixins/virtual_attributes/virtual_column_wrapper.rb".freeze, "lib/rails_ops/model_mixins/virtual_has_one.rb".freeze, "lib/rails_ops/model_mixins/virtual_model_name.rb".freeze, "lib/rails_ops/operation.rb".freeze, "lib/rails_ops/operation/model.rb".freeze, "lib/rails_ops/operation/model/create.rb".freeze, "lib/rails_ops/operation/model/destroy.rb".freeze, "lib/rails_ops/operation/model/load.rb".freeze, "lib/rails_ops/operation/model/update.rb".freeze, "lib/rails_ops/profiler.rb".freeze, "lib/rails_ops/profiler/node.rb".freeze, "lib/rails_ops/railtie.rb".freeze, "lib/rails_ops/scoped_env.rb".freeze, "lib/rails_ops/virtual_model.rb".freeze, "rails_ops.gemspec".freeze, "test/db/models.rb".freeze, "test/db/schema.rb".freeze, "test/dummy/Rakefile".freeze, "test/dummy/app/assets/config/manifest.js".freeze, "test/dummy/app/assets/images/.keep".freeze, "test/dummy/app/assets/javascripts/application.js".freeze, "test/dummy/app/assets/javascripts/cable.js".freeze, "test/dummy/app/assets/javascripts/channels/.keep".freeze, "test/dummy/app/assets/stylesheets/application.css".freeze, "test/dummy/app/channels/application_cable/channel.rb".freeze, "test/dummy/app/channels/application_cable/connection.rb".freeze, "test/dummy/app/controllers/application_controller.rb".freeze, "test/dummy/app/controllers/concerns/.keep".freeze, "test/dummy/app/helpers/application_helper.rb".freeze, "test/dummy/app/jobs/application_job.rb".freeze, "test/dummy/app/mailers/application_mailer.rb".freeze, "test/dummy/app/models/animal.rb".freeze, "test/dummy/app/models/application_record.rb".freeze, "test/dummy/app/models/bird.rb".freeze, "test/dummy/app/models/cat.rb".freeze, "test/dummy/app/models/concerns/.keep".freeze, "test/dummy/app/models/dog.rb".freeze, "test/dummy/app/models/flower.rb".freeze, "test/dummy/app/models/group.rb".freeze, "test/dummy/app/models/nightingale.rb".freeze, "test/dummy/app/models/phoenix.rb".freeze, "test/dummy/app/models/user.rb".freeze, "test/dummy/app/views/layouts/application.html.erb".freeze, "test/dummy/app/views/layouts/mailer.html.erb".freeze, "test/dummy/app/views/layouts/mailer.text.erb".freeze, "test/dummy/bin/bundle".freeze, "test/dummy/bin/rails".freeze, "test/dummy/bin/rake".freeze, "test/dummy/bin/setup".freeze, "test/dummy/bin/update".freeze, "test/dummy/bin/yarn".freeze, "test/dummy/config.ru".freeze, "test/dummy/config/application.rb".freeze, "test/dummy/config/boot.rb".freeze, "test/dummy/config/cable.yml".freeze, "test/dummy/config/database.yml".freeze, "test/dummy/config/environment.rb".freeze, "test/dummy/config/environments/development.rb".freeze, "test/dummy/config/environments/production.rb".freeze, "test/dummy/config/environments/test.rb".freeze, "test/dummy/config/initializers/application_controller_renderer.rb".freeze, "test/dummy/config/initializers/assets.rb".freeze, "test/dummy/config/initializers/backtrace_silencers.rb".freeze, "test/dummy/config/initializers/cookies_serializer.rb".freeze, "test/dummy/config/initializers/filter_parameter_logging.rb".freeze, "test/dummy/config/initializers/inflections.rb".freeze, "test/dummy/config/initializers/mime_types.rb".freeze, "test/dummy/config/initializers/rails_ops.rb".freeze, "test/dummy/config/initializers/wrap_parameters.rb".freeze, "test/dummy/config/locales/en.yml".freeze, "test/dummy/config/puma.rb".freeze, "test/dummy/config/routes.rb".freeze, "test/dummy/config/secrets.yml".freeze, "test/dummy/config/spring.rb".freeze, "test/dummy/db/schema.rb".freeze, "test/dummy/lib/assets/.keep".freeze, "test/dummy/log/.keep".freeze, "test/dummy/package.json".freeze, "test/dummy/public/404.html".freeze, "test/dummy/public/422.html".freeze, "test/dummy/public/500.html".freeze, "test/dummy/public/apple-touch-icon-precomposed.png".freeze, "test/dummy/public/apple-touch-icon.png".freeze, "test/dummy/public/favicon.ico".freeze, "test/dummy/tmp/.keep".freeze, "test/test_helper.rb".freeze, "test/unit/rails_ops/generators/operation_generator_test.rb".freeze, "test/unit/rails_ops/mixins/model/
|
13
|
-
s.rubygems_version = "3.3.
|
11
|
+
s.date = "2023-02-21"
|
12
|
+
s.files = [".github/workflows/rubocop.yml".freeze, ".github/workflows/ruby.yml".freeze, ".gitignore".freeze, ".releaser_config".freeze, ".rubocop.yml".freeze, "Appraisals".freeze, "CHANGELOG.md".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "gemfiles/rails_6.0.gemfile".freeze, "gemfiles/rails_6.1.gemfile".freeze, "gemfiles/rails_7.0.gemfile".freeze, "lib/generators/operation/USAGE".freeze, "lib/generators/operation/operation_generator.rb".freeze, "lib/generators/operation/templates/controller.erb".freeze, "lib/generators/operation/templates/create.erb".freeze, "lib/generators/operation/templates/destroy.erb".freeze, "lib/generators/operation/templates/load.erb".freeze, "lib/generators/operation/templates/update.erb".freeze, "lib/generators/operation/templates/view.erb".freeze, "lib/rails_ops.rb".freeze, "lib/rails_ops/authorization_backend/abstract.rb".freeze, "lib/rails_ops/authorization_backend/can_can_can.rb".freeze, "lib/rails_ops/configuration.rb".freeze, "lib/rails_ops/context.rb".freeze, "lib/rails_ops/controller_mixin.rb".freeze, "lib/rails_ops/exceptions.rb".freeze, "lib/rails_ops/hooked_job.rb".freeze, "lib/rails_ops/hookup.rb".freeze, "lib/rails_ops/hookup/dsl.rb".freeze, "lib/rails_ops/hookup/dsl_validator.rb".freeze, "lib/rails_ops/hookup/hook.rb".freeze, "lib/rails_ops/log_subscriber.rb".freeze, "lib/rails_ops/mixins.rb".freeze, "lib/rails_ops/mixins/authorization.rb".freeze, "lib/rails_ops/mixins/log_settings.rb".freeze, "lib/rails_ops/mixins/model.rb".freeze, "lib/rails_ops/mixins/model/authorization.rb".freeze, "lib/rails_ops/mixins/model/nesting.rb".freeze, "lib/rails_ops/mixins/param_authorization.rb".freeze, "lib/rails_ops/mixins/policies.rb".freeze, "lib/rails_ops/mixins/require_context.rb".freeze, "lib/rails_ops/mixins/routes.rb".freeze, "lib/rails_ops/mixins/schema_validation.rb".freeze, "lib/rails_ops/mixins/sub_ops.rb".freeze, "lib/rails_ops/model_mixins.rb".freeze, "lib/rails_ops/model_mixins/ar_extension.rb".freeze, "lib/rails_ops/model_mixins/marshalling.rb".freeze, "lib/rails_ops/model_mixins/parent_op.rb".freeze, "lib/rails_ops/model_mixins/sti_fixes.rb".freeze, "lib/rails_ops/model_mixins/virtual_attributes.rb".freeze, "lib/rails_ops/model_mixins/virtual_attributes/virtual_column_wrapper.rb".freeze, "lib/rails_ops/model_mixins/virtual_has_one.rb".freeze, "lib/rails_ops/model_mixins/virtual_model_name.rb".freeze, "lib/rails_ops/operation.rb".freeze, "lib/rails_ops/operation/model.rb".freeze, "lib/rails_ops/operation/model/create.rb".freeze, "lib/rails_ops/operation/model/destroy.rb".freeze, "lib/rails_ops/operation/model/load.rb".freeze, "lib/rails_ops/operation/model/update.rb".freeze, "lib/rails_ops/profiler.rb".freeze, "lib/rails_ops/profiler/node.rb".freeze, "lib/rails_ops/railtie.rb".freeze, "lib/rails_ops/scoped_env.rb".freeze, "lib/rails_ops/virtual_model.rb".freeze, "rails_ops.gemspec".freeze, "test/db/models.rb".freeze, "test/db/schema.rb".freeze, "test/dummy/Rakefile".freeze, "test/dummy/app/assets/config/manifest.js".freeze, "test/dummy/app/assets/images/.keep".freeze, "test/dummy/app/assets/javascripts/application.js".freeze, "test/dummy/app/assets/javascripts/cable.js".freeze, "test/dummy/app/assets/javascripts/channels/.keep".freeze, "test/dummy/app/assets/stylesheets/application.css".freeze, "test/dummy/app/channels/application_cable/channel.rb".freeze, "test/dummy/app/channels/application_cable/connection.rb".freeze, "test/dummy/app/controllers/application_controller.rb".freeze, "test/dummy/app/controllers/concerns/.keep".freeze, "test/dummy/app/helpers/application_helper.rb".freeze, "test/dummy/app/jobs/application_job.rb".freeze, "test/dummy/app/mailers/application_mailer.rb".freeze, "test/dummy/app/models/animal.rb".freeze, "test/dummy/app/models/application_record.rb".freeze, "test/dummy/app/models/bird.rb".freeze, "test/dummy/app/models/cat.rb".freeze, "test/dummy/app/models/computer.rb".freeze, "test/dummy/app/models/concerns/.keep".freeze, "test/dummy/app/models/cpu.rb".freeze, "test/dummy/app/models/dog.rb".freeze, "test/dummy/app/models/flower.rb".freeze, "test/dummy/app/models/group.rb".freeze, "test/dummy/app/models/mainboard.rb".freeze, "test/dummy/app/models/nightingale.rb".freeze, "test/dummy/app/models/phoenix.rb".freeze, "test/dummy/app/models/user.rb".freeze, "test/dummy/app/views/layouts/application.html.erb".freeze, "test/dummy/app/views/layouts/mailer.html.erb".freeze, "test/dummy/app/views/layouts/mailer.text.erb".freeze, "test/dummy/bin/bundle".freeze, "test/dummy/bin/rails".freeze, "test/dummy/bin/rake".freeze, "test/dummy/bin/setup".freeze, "test/dummy/bin/update".freeze, "test/dummy/bin/yarn".freeze, "test/dummy/config.ru".freeze, "test/dummy/config/application.rb".freeze, "test/dummy/config/boot.rb".freeze, "test/dummy/config/cable.yml".freeze, "test/dummy/config/database.yml".freeze, "test/dummy/config/environment.rb".freeze, "test/dummy/config/environments/development.rb".freeze, "test/dummy/config/environments/production.rb".freeze, "test/dummy/config/environments/test.rb".freeze, "test/dummy/config/initializers/application_controller_renderer.rb".freeze, "test/dummy/config/initializers/assets.rb".freeze, "test/dummy/config/initializers/backtrace_silencers.rb".freeze, "test/dummy/config/initializers/cookies_serializer.rb".freeze, "test/dummy/config/initializers/filter_parameter_logging.rb".freeze, "test/dummy/config/initializers/inflections.rb".freeze, "test/dummy/config/initializers/mime_types.rb".freeze, "test/dummy/config/initializers/rails_ops.rb".freeze, "test/dummy/config/initializers/wrap_parameters.rb".freeze, "test/dummy/config/locales/en.yml".freeze, "test/dummy/config/puma.rb".freeze, "test/dummy/config/routes.rb".freeze, "test/dummy/config/secrets.yml".freeze, "test/dummy/config/spring.rb".freeze, "test/dummy/db/schema.rb".freeze, "test/dummy/lib/assets/.keep".freeze, "test/dummy/log/.keep".freeze, "test/dummy/package.json".freeze, "test/dummy/public/404.html".freeze, "test/dummy/public/422.html".freeze, "test/dummy/public/500.html".freeze, "test/dummy/public/apple-touch-icon-precomposed.png".freeze, "test/dummy/public/apple-touch-icon.png".freeze, "test/dummy/public/favicon.ico".freeze, "test/dummy/tmp/.keep".freeze, "test/test_helper.rb".freeze, "test/unit/rails_ops/generators/operation_generator_test.rb".freeze, "test/unit/rails_ops/mixins/model/deep_nesting_test.rb".freeze, "test/unit/rails_ops/mixins/param_authorization_test.rb".freeze, "test/unit/rails_ops/mixins/policies_test.rb".freeze, "test/unit/rails_ops/operation/model/create_test.rb".freeze, "test/unit/rails_ops/operation/model/load_test.rb".freeze, "test/unit/rails_ops/operation/model/sti_test.rb".freeze, "test/unit/rails_ops/operation/model/update_test.rb".freeze, "test/unit/rails_ops/operation/model_test.rb".freeze, "test/unit/rails_ops/operation/update_auth_test.rb".freeze, "test/unit/rails_ops/operation/update_lazy_auth_test.rb".freeze, "test/unit/rails_ops/operation_test.rb".freeze]
|
13
|
+
s.rubygems_version = "3.3.20".freeze
|
14
14
|
s.summary = "An operations service layer for rails projects.".freeze
|
15
|
-
s.test_files = ["test/db/models.rb".freeze, "test/db/schema.rb".freeze, "test/dummy/Rakefile".freeze, "test/dummy/app/assets/config/manifest.js".freeze, "test/dummy/app/assets/images/.keep".freeze, "test/dummy/app/assets/javascripts/application.js".freeze, "test/dummy/app/assets/javascripts/cable.js".freeze, "test/dummy/app/assets/javascripts/channels/.keep".freeze, "test/dummy/app/assets/stylesheets/application.css".freeze, "test/dummy/app/channels/application_cable/channel.rb".freeze, "test/dummy/app/channels/application_cable/connection.rb".freeze, "test/dummy/app/controllers/application_controller.rb".freeze, "test/dummy/app/controllers/concerns/.keep".freeze, "test/dummy/app/helpers/application_helper.rb".freeze, "test/dummy/app/jobs/application_job.rb".freeze, "test/dummy/app/mailers/application_mailer.rb".freeze, "test/dummy/app/models/animal.rb".freeze, "test/dummy/app/models/application_record.rb".freeze, "test/dummy/app/models/bird.rb".freeze, "test/dummy/app/models/cat.rb".freeze, "test/dummy/app/models/concerns/.keep".freeze, "test/dummy/app/models/dog.rb".freeze, "test/dummy/app/models/flower.rb".freeze, "test/dummy/app/models/group.rb".freeze, "test/dummy/app/models/nightingale.rb".freeze, "test/dummy/app/models/phoenix.rb".freeze, "test/dummy/app/models/user.rb".freeze, "test/dummy/app/views/layouts/application.html.erb".freeze, "test/dummy/app/views/layouts/mailer.html.erb".freeze, "test/dummy/app/views/layouts/mailer.text.erb".freeze, "test/dummy/bin/bundle".freeze, "test/dummy/bin/rails".freeze, "test/dummy/bin/rake".freeze, "test/dummy/bin/setup".freeze, "test/dummy/bin/update".freeze, "test/dummy/bin/yarn".freeze, "test/dummy/config.ru".freeze, "test/dummy/config/application.rb".freeze, "test/dummy/config/boot.rb".freeze, "test/dummy/config/cable.yml".freeze, "test/dummy/config/database.yml".freeze, "test/dummy/config/environment.rb".freeze, "test/dummy/config/environments/development.rb".freeze, "test/dummy/config/environments/production.rb".freeze, "test/dummy/config/environments/test.rb".freeze, "test/dummy/config/initializers/application_controller_renderer.rb".freeze, "test/dummy/config/initializers/assets.rb".freeze, "test/dummy/config/initializers/backtrace_silencers.rb".freeze, "test/dummy/config/initializers/cookies_serializer.rb".freeze, "test/dummy/config/initializers/filter_parameter_logging.rb".freeze, "test/dummy/config/initializers/inflections.rb".freeze, "test/dummy/config/initializers/mime_types.rb".freeze, "test/dummy/config/initializers/rails_ops.rb".freeze, "test/dummy/config/initializers/wrap_parameters.rb".freeze, "test/dummy/config/locales/en.yml".freeze, "test/dummy/config/puma.rb".freeze, "test/dummy/config/routes.rb".freeze, "test/dummy/config/secrets.yml".freeze, "test/dummy/config/spring.rb".freeze, "test/dummy/db/schema.rb".freeze, "test/dummy/lib/assets/.keep".freeze, "test/dummy/log/.keep".freeze, "test/dummy/package.json".freeze, "test/dummy/public/404.html".freeze, "test/dummy/public/422.html".freeze, "test/dummy/public/500.html".freeze, "test/dummy/public/apple-touch-icon-precomposed.png".freeze, "test/dummy/public/apple-touch-icon.png".freeze, "test/dummy/public/favicon.ico".freeze, "test/dummy/tmp/.keep".freeze, "test/test_helper.rb".freeze, "test/unit/rails_ops/generators/operation_generator_test.rb".freeze, "test/unit/rails_ops/mixins/model/
|
15
|
+
s.test_files = ["test/db/models.rb".freeze, "test/db/schema.rb".freeze, "test/dummy/Rakefile".freeze, "test/dummy/app/assets/config/manifest.js".freeze, "test/dummy/app/assets/images/.keep".freeze, "test/dummy/app/assets/javascripts/application.js".freeze, "test/dummy/app/assets/javascripts/cable.js".freeze, "test/dummy/app/assets/javascripts/channels/.keep".freeze, "test/dummy/app/assets/stylesheets/application.css".freeze, "test/dummy/app/channels/application_cable/channel.rb".freeze, "test/dummy/app/channels/application_cable/connection.rb".freeze, "test/dummy/app/controllers/application_controller.rb".freeze, "test/dummy/app/controllers/concerns/.keep".freeze, "test/dummy/app/helpers/application_helper.rb".freeze, "test/dummy/app/jobs/application_job.rb".freeze, "test/dummy/app/mailers/application_mailer.rb".freeze, "test/dummy/app/models/animal.rb".freeze, "test/dummy/app/models/application_record.rb".freeze, "test/dummy/app/models/bird.rb".freeze, "test/dummy/app/models/cat.rb".freeze, "test/dummy/app/models/computer.rb".freeze, "test/dummy/app/models/concerns/.keep".freeze, "test/dummy/app/models/cpu.rb".freeze, "test/dummy/app/models/dog.rb".freeze, "test/dummy/app/models/flower.rb".freeze, "test/dummy/app/models/group.rb".freeze, "test/dummy/app/models/mainboard.rb".freeze, "test/dummy/app/models/nightingale.rb".freeze, "test/dummy/app/models/phoenix.rb".freeze, "test/dummy/app/models/user.rb".freeze, "test/dummy/app/views/layouts/application.html.erb".freeze, "test/dummy/app/views/layouts/mailer.html.erb".freeze, "test/dummy/app/views/layouts/mailer.text.erb".freeze, "test/dummy/bin/bundle".freeze, "test/dummy/bin/rails".freeze, "test/dummy/bin/rake".freeze, "test/dummy/bin/setup".freeze, "test/dummy/bin/update".freeze, "test/dummy/bin/yarn".freeze, "test/dummy/config.ru".freeze, "test/dummy/config/application.rb".freeze, "test/dummy/config/boot.rb".freeze, "test/dummy/config/cable.yml".freeze, "test/dummy/config/database.yml".freeze, "test/dummy/config/environment.rb".freeze, "test/dummy/config/environments/development.rb".freeze, "test/dummy/config/environments/production.rb".freeze, "test/dummy/config/environments/test.rb".freeze, "test/dummy/config/initializers/application_controller_renderer.rb".freeze, "test/dummy/config/initializers/assets.rb".freeze, "test/dummy/config/initializers/backtrace_silencers.rb".freeze, "test/dummy/config/initializers/cookies_serializer.rb".freeze, "test/dummy/config/initializers/filter_parameter_logging.rb".freeze, "test/dummy/config/initializers/inflections.rb".freeze, "test/dummy/config/initializers/mime_types.rb".freeze, "test/dummy/config/initializers/rails_ops.rb".freeze, "test/dummy/config/initializers/wrap_parameters.rb".freeze, "test/dummy/config/locales/en.yml".freeze, "test/dummy/config/puma.rb".freeze, "test/dummy/config/routes.rb".freeze, "test/dummy/config/secrets.yml".freeze, "test/dummy/config/spring.rb".freeze, "test/dummy/db/schema.rb".freeze, "test/dummy/lib/assets/.keep".freeze, "test/dummy/log/.keep".freeze, "test/dummy/package.json".freeze, "test/dummy/public/404.html".freeze, "test/dummy/public/422.html".freeze, "test/dummy/public/500.html".freeze, "test/dummy/public/apple-touch-icon-precomposed.png".freeze, "test/dummy/public/apple-touch-icon.png".freeze, "test/dummy/public/favicon.ico".freeze, "test/dummy/tmp/.keep".freeze, "test/test_helper.rb".freeze, "test/unit/rails_ops/generators/operation_generator_test.rb".freeze, "test/unit/rails_ops/mixins/model/deep_nesting_test.rb".freeze, "test/unit/rails_ops/mixins/param_authorization_test.rb".freeze, "test/unit/rails_ops/mixins/policies_test.rb".freeze, "test/unit/rails_ops/operation/model/create_test.rb".freeze, "test/unit/rails_ops/operation/model/load_test.rb".freeze, "test/unit/rails_ops/operation/model/sti_test.rb".freeze, "test/unit/rails_ops/operation/model/update_test.rb".freeze, "test/unit/rails_ops/operation/model_test.rb".freeze, "test/unit/rails_ops/operation/update_auth_test.rb".freeze, "test/unit/rails_ops/operation/update_lazy_auth_test.rb".freeze, "test/unit/rails_ops/operation_test.rb".freeze]
|
16
16
|
|
17
17
|
if s.respond_to? :specification_version then
|
18
18
|
s.specification_version = 4
|
data/test/dummy/db/schema.rb
CHANGED
@@ -14,4 +14,18 @@ ActiveRecord::Schema.define do
|
|
14
14
|
create_table :flowers, force: true do |t|
|
15
15
|
t.boolean :planted, null: false, default: true
|
16
16
|
end
|
17
|
+
|
18
|
+
create_table :computers, force: true do |t|
|
19
|
+
t.string :name
|
20
|
+
t.references :mainboard
|
21
|
+
end
|
22
|
+
|
23
|
+
create_table :mainboards, force: true do |t|
|
24
|
+
t.string :name
|
25
|
+
t.references :cpu
|
26
|
+
end
|
27
|
+
|
28
|
+
create_table :cpus, force: true do |t|
|
29
|
+
t.string :name
|
30
|
+
end
|
17
31
|
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class RailsOps::Mixins::Model::DeepNestingTest < ActiveSupport::TestCase
|
4
|
+
include TestHelper
|
5
|
+
|
6
|
+
CPU_CREATION_OP = Class.new(RailsOps::Operation::Model::Create) do
|
7
|
+
model Cpu do
|
8
|
+
validates :name, presence: true
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
MAINBOARD_CREATION_OP = Class.new(RailsOps::Operation::Model::Create) do
|
13
|
+
model Mainboard do
|
14
|
+
validates :name, presence: true
|
15
|
+
end
|
16
|
+
|
17
|
+
nest_model_op :cpu, CPU_CREATION_OP
|
18
|
+
end
|
19
|
+
|
20
|
+
COMPUTER_CREATION_OP = Class.new(RailsOps::Operation::Model::Create) do
|
21
|
+
model Computer do
|
22
|
+
validates :name, presence: true
|
23
|
+
end
|
24
|
+
|
25
|
+
nest_model_op :mainboard, MAINBOARD_CREATION_OP
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_create_cpu
|
29
|
+
assert_nothing_raised do
|
30
|
+
CPU_CREATION_OP.run!(cpu: { name: 'CPU' })
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_create_mainboard
|
35
|
+
assert_nothing_raised do
|
36
|
+
MAINBOARD_CREATION_OP.run!(
|
37
|
+
mainboard: {
|
38
|
+
name: 'Mainboard',
|
39
|
+
cpu_attributes: {
|
40
|
+
name: 'CPU'
|
41
|
+
}
|
42
|
+
}
|
43
|
+
)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_create_computer_success
|
48
|
+
model = assert_nothing_raised do
|
49
|
+
COMPUTER_CREATION_OP.run!(
|
50
|
+
computer: {
|
51
|
+
name: 'Computer',
|
52
|
+
|
53
|
+
mainboard_attributes: {
|
54
|
+
name: 'Mainboard',
|
55
|
+
|
56
|
+
cpu_attributes: {
|
57
|
+
name: 'CPU'
|
58
|
+
}
|
59
|
+
}
|
60
|
+
}
|
61
|
+
).model
|
62
|
+
end
|
63
|
+
|
64
|
+
assert 'Computer', model.persisted?
|
65
|
+
assert 'Mainboard', model.mainboard.persisted?
|
66
|
+
assert 'CPU', model.mainboard.cpu.persisted?
|
67
|
+
|
68
|
+
assert_equal 'Computer', model.name
|
69
|
+
assert_equal 'Mainboard', model.mainboard.name
|
70
|
+
assert_equal 'CPU', model.mainboard.cpu.name
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_create_computer_level_1_validation_error
|
74
|
+
op = COMPUTER_CREATION_OP.new(
|
75
|
+
computer: {
|
76
|
+
mainboard_attributes: {
|
77
|
+
name: 'Mainboard',
|
78
|
+
|
79
|
+
cpu_attributes: {
|
80
|
+
name: 'CPU'
|
81
|
+
}
|
82
|
+
}
|
83
|
+
}
|
84
|
+
)
|
85
|
+
|
86
|
+
assert_raises_with_message ActiveRecord::RecordInvalid, /Name can't be blank/ do
|
87
|
+
op.run!
|
88
|
+
end
|
89
|
+
|
90
|
+
assert_equal ["Name can't be blank"], op.model.errors.full_messages
|
91
|
+
refute op.model.persisted?
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_create_computer_level_2_validation_error
|
95
|
+
op = COMPUTER_CREATION_OP.new(
|
96
|
+
computer: {
|
97
|
+
name: 'Computer',
|
98
|
+
|
99
|
+
mainboard_attributes: {
|
100
|
+
cpu_attributes: {
|
101
|
+
name: 'CPU'
|
102
|
+
}
|
103
|
+
}
|
104
|
+
}
|
105
|
+
)
|
106
|
+
|
107
|
+
assert_raises_with_message ActiveRecord::RecordInvalid, /Mainboard is invalid/ do
|
108
|
+
op.run!
|
109
|
+
end
|
110
|
+
|
111
|
+
assert_equal ["Mainboard is invalid"], op.model.errors.full_messages
|
112
|
+
refute op.model.persisted?
|
113
|
+
|
114
|
+
assert_equal ["Name can't be blank"], op.model.mainboard.errors.full_messages
|
115
|
+
refute op.model.mainboard.persisted?
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_create_computer_level_3_validation_error
|
119
|
+
op = COMPUTER_CREATION_OP.new(
|
120
|
+
computer: {
|
121
|
+
name: 'Computer',
|
122
|
+
|
123
|
+
mainboard_attributes: {
|
124
|
+
name: 'Mainboard',
|
125
|
+
|
126
|
+
cpu_attributes: {}
|
127
|
+
}
|
128
|
+
}
|
129
|
+
)
|
130
|
+
|
131
|
+
assert_raises_with_message ActiveRecord::RecordInvalid, /Mainboard is invalid/ do
|
132
|
+
op.run!
|
133
|
+
end
|
134
|
+
|
135
|
+
assert_equal ["Mainboard is invalid"], op.model.errors.full_messages
|
136
|
+
refute op.model.persisted?
|
137
|
+
|
138
|
+
assert_equal ["Cpu is invalid"], op.model.mainboard.errors.full_messages
|
139
|
+
refute op.model.mainboard.persisted?
|
140
|
+
|
141
|
+
assert_equal ["Name can't be blank"], op.model.mainboard.cpu.errors.full_messages
|
142
|
+
refute op.model.mainboard.cpu.persisted?
|
143
|
+
end
|
144
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails_ops
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sitrox
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-02-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: appraisal
|
@@ -212,8 +212,8 @@ dependencies:
|
|
212
212
|
- - "<="
|
213
213
|
- !ruby/object:Gem::Version
|
214
214
|
version: '3.1'
|
215
|
-
description:
|
216
|
-
email:
|
215
|
+
description:
|
216
|
+
email:
|
217
217
|
executables: []
|
218
218
|
extensions: []
|
219
219
|
extra_rdoc_files: []
|
@@ -307,10 +307,13 @@ files:
|
|
307
307
|
- test/dummy/app/models/application_record.rb
|
308
308
|
- test/dummy/app/models/bird.rb
|
309
309
|
- test/dummy/app/models/cat.rb
|
310
|
+
- test/dummy/app/models/computer.rb
|
310
311
|
- test/dummy/app/models/concerns/.keep
|
312
|
+
- test/dummy/app/models/cpu.rb
|
311
313
|
- test/dummy/app/models/dog.rb
|
312
314
|
- test/dummy/app/models/flower.rb
|
313
315
|
- test/dummy/app/models/group.rb
|
316
|
+
- test/dummy/app/models/mainboard.rb
|
314
317
|
- test/dummy/app/models/nightingale.rb
|
315
318
|
- test/dummy/app/models/phoenix.rb
|
316
319
|
- test/dummy/app/models/user.rb
|
@@ -359,7 +362,7 @@ files:
|
|
359
362
|
- test/dummy/tmp/.keep
|
360
363
|
- test/test_helper.rb
|
361
364
|
- test/unit/rails_ops/generators/operation_generator_test.rb
|
362
|
-
- test/unit/rails_ops/mixins/model/
|
365
|
+
- test/unit/rails_ops/mixins/model/deep_nesting_test.rb
|
363
366
|
- test/unit/rails_ops/mixins/param_authorization_test.rb
|
364
367
|
- test/unit/rails_ops/mixins/policies_test.rb
|
365
368
|
- test/unit/rails_ops/operation/model/create_test.rb
|
@@ -370,10 +373,10 @@ files:
|
|
370
373
|
- test/unit/rails_ops/operation/update_auth_test.rb
|
371
374
|
- test/unit/rails_ops/operation/update_lazy_auth_test.rb
|
372
375
|
- test/unit/rails_ops/operation_test.rb
|
373
|
-
homepage:
|
376
|
+
homepage:
|
374
377
|
licenses: []
|
375
378
|
metadata: {}
|
376
|
-
post_install_message:
|
379
|
+
post_install_message:
|
377
380
|
rdoc_options: []
|
378
381
|
require_paths:
|
379
382
|
- lib
|
@@ -388,8 +391,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
388
391
|
- !ruby/object:Gem::Version
|
389
392
|
version: '0'
|
390
393
|
requirements: []
|
391
|
-
rubygems_version: 3.3.
|
392
|
-
signing_key:
|
394
|
+
rubygems_version: 3.0.3.1
|
395
|
+
signing_key:
|
393
396
|
specification_version: 4
|
394
397
|
summary: An operations service layer for rails projects.
|
395
398
|
test_files:
|
@@ -413,10 +416,13 @@ test_files:
|
|
413
416
|
- test/dummy/app/models/application_record.rb
|
414
417
|
- test/dummy/app/models/bird.rb
|
415
418
|
- test/dummy/app/models/cat.rb
|
419
|
+
- test/dummy/app/models/computer.rb
|
416
420
|
- test/dummy/app/models/concerns/.keep
|
421
|
+
- test/dummy/app/models/cpu.rb
|
417
422
|
- test/dummy/app/models/dog.rb
|
418
423
|
- test/dummy/app/models/flower.rb
|
419
424
|
- test/dummy/app/models/group.rb
|
425
|
+
- test/dummy/app/models/mainboard.rb
|
420
426
|
- test/dummy/app/models/nightingale.rb
|
421
427
|
- test/dummy/app/models/phoenix.rb
|
422
428
|
- test/dummy/app/models/user.rb
|
@@ -465,7 +471,7 @@ test_files:
|
|
465
471
|
- test/dummy/tmp/.keep
|
466
472
|
- test/test_helper.rb
|
467
473
|
- test/unit/rails_ops/generators/operation_generator_test.rb
|
468
|
-
- test/unit/rails_ops/mixins/model/
|
474
|
+
- test/unit/rails_ops/mixins/model/deep_nesting_test.rb
|
469
475
|
- test/unit/rails_ops/mixins/param_authorization_test.rb
|
470
476
|
- test/unit/rails_ops/mixins/policies_test.rb
|
471
477
|
- test/unit/rails_ops/operation/model/create_test.rb
|
@@ -1,60 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class RailsOps::Mixins::Model::NestingTest < ActiveSupport::TestCase
|
4
|
-
include TestHelper
|
5
|
-
|
6
|
-
GROUP_CREATION_OP = Class.new RailsOps::Operation::Model::Create do
|
7
|
-
model Group do
|
8
|
-
validates :name, presence: true
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
BASIC_OP = Class.new RailsOps::Operation::Model::Create do
|
13
|
-
model User do
|
14
|
-
end
|
15
|
-
nest_model_op :group, GROUP_CREATION_OP
|
16
|
-
end
|
17
|
-
|
18
|
-
def test_has_many_basic
|
19
|
-
BASIC_OP.run!(
|
20
|
-
user: {
|
21
|
-
name: 'test',
|
22
|
-
group_attributes: {
|
23
|
-
name: 'g1',
|
24
|
-
color: 'blue'
|
25
|
-
}
|
26
|
-
}
|
27
|
-
)
|
28
|
-
|
29
|
-
assert_equal 1, User.count
|
30
|
-
assert_equal 1, Group.count
|
31
|
-
assert_equal 'test', User.first.name
|
32
|
-
assert_equal 'g1', Group.first.name
|
33
|
-
assert_equal Group.first, User.first.group
|
34
|
-
assert_equal [User.first], Group.first.users
|
35
|
-
end
|
36
|
-
|
37
|
-
def test_has_many_validation
|
38
|
-
op = BASIC_OP.new(
|
39
|
-
user: {
|
40
|
-
name: 'test',
|
41
|
-
group_attributes: {
|
42
|
-
color: 'blue'
|
43
|
-
}
|
44
|
-
}
|
45
|
-
)
|
46
|
-
|
47
|
-
assert_raises ActiveRecord::RecordInvalid do
|
48
|
-
op.run!
|
49
|
-
end
|
50
|
-
|
51
|
-
refute op.model.persisted?
|
52
|
-
refute op.model.group.persisted?
|
53
|
-
|
54
|
-
assert_equal BASIC_OP.model, op.model.class
|
55
|
-
assert_equal GROUP_CREATION_OP.model, op.model.group.class
|
56
|
-
|
57
|
-
refute op.model.group.valid?
|
58
|
-
refute op.model.valid?
|
59
|
-
end
|
60
|
-
end
|