提交 21c0a1f3 编写于 作者: G Griffin Smith

Support :if and :unless in has_secure_token

Pass through :if and :unless options from has_secure_token to the
generated before_create callback
上级 9d681fc7
* Support `:if` and `:unless` options in `has_secure_token`
*Griffin Smith*
* Use `version` column as primary key for schema_migrations table because
schema_migrations versions are guaranteed to be unique.
......
......@@ -20,14 +20,35 @@ module ClassMethods
#
# <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
......
......@@ -29,4 +29,14 @@ def test_token_value_not_overwritten_when_present
assert_equal @user.token, "custom-secure-token"
end
def test_token_with_if_condition_checks_condition_on_save
@user.token_condition = false
@user.save
assert_nil @user.conditional_token
@user.token_condition = true
@user.save
assert_not_nil @user.conditional_token
end
end
class User < ActiveRecord::Base
has_secure_token
has_secure_token :auth_token
has_secure_token :conditional_token, if: :token_condition
attr_accessor :token_condition
end
class UserWithNotification < User
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册