Ответ 1
Интересный вопрос для меня. К сожалению, рельсы не обеспечивают способ автоматического увеличения столбцов, поэтому мы должны прибегать к SQL с небольшой автоматизацией. Я пробовал это в Rails 3.0.7, используя PostgreSQL в качестве моей базы данных, и он работает, и надеюсь, что это будет полезно:
Создание последовательности для token_number Документация PGSql
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
Теперь, поскольку существует возможность того, что токен_нумера задается пользователем вручную, нам нужно будет сгенерировать токен-номер, только если он не установлен. Читайте об обратных вызовах здесь. С этим мы имеем
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 и для второго присваивания.
ruby-1.9.2-p0 > token = Token.new
=> #<Token id: nil, name: nil, token_number: nil, created_at: nil, updated_at: nil>
ruby-1.9.2-p0 > 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
ruby-1.9.2-p0 > token = Token.new
=> #<Token id: nil, name: nil, token_number: nil, created_at: nil, updated_at: nil>
ruby-1.9.2-p0 > token.token_number = 3000
=> 3000
ruby-1.9.2-p0 > 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-1.9.2-p0 >