我有一些需要具有默认值的属性。我已设置迁移,以按如下所示在数据库中设置默认值:
reduce
将默认值直接添加到数据库时,默认值非常有用。但是,如果我在Rails中构建新模型,则一个属性可以按预期工作,而另一个则不能:
const taxItems = [{
taxCode: '430',
taxAmount: 2,
ItemTaxPercentage: 20,
taxCategory: '2'
},
{
taxCode: '430',
taxAmount: 4,
ItemTaxPercentage: 20,
taxCategory: '2'
},
{
taxCode: '431',
taxAmount: 5,
ItemTaxPercentage: 20,
taxCategory: '2'
},
{
taxCode: '430',
taxAmount: 6,
ItemTaxPercentage: 20,
taxCategory: '2'
}
]
let op = Object.values(taxItems.reduce((op,cur)=>{
if(op[cur['taxCode']]){
op[cur['taxCode']]['taxAmount']+= cur['taxAmount'];
} else {
op[cur['taxCode']] = cur
}
return op;
},{}))
console.log(op)
这种行为是故意的吗?我还必须在模型中设置默认值吗?为什么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
起作用但post = Post.new
post.post_type # draft (as expected)
post.date_time # nil (expecting the current date and time)
不起作用?
答案 0 :(得分:1)
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
挂钩自己设置默认值:
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
。