Reputation: 3090
In my Article
model file I have:
before_create :generate_token
validates :token, presence: true
private
def generate_token
self.token = SecureRandom.urlsafe_base64
end
And in my migration:
t.string :token, null: false
But now tests that create an article fail with ActiveRecord::RecordInvalid: Validation failed: Token can't be blank
. In these tests I indeed don't give a value for token
. However, shouldn't the before_create
method above do this automatically? It concerns test that call upon the create
method for a new author, of which the controller method includes the line @author.articles.create!
(so without a token value for the article).
P.S. I put the debugger
at the top of the generate_token
method, and it never fires for any of the tests.
Upvotes: 3
Views: 1152
Reputation: 76774
#app/models/article.rb
class Article < ActiveRecord::Base
before_validation :generate_token, on: :create
validates :token, presence: true
private
def generate_token
self.token = loop do
random_token = SecureRandom.urlsafe_base64
break random_token unless self.class.exists? random_token
end
end
end
A much better way is to use has_secure_token
(included in Rails 5; gem here):
#Gemfile
gem "has_secure_token" #-> not needed for Rails 5
#app/models/article.rb
class Article < ActiveRecord::Base
has_secure_token
end
Upvotes: 4
Reputation: 28554
You probably want to use
before_validation :generate_token, on: :create
That will fire at exactly the time you are wanting it to and only on the initial creation, not on every save.
Upvotes: 2