2012-09-04 99 views
2

我有2場=>型號:名稱和:年齡移民設置主鍵的值0和自動遞增的PostgreSQL

我需要做的遷移是添加列:位置,這需要自動增量和啓動與0(零)。

我嘗試這些方法:

class AddPosition < ActiveRecord::Migration 
    def up 
    add_column :clientes, :position, :integer, :default => 0, :null => false 
    execute "ALTER TABLE clientes ADD PRIMARY KEY (position);" 
    end 

但它不工作,因爲它不會自動遞增。如果我嘗試使用主鍵作爲類型:

class AddPosition < ActiveRecord::Migration 
    def up 
    add_column :clientes, :position, :primary_key, :default => 0, :null => false 
    end 
end 

rake db:migrate不會運行,因爲有多個值。

任何人都可以解釋在主鍵w/Rails 3.2上有零和自動增量的方法嗎?

回答

2

下面是你可以在PostgreSQL設置自動遞增列:

# in migration: 
def up 
    execute <<-SQL 
    CREATE SEQUENCE clients_position_seq START WITH 0 MINVALUE 0; 
    ALTER TABLE clients ADD COLUMN position INTEGER NOT NULL DEFAULT nextval('clients_position_seq'); 
    SQL 
end 

但不幸的是它可能不是你所需要的。如果你想用如下的SQL將值插入clients表中,上面的方法是有效的:INSERT INTO clients(name, age) VALUES('Joe', 21),並且rails不能這樣工作。

第一個問題是rails期望主鍵被稱爲id。雖然你可以重寫這個約定,但它會導致比解決問題更多的問題。如果你要綁定位置,主鍵值,更好的選擇是虛擬的屬性添加到您的模型,這樣的方法:

def position 
    id.nil? ? nil : id - 1 
end 

但是讓我們假設你已經有傳統的主鍵id並希望添加position場這樣你就可以在客戶創建後重新排列客戶,沒有觸摸他們的ID(這總是一個好主意)。第二個問題是:rails無法識別並尊重DEFAULT nextval('clients_position_seq'),即它不會從PG支持的序列中提取值,並會默認將NULL置於position

我想建議看看acts_as_list gem作爲更好的選擇。這會使DB序列操作變得不必要。不幸的是,它使用1作爲position的初始值,但是可以通過爲列表位置字段設置自定義名稱並按照上面顯示的定義方法來解決該問題。

相關問題