我有一些属性需要有默认值。我已经设置了迁移以在数据库中设置默认值,如下所示:
class AddDefaultsToModel < ActiveRecord::Migration[5.2]
def change
change_column :posts, :post_type, :string, default: 'draft'
change_column :posts, :date_time, :datetime, default: -> { 'CURRENT_TIMESTAMP' }
end
end
直接添加到数据库时,默认值效果很好。但是,如果我在 Rails 中构建一个新模型,一个属性会按预期工作,而另一个则不会:
post = Post.new
post.post_type # draft (as expected)
post.date_time # nil (expecting the current date and time)
这种行为是故意的吗?我是否也必须在模型中设置默认值?为什么Post#post_type
工作但不工作Post#date_time
?
ActiveRecord 不理解您的默认值date_time
意味着它不给date_time
根本没有默认值。然后,当您将该行插入数据库时(即post.save
),数据库将使用当前时间戳作为date_time
值(当然假设没有人接触过date_time
)。 Rails 不会知道这一点date_time
插入后有一个值,因此您会得到如下行为:
post = Post.new
post.date_time # `nil` because it hasn't been set at all
# set some other values on `post`...
post.save # INSERT INTO posts (columns other than date_time...) values (...)
post.date_time # `nil` even thought there is a value in the database
post.reload # Pull everything out of the database
post.date_time # Now we have a timestamp
您有一些选择:
Call post.reload
保存后post
获取数据库使用的默认时间戳。
-
Use an after_initialize
自行设置默认值的钩子:
class Post < ApplicationRecord
after_initialize if: :new_record? do
self.date_time = Time.now
end
end
-
Use the 属性API手动设置默认值:
class Post < ApplicationRecord
attribute :date_time, :datetime, default: ->{ Time.now }
end
您需要使用 lambda(或 Proc),以便Time.now
在正确的时间执行。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)