aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/secure_token.rb
diff options
context:
space:
mode:
authorGriffin Smith <wildgriffin45@gmail.com>2015-07-10 11:32:18 -0400
committerGriffin Smith <wildgriffin45@gmail.com>2016-01-09 14:49:00 -0500
commit21c0a1f3016b1de81f455f2a242803db91f96f17 (patch)
treeddd93f8de3d51333bd0ab18fb2f7181368c5500e /activerecord/lib/active_record/secure_token.rb
parent9d681fc74c6251d5f2b93fa9576c9b2113116680 (diff)
downloadrails-21c0a1f3016b1de81f455f2a242803db91f96f17.tar.gz
rails-21c0a1f3016b1de81f455f2a242803db91f96f17.tar.bz2
rails-21c0a1f3016b1de81f455f2a242803db91f96f17.zip
Support :if and :unless in has_secure_token
Pass through :if and :unless options from has_secure_token to the generated before_create callback
Diffstat (limited to 'activerecord/lib/active_record/secure_token.rb')
-rw-r--r--activerecord/lib/active_record/secure_token.rb25
1 files changed, 23 insertions, 2 deletions
diff --git a/activerecord/lib/active_record/secure_token.rb b/activerecord/lib/active_record/secure_token.rb
index 8abda2ac49..f10f7a1515 100644
--- a/activerecord/lib/active_record/secure_token.rb
+++ b/activerecord/lib/active_record/secure_token.rb
@@ -20,14 +20,35 @@ module ActiveRecord
#
# <tt>SecureRandom::base58</tt> is used to generate the 24-character unique token, so collisions are highly unlikely.
#
+ # A secure token can also be only created given a condition, for example if a user should only have an
+ # auto-generated invitation token if the user was invited:
+ #
+ # # Schema: User(token:string, invited:boolean)
+ # class User < ActiveRecord::Base
+ # has_secure_token if: :invited?
+ # end
+ #
+ # user = User.new(invited: true)
+ # user.save
+ # user.token # => "pX27zsMN2ViQKta1bGfLmVJE"
+ #
+ # user = User.new(invited: false)
+ # user.save
+ # user.token # => nil
+ #
+ # The secure token creation supports all the options a `before_create` does - like +:if+ and +:unless+.
+ #
# Note that it's still possible to generate a race condition in the database in the same way that
# {validates_uniqueness_of}[rdoc-ref:Validations::ClassMethods#validates_uniqueness_of] can.
# You're encouraged to add a unique index in the database to deal with this even more unlikely scenario.
- def has_secure_token(attribute = :token)
+ def has_secure_token(attribute = :token, **before_create_options)
# Load securerandom only when has_secure_token is used.
require 'active_support/core_ext/securerandom'
+
define_method("regenerate_#{attribute}") { update! attribute => self.class.generate_unique_secure_token }
- before_create { self.send("#{attribute}=", self.class.generate_unique_secure_token) unless self.send("#{attribute}?")}
+ before_create(before_create_options) do
+ self.send("#{attribute}=", self.class.generate_unique_secure_token) unless self.send("#{attribute}?")
+ end
end
def generate_unique_secure_token