在 rails 中生成一个自增字段 [英] Generate an auto increment field in rails

查看:38
本文介绍了在 rails 中生成一个自增字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个模型令牌,它有一个字段 token_number 我需要自动递增(从 1001 开始),当且仅当用户不提供它时.问题是,由于用户可以选择提供此字段,因此我无法准确查询数据库并要求提供最大的 token_number.我在这个论坛上找到了一个答案,但我很确定必须有比执行 SQL 语句更好的方法来做到这一点?在 Ruby 中自动增加非主键字段在 Rails 上

I have a model Token, which has a field token_number that I need to auto increment (starting from 1001), if and only if the user does not provide it. The problem is that, since the user has the option to provide this field, I can't exactly query the database and ask for the largest token_number. I found one answer on this forum, but I'm quite certain there has to be a better way to do it than to execute an SQL statement? Auto increment a non-primary key field in Ruby on Rails

推荐答案

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

Interesting question for me. Unfortunately, rails doesn't provide a way to auto-increment columns, so we must resort to SQL with little automation. I tried this in Rails 3.0.7 using PostgreSQL as my database and it works and hope this will be useful:

为 token_number 创建序列 PGSql 文档

Creating sequence for 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.在此处阅读有关回调的信息.有了这个,

Now, since there is a possibility of token_number being set by the user manually, we'll need to generate the token_number only if it is not being set. Read about Callbacks here. With that we have,

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

示例运行.请注意,对于第一个令牌,我没有设置 token_number,它会生成 token_number 序列,而对于第二个令牌,我正在分配.

A sample run. Please note that for the first token I am not setting token_number and it generates the token_number sequence and for the second I am assigning.

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 

这篇关于在 rails 中生成一个自增字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆