【问题标题】:ActiveRecord - Altering a table to set an auto increment minimum value?ActiveRecord - 更改表格以设置自动增量最小值?
【发布时间】:2015-05-01 20:40:23
【问题描述】:

背景

一个简单的 rails activerecord 迁移

class CreateMyTable < ActiveRecord::Migration
  def change    
    create_table :my_table, force: :cascade do |t|
      t.index    "id"
      t.string   "column1",     limit: 64
      t.string   "column2", limit: 64

      t.timestamps null: false
    end       
    MyTable.connection.execute("ALTER TABLE my_table AUTO_INCREMENT = 10000;") 
  end
end

它创建my_table 并向其中添加几列。最后一行执行一个原始命令,将第一个 id 设置为从 10000 开始计数。

问题

运行db:migrate 时,rails 会更新schema.rb 文件以合并此迁移的结果,即添加新表。

但是,设置 AUTO_INCREMENT 的最后一条语句不会在 schema.rb 文件中捕获。

当另一个用户或服务器第一次运行 db:setup 时,rails 将使用该 schema.rb 来构建架构,并且不会发现它需要将 id 提升到 10000 的事实。

有什么方法可以将此迁移更改到schema.rb 文件中,以便将来基于此schema.rb 文件构建的所有数据库都会适当地增加id

编辑

根据 inye 下面的建议,我尝试编辑迁移以删除 t.index 引用,我的 schema.rb 如下

ActiveRecord::Schema.define(version: 20150501211519) do

  create_table "my_table", force: :cascade do |t|
    t.string   "column1",    limit: 64
    t.string   "column2",    limit: 64
    t.datetime "created_at",            null: false
    t.datetime "updated_at",            null: false
  end

end

【问题讨论】:

    标签: mysql ruby-on-rails activerecord


    【解决方案1】:

    试试

    class CreateMyTable < ActiveRecord::Migration
        def change    
            create_table :my_table, force: :cascade do |t|
                t.string   "column1",     limit: 64
                t.string   "column2", limit: 64
    
                t.timestamps null: false
            end       
            execute("ALTER TABLE my_table AUTO_INCREMENT = 10000;")
        end
    end
    

    根据http://edgeguides.rubyonrails.org/active_record_migrations.html,你不需要t.index "id"这一行

    一个名为 id 的主键列也将被隐式添加,因为它是所有 Active Record 模型的默认主键。

    编辑:

    其他选项是before_save 和一些类似

    class Model < ActiveRecord::Base
        before_save :change_id
    
        def change_id
    
            last_model = Model.order("id DESC").first
            if last_model.id < 10000 or last_model.nil?
                self.id = 10000
            else
                self.id = last_model.id + 1
            end
        end
    end
    

    【讨论】:

    • 不幸的是,运气不好。它第一次正确执行语句,但不修改schema.rb 中的任何内容。下次任何机器使用该schema.rb 文件重新构建模式时,它都不知道需要设置AUTO_INCREMENT
    • 试试编辑后的答案,你能把你的my_table 架构放进去吗?
    • 这是个好建议。我尝试删除 ID,它第一次确实可以正常工作,但它仍然没有更新 schema.rb。我在上面的评论中添加了输出。
    • id 的表格没有显示在schema.rb
    • 如果在表格中插入一行会发生什么?你得到什么身份证?
    猜你喜欢
    • 2012-11-30
    • 2012-02-08
    • 2015-06-11
    • 1970-01-01
    • 2011-09-17
    • 2011-11-25
    • 2014-02-07
    • 1970-01-01
    • 2021-03-03
    相关资源
    最近更新 更多