2015-12-07 29 views
7

Neden raylar bir oluşturmak döndü öğesinde otomatik artan sütunu doldurmuyor? Bunu yapmanın daha iyi bir yolu var mı? raylar iseNeden activerecord, oluşturulduktan döndürülen öğeye otomatik arttırma sütunu yerleştirmiyor?

, daha sonra a = Foo.create yaptığınızda a.id

doldurulur Ama
def up 
    execute "ALTER TABLE my_table ADD COLUMN my_auto_incrementing_column INTEGER AUTO_INCREMENT not null UNIQUE KEY;" 
end 

yoluyla oluşturulan bir alan varsa oluşturmak kullandığınızda Sonra bu alan görünmüyor. Ayrıca bir yeniden yükleme kullanmanız gerekir.

a = Foo.create 
a.id # not nil 
a.my_auto_incrementing_column # nil 
a.reload 
a.my_auto_incrementing_column # is now populated 

Sürüm bilgileri:

$ ruby -v 
ruby 1.9.3p484 (2013-11-22 revision 43786) [x86_64-darwin14.5.0] 
$ bundle exec rails -v 
Rails 3.2.12 
$ mysql --version 
mysql Ver 14.14 Distrib 5.6.26, for osx10.10 (x86_64) using EditLine wrapper 

Bazı arka plan: Bu kod tüm id alanları Uuıdlerin olmasını gerektirir büyük varolan içinde üretim raylar kod temeli uygulanıyor

. Auto_increment sütunu birincil anahtar değildir, çünkü yeni bir harici entegrasyon iş ortağımızın mevcut uzun benzersiz tanımlayıcılarımızı (UUID'ler) kullanarak işleyemediğini fark ettikten sonra eklenmiştir.

Biz yakut bizim sürümünü güncellemek için çalışıyoruz ama biz bu soruna bir çözüm olarak bunun için beklemek istemiyoruz. Ayrıca, activerecord'daki changelogları okuduktan sonra, ruby ​​/ rayların gelecekteki herhangi bir versiyonunun bu problem için bir hata düzeltmesi içerdiğini ispatlamıyorum.

Ben artırmak istiyorum kod:

class Foo < ActiveRecord::Base 
    has_one :object_containing_auto_incrementing_column 

    def my_method 
    if self.object_containing_auto_incrementing_column.nil? 
     self.object_containing_auto_incrementing_column = ObjectContainingAutoIncrementingColumn.create(owner: self) 
     self.object_containing_auto_incrementing_column.reload 
    end 
    self.object_containing_auto_incrementing_column.my_auto_incrementing_column 
    end 
end 
+0

Muhtemelen bir kopyası http://stackoverflow.com/a/9534482/531479 – CWitty

+0

@CWitty http://stackoverflow.com/questions/9513739/generate-an-auto-increment-field-in-rails/9534482 # 9534482 bu çözümü tasarlarken çok yardımcı oldu, ancak rayların neden bu hataya sahip olduğunu veya etrafından nasıl geçeceğini açıklamıyor. Ayrıca postgres dayanmaktadır, bu yüzden tavsiyelerin bazıları geçerli olmayan sözdizimine sahiptir. – compiledwrong

+1

Lütfen, 'CREATE TABLE CREATE' tablosunun nasıl göründüğünü düşünüyor. Kodunuzun söylediklerinin doğru bir şekilde tercüme edildiğini görmek istiyorum. –

cevap

2

o ActiveRecord otomatik artan sütunları doldurmak için çalıştığı görünmüyor source code baktıktan sonra. Sadece #id özniteliği ve başka hiçbir şey INSERT deyimi tarafından döndürülen değeri atar. iki kez DB vurmadan my_auto_incrementing_column doldurmak istiyorsanız

# ActiveRecord:: Persistence::ClassMethods 
def create 
# ... 
    self.id ||= new_id if self.class.primary_key 
# ... 
end 

, ben ActiveRecord kendisi yama etrafında bir yolu yoktur düşünüyorum.

# Returns the last auto-generated ID from the affected table. 
    # 
    # +id_value+ will be returned unless the value is nil, in 
    # which case the database will attempt to calculate the last inserted 
    # id and return that value. 
    # 
    # If the next id was calculated in advance (as in Oracle), it should be 
    # passed in as +id_value+. 
    def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) 
    sql, binds = sql_for_insert(to_sql(arel, binds), pk, id_value, sequence_name, binds) 
    value  = exec_insert(sql, name, binds) 
    id_value || last_inserted_id(value) 
    end 

söz konusu sizin alanını doldurmak için geçerli API değiştirmek için herhangi bir önemsiz bir yol yoktur olmayabilir:

bir insert method nasıl uygulandığını de bakın.

İlgili konular