我要在Rails应用程序的表中添加一个新列,并且不确定如何通过常量设置默认值
我在User.rb模型中定义了常量:
class AddAccountTypeIdInAccounts < ActiveRecord::Migration[5.2]
def change
add_column :users, :user_type_id, :integer, :default => ?
end
end
并产生了新的迁移
{{1}}
应该用什么代替“?”将ID为1且名称为“ User”的USER_TYPE从常量保存为新User的默认值?
答案 0 :(得分:3)
add_column :users, :user_type_id, :integer, :default => 1
说真的,为什么要根据应用程序代码中存在的常量来定义默认值?迁移是您将在某个时间点运行的东西,而不是您将一直维护的代码。在迁移中引用应用程序代码没有什么意义,因为应用程序将不断发展,引用也会发生变化。您不想维护迁移。
当然,您也可以引用存储在该常量中的值,也许它可以作为您的文档。在这种情况下:
add_column :users, :user_type_id, :integer, :default => User::USER_TYPE.first[:id]
(不确定USER_TYPE
内是否定义了class User
;否则,请省略上面的User::
。)
答案 1 :(得分:0)
在最后一条评论中回答了您的特定问题后,我将提出几点建议,以激发您的想象力,以寻求针对该问题的更好选择。
让我们想象一下,如果明天您需要更改此特定列的默认值,则需要创建一个新的迁移,如果需要更改此次数20次,则需要创建20个新的迁移。
以上选项不可扩展。
您可能应该让默认的nil
迁移,并使用ActiveRecord
回调,甚至更好的是另一个模块(服务或操作),该模块将为您处理create操作并设置默认值。
# models/user
# option 1
class User < ApplicationRecord
USER_TYPE = [
{ id: 1, name: "User" },
{ id: 2, name: "Admin" },
{ id: 3, name: "Super Admin" }
].freeze
before_create do
self.user_type_id = USER_TYPE.first[:id]
end
end
# services/user_creator_service
# option 2
class UserCreatorService
def self.call(user)
user.user_type_id = User::USER_TYPE.first[:id]
user.save
end
end