File tree Expand file tree Collapse file tree 3 files changed +39
-8
lines changed Expand file tree Collapse file tree 3 files changed +39
-8
lines changed Original file line number Diff line number Diff line change 1
1
## 2.0.0 (unreleased)
2
2
3
+ - Improved ` attributes ` , ` attribute_names ` , and ` has_attribute? ` when ciphertext attribute not loaded
3
4
- Dropped support for Active Record < 7 and Ruby < 3.1
4
5
- Dropped support for Mongoid < 8
5
6
Original file line number Diff line number Diff line change @@ -148,7 +148,40 @@ def attributes
148
148
end
149
149
end
150
150
end
151
- super
151
+
152
+ # remove attributes that do not have a ciphertext attribute
153
+ attributes = super
154
+ self . class . lockbox_attributes . each do |k , lockbox_attribute |
155
+ if !attributes . include? ( lockbox_attribute [ :encrypted_attribute ] . to_s )
156
+ attributes . delete ( k . to_s )
157
+ attributes . delete ( lockbox_attribute [ :attribute ] )
158
+ end
159
+ end
160
+ attributes
161
+ end
162
+
163
+ # remove attribute names that do not have a ciphertext attribute
164
+ def attribute_names
165
+ # hash preserves key order
166
+ names_set = super . to_h { |v | [ v , true ] }
167
+ self . class . lockbox_attributes . each do |k , lockbox_attribute |
168
+ if !names_set . include? ( lockbox_attribute [ :encrypted_attribute ] . to_s )
169
+ names_set . delete ( k . to_s )
170
+ names_set . delete ( lockbox_attribute [ :attribute ] )
171
+ end
172
+ end
173
+ names_set . keys
174
+ end
175
+
176
+ # check the ciphertext attribute for encrypted attributes
177
+ def has_attribute? ( attr_name )
178
+ attr_name = attr_name . to_s
179
+ _ , lockbox_attribute = self . class . lockbox_attributes . find { |_ , la | la [ :attribute ] == attr_name }
180
+ if lockbox_attribute
181
+ super ( lockbox_attribute [ :encrypted_attribute ] )
182
+ else
183
+ super
184
+ end
152
185
end
153
186
154
187
# needed for in-place modifications
Original file line number Diff line number Diff line change @@ -225,13 +225,10 @@ def test_attributes_not_loaded
225
225
assert !user . has_attribute? ( "name" )
226
226
assert !user . has_attribute? ( :name )
227
227
228
- # TODO try to make virtual attribute behavior consistent
229
- # this may be difficult, as virtual attributes are set to self.class._default_attributes
230
- # which gets merged with query attributes in initialize method of active_record/core.rb
231
- # assert_equal ["id"], user.attributes.keys
232
- # assert_equal ["id"], user.attribute_names
233
- # assert !user.has_attribute?("email")
234
- # assert !user.has_attribute?(:email)
228
+ assert_equal [ "id" ] , user . attributes . keys
229
+ assert_equal [ "id" ] , user . attribute_names
230
+ assert !user . has_attribute? ( "email" )
231
+ assert !user . has_attribute? ( :email )
235
232
236
233
user = User . select ( "id AS email_ciphertext" ) . last
237
234
assert_raises ( Lockbox ::DecryptionError ) do
You can’t perform that action at this time.
0 commit comments