ruby-on-rails - 在rails中生成一个自动增量字段

标签 ruby-on-rails auto-increment rails-migrations

我有一个模型 Token,它有一个我需要自动递增的字段 token_number(从 1001 开始),当且仅当用户不提供它时。问题是,由于用户可以选择提供这个字段,我不能准确地查询数据库并要求最大的 token_number。我在这个论坛上找到了一个答案,但我很确定必须有比执行 SQL 语句更好的方法来做到这一点? Auto increment a non-primary key field in Ruby on Rails

最佳答案

对我来说很有趣的问题。不幸的是,rails 没有提供自动增加列的方法,所以我们必须求助于几乎没有自动化的 SQL。我在 Rails 3.0.7 中使用 PostgreSQL 作为我的数据库进行了尝试,它可以工作,希望这会很有用:

为 token_number PGSql Documentation 创建序列

class CreateTokens < ActiveRecord::Migration

  def self.up
    create_table :tokens do |t|
      t.string :name
      t.integer :token_number

      t.timestamps
    end

    execute "CREATE SEQUENCE tokens_token_number_seq START 1001"
  end

  def self.down
    drop_table :tokens

    execute "DROP SEQUENCE tokens_token_number_seq"
  end
end

现在,由于用户手动设置了 token_number 的可能性,我们只需要在没有设置 token_number 的情况下生成它。 Read about Callbacks here .有了我们,
class Token < ActiveRecord::Base
  # Generate the sequence no if not already provided.
  before_validation(:on => :create) do
    self.application_no = next_seq unless attribute_present?("application_no")
  end

  private
    def next_seq(column = 'application_no')
      # This returns a PGresult object [http://rubydoc.info/github/ged/ruby-pg/master/PGresult]
      result = Token.connection.execute("SELECT nextval('tokens_token_number_seq')")

      result[0]['nextval']
    end 
end

sample 运行。请注意,对于第一个 token ,我没有设置 token_number,它会生成 token_number 序列,而我正在分配第二个 token 。
token = Token.new
# => #<Token id: nil, name: nil, token_number: nil, created_at: nil, updated_at: nil> 

token.save
  SQL (0.8ms)  BEGIN
  SQL (1.7ms)  SELECT nextval('tokens_token_number_seq')
  SQL (6.6ms)   SELECT tablename
 FROM pg_tables
 WHERE schemaname = ANY (current_schemas(false))

  SQL (33.7ms)  INSERT INTO "tokens" ("name", "token_number", "created_at", "updated_at") VALUES (NULL, 1001, '2012-03-02 12:04:00.848863', '2012-03-02 12:04:00.848863') RETURNING "id"
  SQL (15.9ms)  COMMIT
# => true 

token = Token.new
# => #<Token id: nil, name: nil, token_number: nil, created_at: nil, updated_at: nil> 

token.token_number = 3000
# => 3000 

token.save
  SQL (0.8ms)  BEGIN
  SQL (1.5ms)  INSERT INTO "tokens" ("name", "token_number", "created_at", "updated_at") VALUES (NULL, 3000, '2012-03-02 12:04:22.924834', '2012-03-02 12:04:22.924834') RETURNING "id"
  SQL (19.2ms)  COMMIT
# => true 

关于ruby-on-rails - 在rails中生成一个自动增量字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9513739/

相关文章:

mysql - 使用当前的 auto_increment 值作为同一 INSERT 查询中另一个字段的基础——这在 MySQL 中可能吗?

mysql - 从 MySQL 中的 TRIGGER 中更改 LAST_INSERT_ID()

ruby-on-rails - 迁移无法识别在 schema_search_path 上创建的 hstore 扩展

mysql - 通过 ruby​​ Rails 迁移添加 MySQL 枚举列时出现问题

ruby-on-rails - 使用 Phusion 乘客和 Rails 时初始服务器启动缓慢

ruby-on-rails - 如何增加 rails 中 HTTParty post 方法的超时时间?

ruby-on-rails - 如何在 Elementary O.S. 上安装 rails ?

sql - 如何将 SQL 中的主键更改为 auto_increment?

ruby-on-rails - 在 Rails 中清理迁移的好方法是什么?

ruby-on-rails - Rails 密码在 24 小时内过期