2012-03-01 41 views
14

Tôi có Mã thông báo mô hình, có mã thông báo trường mà tôi cần tăng tự động (bắt đầu từ 1001), nếu và chỉ khi người dùng không cung cấp. Vấn đề là, vì người dùng có tùy chọn cung cấp trường này, tôi không thể truy vấn chính xác cơ sở dữ liệu và yêu cầu mã thông báo lớn nhất. Tôi tìm thấy một câu trả lời trên diễn đàn này, nhưng tôi khá chắc chắn có phải là một cách tốt hơn để làm điều đó hơn để thực hiện một câu lệnh SQL? Auto increment a non-primary key field in Ruby on RailsTạo trường tăng tự động trong đường ray

Trả lời

12

Câu hỏi thú vị dành cho tôi. Thật không may, đường ray không cung cấp một cách để tự động tăng cột, vì vậy chúng tôi phải nghỉ mát với SQL với ít tự động hóa. Tôi cố gắng này trong Rails 3.0.7 sử dụng PostgreSQL là cơ sở dữ liệu của tôi và nó hoạt động và hy vọng điều này sẽ hữu ích:

Tạo chuỗi cho 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 

Bây giờ, kể từ khi có một khả năng của token_number được thiết lập bởi người dùng theo cách thủ công, chúng tôi sẽ chỉ cần tạo token_number nếu nó không được đặt. Read about Callbacks here. Với điều đó, chúng tôi có,

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 

Chạy mẫu. Xin lưu ý rằng đối với mã thông báo đầu tiên tôi không đặt token_number và nó tạo ra chuỗi token_number và thứ hai tôi đang gán.

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 > 
+0

Có thể bằng cách nào đó sử dụng giá trị mặc định kết hợp với 'nextval' để tránh sử dụng gọi lại không? – freemanoid

Các vấn đề liên quan