如何在Rails迁移中找到常量ID?

时间:2019-06-10 15:10:48

标签: ruby-on-rails

我要在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的默认值?

2 个答案:

答案 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