在我的Article
模型文件中,我有:
before_create :generate_token
validates :token, presence: true
private
def generate_token
self.token = SecureRandom.urlsafe_base64
end
在我的迁移中:
t.string :token, null: false
但现在创建文章的测试失败了ActiveRecord::RecordInvalid: Validation failed: Token can't be blank
。在这些测试中,我确实没有给出token
的值。但是,上面的before_create
方法不应该自动执行此操作吗?它涉及为新作者调用create
方法的测试,其中控制器方法包含行@author.articles.create!
(因此没有文章的标记值)。
P.S。我将debugger
放在generate_token
方法的顶部,它永远不会触发任何测试。
答案 0 :(得分:3)
#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
更好的方法是使用has_secure_token
(包含在Rails 5中; gem此处):
#Gemfile
gem "has_secure_token" #-> not needed for Rails 5
#app/models/article.rb
class Article < ActiveRecord::Base
has_secure_token
end
答案 1 :(得分:2)
您可能想要使用
before_validation :generate_token, on: :create
这将在您想要的时间触发,并且仅在初始创建时触发,而不是在每次保存时触发。
答案 2 :(得分:0)
尝试将before_create
更改为before_validation
。