diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 78cc7bc770b..9226be459ca 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -66,7 +66,7 @@ module ActiveRecord include Enumerable include FinderMethods, Calculations, SpawnMethods, QueryMethods, Batches, Explain, Delegation - include SignedId::RelationMethods + include SignedId::RelationMethods, TokenFor::RelationMethods attr_reader :table, :klass, :loaded, :predicate_builder attr_accessor :skip_preloading_value diff --git a/activerecord/lib/active_record/token_for.rb b/activerecord/lib/active_record/token_for.rb index 3b521922443..2a4e2266996 100644 --- a/activerecord/lib/active_record/token_for.rb +++ b/activerecord/lib/active_record/token_for.rb @@ -35,6 +35,24 @@ module ActiveRecord end end + module RelationMethods + # Finds a record using a given +token+ for a predefined +purpose+. Returns + # +nil+ if the token is invalid or the record was not found. + def find_by_token_for(purpose, token) + raise UnknownPrimaryKey.new(self) unless model.primary_key + model.token_definitions.fetch(purpose).resolve_token(token) { |id| find_by(model.primary_key => id) } + end + + # Finds a record using a given +token+ for a predefined +purpose+. Raises + # ActiveSupport::MessageVerifier::InvalidSignature if the token is invalid + # (e.g. expired, bad format, etc). Raises ActiveRecord::RecordNotFound if + # the token is valid but the record was not found. + def find_by_token_for!(purpose, token) + model.token_definitions.fetch(purpose).resolve_token(token) { |id| find(id) } || + (raise ActiveSupport::MessageVerifier::InvalidSignature) + end + end + module ClassMethods # Defines the behavior of tokens generated for a specific +purpose+. # A token can be generated by calling TokenFor#generate_token_for on a @@ -85,20 +103,12 @@ module ActiveRecord self.token_definitions = token_definitions.merge(purpose => TokenDefinition.new(self, purpose, expires_in, block)) end - # Finds a record using a given +token+ for a predefined +purpose+. Returns - # +nil+ if the token is invalid or the record was not found. - def find_by_token_for(purpose, token) - raise UnknownPrimaryKey.new(self) unless primary_key - token_definitions.fetch(purpose).resolve_token(token) { |id| find_by(primary_key => id) } + def find_by_token_for(purpose, token) # :nodoc: + all.find_by_token_for(purpose, token) end - # Finds a record using a given +token+ for a predefined +purpose+. Raises - # ActiveSupport::MessageVerifier::InvalidSignature if the token is invalid - # (e.g. expired, bad format, etc). Raises ActiveRecord::RecordNotFound if - # the token is valid but the record was not found. - def find_by_token_for!(purpose, token) - token_definitions.fetch(purpose).resolve_token(token) { |id| find(id) } || - (raise ActiveSupport::MessageVerifier::InvalidSignature) + def find_by_token_for!(purpose, token) # :nodoc: + all.find_by_token_for!(purpose, token) end end