mirror of https://github.com/rails/rails
Refactor `ActiveRecord::SignedId` to not rely on relation delegation
Ref: https://github.com/rails/rails/pull/50396 Ref: https://github.com/rails/rails/pull/51776 `ActiveRecord::Relation` automatically delegates missing methods to the model class wrapped in a `scoping { }` block. This is to support scoping in user defined class methods. The problem however is that it's very error prone for the framework, because we can mistakenly call model methods from inside `Relation` and not realized we're applying a global scope. In the best case scenario it's just a waste of performance, but it can also lead to bugs like https://github.com/rails/rails/issues/51775 I'm planning to restrict this automatic delegation to methods defined in childs of `ActiveRecord::Base` only: https://github.com/rails/rails/pull/50396 but for this to work we must first refactor any Rails code that rely on it.
This commit is contained in:
parent
007a609ef2
commit
c6d0ef5974
|
@ -66,6 +66,7 @@ module ActiveRecord
|
|||
|
||||
include Enumerable
|
||||
include FinderMethods, Calculations, SpawnMethods, QueryMethods, Batches, Explain, Delegation
|
||||
include SignedId::RelationMethods
|
||||
|
||||
attr_reader :table, :klass, :loaded, :predicate_builder
|
||||
attr_accessor :skip_preloading_value
|
||||
|
|
|
@ -13,6 +13,16 @@ module ActiveRecord
|
|||
class_attribute :signed_id_verifier_secret, instance_writer: false
|
||||
end
|
||||
|
||||
module RelationMethods # :nodoc:
|
||||
def find_signed(...)
|
||||
scoping { model.find_signed(...) }
|
||||
end
|
||||
|
||||
def find_signed!(...)
|
||||
scoping { model.find_signed!(...) }
|
||||
end
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
# Lets you find a record based on a signed id that's safe to put into the world without risk of tampering.
|
||||
# This is particularly useful for things like password reset or email verification, where you want
|
||||
|
|
Loading…
Reference in New Issue