【问题标题】:reseting primary key id in rails在rails中重置主键ID
【发布时间】:2010-12-28 07:37:44
【问题描述】:

当我从表中删除_all 并再次开始插入时,我遇到了主键如何递增的问题。这是有问题的,因为我有其他与清除表关联的模型。例如,如果我有属于计算机的 Apple,那么当我清除计算机表并重新添加计算机时,关联会变得混乱,因为 Apple 现在在其行中有婴儿计算机 ID。我希望能够重置计算机的主键,这样当我重新添加计算机时,关联仍然保持不变。我应该如何在 Rails 中执行此操作?

编辑 我很抱歉不清楚这一点,但现在我会告诉你我想做的事情。我希望用户与机器(计算机)相关联。计算机有自己的 id,只能由管理员创建。电脑桌上有固定数量的电脑。

User
belongs_to :computer

Computer
has_many :users

我面临的问题是,我在种子.rb/some rakefile 中预先加载了计算机表。当我启动我的应用程序时,我只想运行首先删除所有内容然后预加载表的文件。这将让用户仅从计算机表中提供的计算机中选择计算机。我希望能够再次运行这个脚本(比如在 heroku 控制台中,而不删除 User 表)并且仍然获得与每台机器(以及每个用户)相关联的相同 id。我对如何做到这一点感到困惑。请让我知道我是否应该这样做。

【问题讨论】:

  • 您不应该使用种子或固定装置或其他任何东西加载此类数据。它应该通过一些管理界面进行维护。不要使用两个主键 - 你最终会一团糟:)
  • 也许试着解释一下你在做什么以及为什么要这样做。

标签: ruby-on-rails ruby-on-rails-3


【解决方案1】:

首先,你不应该这样做!如果要更改记录,则只需更新表中的行。不要删除它并重新插入它!如果你还想这样做,那么你应该删除其他表中所有关联的行,并插入计算机和苹果。

我不知道 Rails 重置自动增量主键的方式,但如果你使用 mysql,那么你可以运行自定义查询:

ActiveRecord::Base.connection.execute('ALTER TABLE tablename AUTO_INCREMENT = 1')

它应该将自动增量值重置为下一个可用数字。

编辑:

如何使用id 加载数据。 我不确定加载种子是否可以做到,但使用固定装置肯定会有所帮助。您需要准备带有数据的computers.yml 文件:

First_computer:
  id: 1
  name: computer

Second_computer:
  id: 2
  name: dell

等等

然后你可以使用它来加载它到db:

require 'active_record/fixtures'

Fixtures.create_fixtures("/path/to/directory/where/your/yml/file/is/", "computers")

但它会重置整个表(所有行都将被删除并重新插入 - 但您可以保留您的 ID)。

我想再次警告您,以这种方式加载数据是个坏主意。 Fixtures/seeds 应该只用于为您的数据库播种初始(需要启动您的应用程序)数据。

为什么要重置此表?

【讨论】:

  • 您是否建议我只添加新计算机而不删除所有表?我遇到的问题是,当我销毁所有表格并开始添加新计算机时,用户将拥有婴儿计算机。那么我应该如何预加载数据,以便每次运行脚本加载数据时 id 和保持不变。
  • 使用夹具加载数据会重置表。它还会重置 id。
  • 您不应该在此转发其他模型关系。这是个坏主意:)。我还是不明白你为什么要重置这张表?为什么不直接更新每个字段而不删除它呢?或者,如果它是您的应用程序中的某种 const 数据,您可以尝试使用:github.com/jeffp/enumerated_attribute
  • 我用它来让它工作。在不重置 id 计数器的情况下将数据导入数据库可能会让您在尝试使用现有 id 的新记录时遇到麻烦。答案在这里:stackoverflow.com/a/23998870/293856
【解决方案2】:

这是一种奇怪的处理方式,但是如果您需要删除和替换关联表中的键,您可以尝试指定:dependent => :nullify,它会保留关联的行并在删除时将外键设置为 NULL:

class Computer
  has_many :apples, :dependent => :nullify
end

class Apple
  belongs_to :computer
end

c = Computer.find(some_id)
apples = c.apples
c.destroy # sets each foreign key in apples to NULL
new_c = Computer.create
new_c.apples = apples # sets each foreign key to new_c.id

【讨论】:

    【解决方案3】:

    您不应该依赖重置主键来维护关系,这不是正确的做法。如果您发现自己必须删除源表,而将来仍要保持关系,请使用不同的键进行映射,例如,您可以在计算机表中有一个代码字段,然后使用它来构建您的关系。您为 relationships 指定 foreign_key。

    【讨论】:

    • 我也这么认为...我正在尝试使用 rails 提供的其他选项。所以如果我希望计算机有一个名为 machine_id 的主键(它将在 Apple 中用作外键),我应该这样做吗? has_many :apples, class=> 'apple', :foreign_key => 'machine_id'
    • @denniss:遵循“Rails 方式”确实是个好主意,因此请始终使用 id 作为主键 - 它要简单得多。而且我不确定您的示例关联是否正确。如果您在Apple 模型/表中有machine_id 列,那将是正确的。如果您可以将这两种模型都添加到您的问题和表格架构中,那么我们可以提供更多帮助。
    猜你喜欢
    • 2011-10-24
    • 1970-01-01
    • 1970-01-01
    • 2010-11-28
    • 1970-01-01
    • 2021-08-26
    • 2011-09-24
    • 1970-01-01
    • 2019-07-13
    相关资源
    最近更新 更多