rails_ops 1.7.6 → 1.7.7

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: 3cbedc7c32b0c2426655e10cc0976a0156d7558fc7ddf60e12a04a554ebd3955
4
- data.tar.gz: 06e926c30fb1b8228eb6f818910392ef9d0509fd610e16effca49f0f49d8389a
3
+ metadata.gz: dcc75b6ab31d484ef579cb73510e759c4b5f85074a491954b991648e9c9d678a
4
+ data.tar.gz: 6c1b1fec40de9cc92ac28b417acd33cc7ca9a61d936a3ecef9b9131758005cd2
5
5
  SHA512:
6
- metadata.gz: cdc2260ce72809585f7bd5b68311d84e9342afdc27dee51f5fb402e9431285a166d9610bc5479f6b5e0837f1c7ec1638da58002e28a912ab4e89447b81da668c
7
- data.tar.gz: 580e14d0f3aa76014e806e64efbb575f9f8287dcbf0460fe4d3ae3baed162e7b0d1e444d3d2e21fc4c88dad1cc169cb8cff5bb7c1393428201255a35e49637fd
6
+ metadata.gz: 369d58ccd929715e12b62cea2b38e42bd629accf5f1b1ed7c00bd9b4e8e58eb947b999c7410959262c647052faac33c3ae84cf502cf1d724954c3e8c51189690
7
+ data.tar.gz: 7eddc5780ab3daa372af54140b03d7c80d51d6bb2465b6022e3b1eb4a605af11e97b47f9a681be79fe8c12b8f60e0abc87eee42cda5e86dd51e2885a3efaadc5
@@ -11,7 +11,7 @@ jobs:
11
11
  - name: Set up Ruby
12
12
  uses: ruby/setup-ruby@v1
13
13
  with:
14
- ruby-version: 3.1.0
14
+ ruby-version: 3.2.0
15
15
  bundler-cache: true
16
16
  - name: Run rubocop
17
17
  run: bundle exec rubocop
data/CHANGELOG.md CHANGED
@@ -1,14 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.7.7 (2026-02-24)
4
+
5
+ * Fix `find_model_relation` to merge the returned relation's conditions
6
+ into the operation's model class. Previously, overriding the method
7
+ with a relation on the base class (e.g. `User.where(...)`) would
8
+ bypass model extensions defined via `model do ... end`. The loaded
9
+ record is now always an instance of the correct (possibly extended)
10
+ model type.
11
+
3
12
  ## 1.7.6 (2026-02-24)
4
13
 
5
14
  * Add `find_model_relation` hook to `RailsOps::Operation::Model::Load`.
6
15
  This protected method can be overridden in subclasses to customize the
7
16
  relation used for looking up the model, e.g. to apply scopes or use a
8
17
  different base query. Since `Update` and `Destroy` inherit from `Load`,
9
- the hook is available in all model operations that load a record. The
10
- default implementation returns `self.class.model`, preserving existing
11
- behavior.
18
+ the hook is available in all model operations that load a record.
12
19
 
13
20
  ## 1.7.5 (2026-02-18)
14
21
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rails_ops (1.7.6)
4
+ rails_ops (1.7.7)
5
5
  active_type (>= 1.3.0)
6
6
  minitest
7
7
  rails (> 4)
data/README.md CHANGED
@@ -1169,15 +1169,21 @@ end
1169
1169
 
1170
1170
  #### Customizing the Lookup Relation
1171
1171
 
1172
- By default, `Load` operations look up the model using the relation returned
1173
- by `self.class.model` (i.e. the model class itself). If you need to use a
1174
- custom relation — for example to apply a scope, join additional tables, or
1175
- restrict visibility — you can override the `protected` method
1176
- `find_model_relation`.
1172
+ By default, `Load` operations look up the model using the class specified
1173
+ via the `model` DSL method. If you need to customize the lookup — for
1174
+ example to apply a scope, join additional tables, or restrict visibility
1175
+ — you can override the `protected` method `find_model_relation`.
1177
1176
 
1178
- Since `Update` and `Destroy` operations inherit from `Load`, this hook is
1179
- available in all of them. For example, you can scope an `Update` operation
1180
- so that it only finds records belonging to the current user's organization:
1177
+ The conditions from the returned relation are **merged** into the
1178
+ operation's model class, so the loaded record is always an instance of
1179
+ the correct (possibly extended) model type. This means model extensions
1180
+ defined via `model do ... end` (e.g. validations, callbacks) are always
1181
+ preserved.
1182
+
1183
+ Since `Update` and `Destroy` operations inherit from `Load`, this hook
1184
+ is available in all of them. For example, you can scope an `Update`
1185
+ operation so that it only finds records belonging to the current user's
1186
+ organization:
1181
1187
 
1182
1188
  ```ruby
1183
1189
  class Operations::User::Update < RailsOps::Operation::Model::Update
@@ -1191,9 +1197,8 @@ class Operations::User::Update < RailsOps::Operation::Model::Update
1191
1197
  end
1192
1198
  ```
1193
1199
 
1194
- The returned object must be an ActiveRecord relation (or the model class
1195
- itself, which acts as one). Locking and eager loading via `model_includes`
1196
- are applied on top of whatever relation this method returns.
1200
+ Locking and eager loading via `model_includes` are applied on top of
1201
+ the merged relation.
1197
1202
 
1198
1203
  #### Locking
1199
1204
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.7.6
1
+ 1.7.7
@@ -79,8 +79,10 @@ class RailsOps::Operation::Model::Load < RailsOps::Operation::Model
79
79
  fail "Param #{model_id_field.inspect} must be given."
80
80
  end
81
81
 
82
- # Obtain relation
83
- relation = find_model_relation
82
+ # Obtain relation, always starting from the operation's model class
83
+ # to ensure the loaded record is of the correct (possibly extended)
84
+ # type, then merge in any custom conditions from find_model_relation.
85
+ relation = self.class.model.all.merge(find_model_relation)
84
86
 
85
87
  # Express intention to lock if required
86
88
  relation = lock_relation(relation)
@@ -112,23 +114,25 @@ class RailsOps::Operation::Model::Load < RailsOps::Operation::Model
112
114
 
113
115
  protected
114
116
 
115
- # Returns the base relation used by {#find_model} to look up the model
116
- # record. Override this method in subclasses to customize the lookup
117
- # relation, e.g. to apply scopes or restrict visibility.
117
+ # Returns a relation whose conditions are merged into the operation's
118
+ # model class when looking up the record. Override this method in
119
+ # subclasses to customize the lookup, e.g. to apply scopes or
120
+ # restrict visibility.
118
121
  #
119
- # The returned object must respond to `find_by!` (i.e. be an
120
- # `ActiveRecord::Relation` or the model class itself). Locking and
121
- # eager loading via {.model_includes} are applied on top of this
122
- # relation.
122
+ # The conditions from this relation are merged onto
123
+ # `self.class.model`, so the loaded record is always an instance of
124
+ # the operation's (possibly extended) model class. This means model
125
+ # extensions defined via `model do ... end` are preserved.
123
126
  #
124
- # @return [ActiveRecord::Relation] the relation to query against
127
+ # @return [ActiveRecord::Relation] the relation whose conditions are
128
+ # merged into the model class
125
129
  #
126
130
  # @example Scoping to the current user's organization
127
131
  # def find_model_relation
128
132
  # User.where(organization: context.user.organization)
129
133
  # end
130
134
  def find_model_relation
131
- self.class.model
135
+ self.class.model.all
132
136
  end
133
137
 
134
138
  private
data/rails_ops.gemspec CHANGED
@@ -1,9 +1,9 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: rails_ops 1.7.6 ruby lib
2
+ # stub: rails_ops 1.7.7 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "rails_ops".freeze
6
- s.version = "1.7.6"
6
+ s.version = "1.7.7"
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]
@@ -1,2 +1,3 @@
1
1
  class Group < ApplicationRecord
2
+ has_many :users
2
3
  end
@@ -15,6 +15,11 @@ ActiveRecord::Schema.define do
15
15
  t.boolean :planted, null: false, default: true
16
16
  end
17
17
 
18
+ create_table :users, force: true do |t|
19
+ t.string :name
20
+ t.references :group
21
+ end
22
+
18
23
  create_table :computers, force: true do |t|
19
24
  t.string :name
20
25
  t.references :mainboard
@@ -74,7 +74,7 @@ class RailsOps::Operation::Model::LoadTest < ActiveSupport::TestCase
74
74
  assert_equal g, op.model
75
75
  end
76
76
 
77
- def test_find_model_relation_override
77
+ def test_find_model_relation_with_where
78
78
  g1 = Group.create(name: 'visible')
79
79
  g2 = Group.create(name: 'hidden')
80
80
 
@@ -94,4 +94,49 @@ class RailsOps::Operation::Model::LoadTest < ActiveSupport::TestCase
94
94
  cls.new(id: g2.id)
95
95
  end
96
96
  end
97
+
98
+ def test_find_model_relation_with_joins
99
+ g1 = Group.create(name: 'with_users')
100
+ g2 = Group.create(name: 'empty')
101
+ User.create(name: 'Alice', group: g1)
102
+
103
+ cls = Class.new(RailsOps::Operation::Model::Load) do
104
+ model Group
105
+
106
+ protected
107
+
108
+ def find_model_relation
109
+ Group.joins(:users).where(users: { name: 'Alice' })
110
+ end
111
+ end
112
+
113
+ assert_equal g1, cls.new(id: g1.id).model
114
+
115
+ assert_raise ActiveRecord::RecordNotFound do
116
+ cls.new(id: g2.id)
117
+ end
118
+ end
119
+
120
+ def test_find_model_relation_preserves_model_extensions
121
+ g = Group.create(name: 'test')
122
+
123
+ cls = Class.new(RailsOps::Operation::Model::Load) do
124
+ model Group do
125
+ def custom_method
126
+ 'extended'
127
+ end
128
+ end
129
+
130
+ protected
131
+
132
+ def find_model_relation
133
+ Group.where(name: 'test')
134
+ end
135
+ end
136
+
137
+ op = cls.new(id: g.id)
138
+ assert_equal 'extended', op.model.custom_method
139
+ assert op.model.class < Group
140
+ assert_not_equal Group, op.model.class
141
+ end
97
142
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_ops
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.6
4
+ version: 1.7.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sitrox