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