gpt4 book ai didi

ruby-on-rails - Rails 5.2 和带有 CURRENT_TIMESTAMP 的 Active Record 迁移

转载 作者:行者123 更新时间:2023-12-01 04:31:21 26 4
gpt4 key购买 nike

我有一些需要具有默认值的属性。我已将迁移设置为在数据库中设置默认值,如下所示:

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

你有一些选择:
  • 调用 post.reload保存后post获取数据库使用的默认时间戳。
  • 使用 after_initialize钩子(Hook)自己设置默认值:
    class Post < ApplicationRecord
    after_initialize if: :new_record? do
    self.date_time = Time.now
    end
    end
  • 使用 attributes API手动设置默认值:
    class Post < ApplicationRecord
    attribute :date_time, :datetime, default: ->{ Time.now }
    end

    您需要使用 lambda(或 Proc),以便 Time.now在正确的时间执行。
  • 关于ruby-on-rails - Rails 5.2 和带有 CURRENT_TIMESTAMP 的 Active Record 迁移,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53804787/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com