rails_ops 1.8.2 → 1.9.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 301c49356e3189c3b035d90a9f8bca818b7003172946dd38e90a7f7d68da427e
4
- data.tar.gz: c8ee69f479cac87ee07a0fa3092db8a8c483681ee4e9bf8398b53f3bb6d48b26
3
+ metadata.gz: 0c45ee8525313c9bd2035a362ade85b51cb5b1d5a12490c3e5355108ae5d7428
4
+ data.tar.gz: 5ce037afb30623876a0edd17be4b32b6955bbc35a6e663da4443c1ec8d7e9dab
5
5
  SHA512:
6
- metadata.gz: 53bf09063fb79dc55679975232efbb0e76200b63b1a9573d15e8430e155812c07f4ef17b6664e31a62a54c7f1daa37b281f57edd62d3b4d2b7e57930084a45ba
7
- data.tar.gz: 5d419519712e506956ad28a53dea7b273f3d2998bb6e5b9cb56f36ed275cd707a278afe49713451afb1a3fcb56371991b944be4c3f0da462c43daeb1ca59ce8e
6
+ metadata.gz: a1d5f2b22eae2450b4e8e97a0eef68a2b1574557ca0c8613819b1319bdfb4236741e4b0b8db30ceab5b1e4fc1cded39a87268aeec623f9d2a5cf83b9ac488a17
7
+ data.tar.gz: 4da33315cd69df69eee5c68048942e44a302652d139d371aac380f48b566f10817acb0fc9f3ec7a9dd095c12b80731757bff1cf29499e5abf9529295dccc81bf
data/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.9.0 (2026-10-29)
4
+
5
+ * Lock models at build again. Since 1.5.5, `Load`, `Update` and `Destroy`
6
+ operations loaded their model without a lock unless the operation itself
7
+ called `lock_model_at_build`; the global setting
8
+ `RailsOps.config.lock_models_at_build`, which defaults to `true`, had no
9
+ effect.
10
+
11
+ This is a minor release because operations now take row locks they have
12
+ not taken for a long time. Look out for new lock waits or deadlocks after
13
+ upgrading, especially where an operation first inserts a row that refers
14
+ to a record through a foreign key and then updates that record. Turn
15
+ locking off per operation with `lock_model_at_build false`, or for the
16
+ whole application with `config.lock_models_at_build = false`.
17
+
3
18
  ## 1.8.2 (2026-09-09)
4
19
 
5
20
  * Relax the `schemacop` requirement from `>= 3.0.0`, `<= 3.1` to `>= 3.0.0`,
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rails_ops (1.8.2)
4
+ rails_ops (1.9.0)
5
5
  active_type (>= 1.3.0)
6
6
  minitest
7
7
  rails (> 4)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.8.2
1
+ 1.9.0
@@ -45,7 +45,7 @@ class RailsOps::Operation::Model::Load < RailsOps::Operation::Model
45
45
  end
46
46
 
47
47
  def lock_model_at_build?
48
- self.class._lock_model_at_build?
48
+ self.class.lock_model_at_build?
49
49
  end
50
50
 
51
51
  # Method to set the lock mode, which can either be :exclusive to use
data/rails_ops.gemspec CHANGED
@@ -1,14 +1,14 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: rails_ops 1.8.2 ruby lib
2
+ # stub: rails_ops 1.9.0 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "rails_ops".freeze
6
- s.version = "1.8.2"
6
+ s.version = "1.9.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 = "2026-09-09"
11
+ s.date = "2026-10-29"
12
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, "CLAUDE.md".freeze, "Gemfile".freeze, "Gemfile.lock".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, "gemfiles/rails_7.1.gemfile".freeze, "gemfiles/rails_7.2.gemfile".freeze, "gemfiles/rails_8.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/controller_wrapper.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/controllers/group_controller.rb".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/ability.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/hookup.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/hookup_test.rb".freeze, "test/unit/rails_ops/mixins/controller_test.rb".freeze, "test/unit/rails_ops/mixins/model/deep_nesting_test.rb".freeze, "test/unit/rails_ops/mixins/model/marshalling_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/auth_test.rb".freeze, "test/unit/rails_ops/operation/model/create_test.rb".freeze, "test/unit/rails_ops/operation/model/destroy_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_lazy_auth_test.rb".freeze, "test/unit/rails_ops/operation_test.rb".freeze, "test/unit/rails_ops/profiler_test.rb".freeze, "test/unit/rails_ops/railtie_test.rb".freeze]
13
13
  s.homepage = "https://github.com/sitrox/rails_ops".freeze
14
14
  s.licenses = ["MIT".freeze]
@@ -139,4 +139,39 @@ class RailsOps::Operation::Model::LoadTest < ActiveSupport::TestCase
139
139
  assert op.model.class < Group
140
140
  assert_not_equal Group, op.model.class
141
141
  end
142
+
143
+ def test_lock_model_at_build_follows_global_config
144
+ g = Group.create
145
+ op = BASIC_OP.new(id: g.id)
146
+
147
+ assert op.lock_model_at_build?
148
+ assert op.send(:lock_relation, Group.all).lock_value
149
+
150
+ with_lock_models_at_build(false) do
151
+ assert_not op.lock_model_at_build?
152
+ assert_not op.send(:lock_relation, Group.all).lock_value
153
+ end
154
+ end
155
+
156
+ def test_lock_model_at_build_per_operation_overrides_global_config
157
+ g = Group.create
158
+ disabled = Class.new(BASIC_OP) { lock_model_at_build false }
159
+ enabled = Class.new(BASIC_OP) { lock_model_at_build }
160
+
161
+ assert_not disabled.new(id: g.id).lock_model_at_build?
162
+
163
+ with_lock_models_at_build(false) do
164
+ assert enabled.new(id: g.id).lock_model_at_build?
165
+ end
166
+ end
167
+
168
+ private
169
+
170
+ def with_lock_models_at_build(value)
171
+ previous = RailsOps.config.lock_models_at_build
172
+ RailsOps.config.lock_models_at_build = value
173
+ yield
174
+ ensure
175
+ RailsOps.config.lock_models_at_build = previous
176
+ end
142
177
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_ops
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.2
4
+ version: 1.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sitrox
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-09-09 00:00:00.000000000 Z
10
+ date: 2026-10-29 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: active_type
@@ -277,7 +277,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
277
277
  - !ruby/object:Gem::Version
278
278
  version: '0'
279
279
  requirements: []
280
- rubygems_version: 4.0.8
280
+ rubygems_version: 3.6.9
281
281
  specification_version: 4
282
282
  summary: An operations service layer for rails projects.
283
283
  test_files: