2012-03-01 7 views
14

मेरे पास एक मॉडल टोकन है, जिसमें फ़ील्ड टोकन_नंबर है जो मुझे ऑटो वृद्धि (1001 से शुरू करने) की आवश्यकता है, अगर और केवल उपयोगकर्ता ही इसे प्रदान नहीं करता है। समस्या यह है कि, चूंकि उपयोगकर्ता के पास यह फ़ील्ड प्रदान करने का विकल्प है, इसलिए मैं डेटाबेस से बिल्कुल पूछताछ नहीं कर सकता और सबसे बड़ा टोकन_नंबर मांग सकता हूं। मुझे इस मंच पर एक जवाब मिला, लेकिन मुझे यकीन है कि SQL कथन निष्पादित करने के बजाय इसे करने का बेहतर तरीका होना चाहिए? Auto increment a non-primary key field in Ruby on Railsरेलों में एक ऑटो वृद्धि क्षेत्र उत्पन्न करें

उत्तर

12

मेरे लिए दिलचस्प सवाल। दुर्भाग्यवश, रेल ऑटो-वर्धित कॉलम का एक तरीका प्रदान नहीं करती है, इसलिए हमें छोटे स्वचालन के साथ एसक्यूएल का सहारा लेना चाहिए। मैं रेल 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 की संभावना स्थापित किया जा रहा है उपयोगकर्ता द्वारा मैन्युअल रूप से, हमें केवल टोकन_नंबर उत्पन्न करने की आवश्यकता होगी यदि इसे सेट नहीं किया जा रहा है। 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 

एक नमूना रन। कृपया ध्यान दें कि पहले टोकन के लिए मैं टोकन_नंबर सेट नहीं कर रहा हूं और यह टोकन_नंबर अनुक्रम उत्पन्न करता है और दूसरे के लिए मैं असाइन कर रहा हूं।

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

कॉलबैक का उपयोग करने से बचने के लिए किसी भी तरह से 'अगलीवाल' के साथ संयोजन में डिफ़ॉल्ट मान का उपयोग करना संभव है? – freemanoid

संबंधित मुद्दे