Before_create不工作 - Before_create isn't working

- 此内容更新于:2016-02-01
主题:

在模型文件我:在我迁移:但现在创建一篇文章失败的测试。在这些测试中我确实不给一个值。然而,不应该自动上面的方法做这个吗?它关注测试调用方法的新作者,控制器的方法包括行(没有一个令牌值文章)。注:我把顶部的方法,和它从来没有火灾的任何测试。

原文:

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.

网友:不创建一篇文章。应该呼吁的对象。

(原文:@author.articles.create! does not create an article. create! should be called on the @author object.)

解决方案:
一个更好的方法是使用(包括在Rails5;宝石):
原文:
#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
楼主:谢谢!我在想什么。我有多个方法模型,创建一个新的作者,和在同一控制器方法创建第一个/新文章的作者()。这会在行动之前自动为所有这些不同的控制器方法,不管他们是否名称或其他什么?

(原文:Thanks! I was wondering about on: :create. I have multiple methods in my Author model that create a new author, and in that same controller method create the first/new article for that author (@author.articles.create()). Would this before action automatically fire for all these different controller methods, irrespective whether they are name create or something else?)

网友:回调是一个对象,而不是方法。为了使对象被初始化/调用,它必须被创建。这是寻找时,所谓的“创造”。一个很好的描述方法可以在文档中找到

(原文:The create callback is for an object, not a method. In order for the object to be initialized / invoked, it has to be created. This is what ActiveRecord looks for when it calls "create". A good description of this methodology can be found in the new_record? docs)

解决方案:
你可能想要使用火的时候你想要它,只在最初的创造,不是每一个省。
原文:

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.

解决方案:
试着改变。
原文:

Try to change before_create to before_validation.

网友:谢谢,那么它实际上火灾。但不会然后创建一个新的令牌不仅创建新记录时,而且每次一条现有的记录被保存?

(原文:Thanks, then it indeed fires. But wouldn't it then create a new token not only when a new record is created but also everytime an existing record gets saved?)