在rails中生成一个自动增量字段 [英] Generate an auto increment field in rails
问题描述
我有一个模型令牌,当且仅当用户没有提供令牌时,该令牌具有我需要自动递增(从1001开始)的字段token_number.问题在于,由于用户可以选择提供此字段,因此我无法完全查询数据库并要求最大的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.我使用PostgreSQL作为数据库在Rails 3.0.7中进行了尝试,并且可以正常工作,希望对您有用:
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屋!