在我使用Heroku进行制作的Rails 4应用程序中,我为初始数据集设置了一个seeds.rb文件。因为一些记录具有特定的主要ID是至关重要的,例如在'活动'表,我已经设定了那些。一切顺利。
UNTIL。直到我需要向活动表添加新活动。添加新记录将失败的次数与该表中的记录一样多,而顺控程序会赶上。 (例如,如果我有三条记录,则新记录创建失败三次,成功完成第四条记录。)
问题:如何让Heroku postgres数据库中的主ID计数器在我的seeds.rb文件中设置的最高主ID之后启动?如果您不知道,我应该使用Google搜索哪些字词?
理想情况下,这个解决方案是自动的,而不是每次我为数据库播种时都要打开psql。
提前致谢。
答案 0 :(得分:3)
:id列是一个自动增量列。因此,您无法控制它使用的值 - 它只是始终使用其内部计数器中的下一个ID。如果这是我,我会找到一些其他方法来识别那些记录而不是:id。例如,也许您可以通过:名称或其他特殊属性来引用记录? (如果你走这条路线,别忘了索引你所找到的属性!)
然后,我会使用seed_fu gem来执行幂等种子,就像你似乎想要的那样。使用幂等种子,如果已经存在记录,那么它将被更新(如果有任何更新要执行;如果没有则那么它是无操作)。这样您就没有例外,您可以随时添加新记录或更新现有记录。
答案 1 :(得分:1)
自动增量
继pdobb
的答案之后,您将从阅读auto_increment
中受益 - 当您将数据插入包含auto_increment
列的表格时,它只会添加一个数字最后一个结束。在正常的情况下,您根本不必关心它
如果您需要包含特定ids
项,例如您引用特定记录或其他内容,我最好的建议是将您的系统更改为不处理特定primary_keys
-
示例强>
我们使用options
表和我们创建的CMS
表,并引用role_id
表中的options
表(我们播种):
这是从我们的db/seeds.rb
文件中填充的:
Option.create({name: "role", value: "admin"})
Option.create({name: "role", value: "moderator"})
Option.create({name: "role", value: "author"})
请注意,没有对id
的引用?
这意味着我们可以按如下方式引用role
:
#app/models/profile.rb
belongs_to :role, -> { where(name: "role") }, class_name: "Option", foreign_key: "role"
def role
role_name = Option.find self[:role]
role_name.value
end
因此,我们将role
id
存储在role
列中;并使用自定义instance method
来访问它,该自定义覆盖了Rails创建的getter!
所以,如果我打电话
current_user.profile.role # -> in DB, will have id stored, but will output "value" of that
-
这意味着我们可以自动分配id
!
这是有效的,因为即使您删除了前面的项目,id
记录的role
仍将保持不变。您无需担心自己的auto_increment
列
答案 2 :(得分:1)
我遇到了rails的acts_as_taggable_on gem遇到这个问题,因为它会抛出重复的标记错误。
在我rails db:seed
之后,我运行RAILS_ENV=development rake db:reset_pk_sequence
以便重置密钥。
# lib/tasks/tag_cleaner.rake
# run using 'RAILS_ENV=development rake db:reset_pk_sequence'
namespace :db do
desc "reset the pk sequence"
task :reset_pk_sequence => :environment do
ActiveRecord::Base.connection.tables.each do |t|
ActiveRecord::Base.connection.reset_pk_sequence!(t)
end
end
end
这似乎解决了这个问题,但后来我没有尝试过生产,因为我没有使用种子数据进行生产。
答案 3 :(得分:0)
问题最终是我从
运行seeds.rb$ rake db:setup
db:setup重新创建数据库,从而重置计数器。切换到:
$ rake db:migrate
$ rake db:seed
我可以在生产数据库中修改种子数据,而无需重置Postgres主ID计数器。
在旁注中,为了不会偶然发生这种情况,我还创建了一个rakefile,在输入rake db:setup时会引发错误。