"Referanslar" geçişinde sütun adı belirtme


124

migrationBaşka bir tabloya başvurarak bir in Rails yapmak istiyorum . Genellikle şöyle bir şey yapardım:

add_column :post, :user, :references

Bu adlı bir sütun oluşturur user_idiçinde postsmasaya. Ama ya bunun yerine user_idşöyle bir şey istersem author_id? Bunu nasıl yapabilirim?

Yanıtlar:


59

Manuel olarak yapın:

add_column :post, :author_id, :integer

ama şimdi, aittir_to ifadesini yarattığınızda, onu değiştirmeniz gerekecek, bu yüzden şimdi aramanız gerekecek

def post
    belongs_to :user, :foreign_key => 'author_id'
end

1
Herhangi bir dizin eklememe gerek yok mu?
caarlos 0

1
Evet, taşıma sırasında bir dizin oluşturmanız gerekecek.
Tom Harrison

1
Rails hileleri - varsayılan olarak indeksleri gerçekten kullanmaz. Şimdi, indeksler istiyorsanız (ki bu harika bir fikir - rayların tamamen görmezden gelmesine rağmen), onları kesinlikle ekleyebilirsiniz. Genel olarak geçişler hakkında daha fazla bilgi için bağladığım kılavuza göz atmak isteyeceksiniz ve hatta SQL kodunu doğrudan geçiş işleminize eklemeye başlayabilirsiniz. Bunu görmezden gelin derim, rayların normal bir parçası olmadığı için bundan 0 performans elde edersiniz, çünkü rayların varsayılan olarak oluşturulmuş SQL sorguları bundan faydalanmaz. bağlantı
mschultz

hmm anlaşıldı. Çok teşekkür ederim!
caarlos 0

schema_plusgem kullanarak , t.references :category, index: true, foreign_key: true, references: :match_categoriesgöç dosyasında da benim için çalıştı.
elquimista

251

Raylar için 5+

İlk Tanım:

Eğer tanımlıyorsanız Postmodeli tablo, ayarlayabilirsiniz references, indexve foreign_keytek satırda:

t.references :author, index: true, foreign_key: { to_table: :users }

Mevcut Olanı Güncelle:

Mevcut bir tabloya referans ekliyorsanız, bunu yapabilirsiniz:

add_reference :posts, :author, foreign_key: { to_table: :users }

Not: için varsayılan değer indextrue.


İlk tanım boş değerlere izin verecek mi? Değilse, null yapılabilir alternatifi biliyor musunuz?
Vorpulus Lyphane

5
Bu tanım, nulls. Bunlara izin vermemek için normal seçeneği ekleyin null: false.
Ashitaka

Teşekkürler. "İlk Tanım" için "dizin: doğru" nun gerekli olmadığını düşünüyorum. Onunla veya onsuz aynı şema değişikliğini elde ederim. Boşver; sonunda notunuzu gördüm.
Joey

Teşekkürler, aradığım şey buydu!
Philippe B.

250

Gelen Raylar 4.2+ da ayarlayabilirsiniz yabancı anahtarlar , hem de db harika bir fikir olan .

Basit ilişkilendirmeler için bu, t.referencesekleme foreign_key: truesırasında da yapılabilir , ancak bu durumda iki satıra ihtiyacınız olacak.

# The migration
add_reference :posts, :author, index: true
add_foreign_key :posts, :users, column: :author_id

# The model
belongs_to :author, class_name: "User"

2
Teşekkürler, ama soru Rails3 olarak etiketlendi, yardımcı olmaktan mutluluk
duyarım

2
Ooh, bunu fark etmedim. Peki, to.me çok yardımcı oldu. :)
bonh

2
Bunu gördüğümde neredeyse umudumu yitirdim! @Ecoologic teşekkür ederiz!
Dan Williams

2
@ecoologic, eklemek isteyebileceğiniz tek şey, add_foreign_key yalnızca 4.2+ raylardır. ;)
Dan Williams

4
Görüşmede references: :usersseçeneğe ihtiyacınız olduğundan emin değilim add_reference. Dokümanlarda belgelendiğini görmüyorum ve benim tarafımda onsuz işe yarıyor gibi görünüyor.
jakecraige

87

Raylarda 4, postgresql ve schema_plus gem kullanırken sadece yazabilirsiniz

add_reference :posts, :author, references: :users

Bu, author_iddoğru şekilde başvuran bir sütun oluşturacaktır users(id).

Ve modelinde yazarsın

belongs_to :author, class_name: "User"

Unutmayın, yeni bir tablo oluştururken aşağıdaki gibi yazabilirsiniz:

create_table :things do |t| 
  t.belongs_to :author, references: :users 
end 

Not: schema_plusgem bütünüyle 5+ raylarıyla uyumlu değildir, ancak bu işlevsellik, raylar 5 ile uyumlu gem schema_auto_foreign_keys ( schema_plus'ın bir parçası) tarafından sunulmaktadır .


28
ve kullanıyorsanız create_table:t.references :author, references: :users
Michael Radionov

2
@ MichaelRadionov'un yorumunu cevabınıza eklemek onu mükemmel hale getirecektir.
toxaq

2
Rails 4.1 kaynağına bakıyordum ve :referencesgerçekten bir şey yapan herhangi bir kanıt bulamıyorum .
jes5199

1
Evet haklısınız, schema_plusmücevheri yıllardır kullanıyorum ve aslında bu işlevselliği ekliyor. Cevabımı buna göre düzenledim.
nathanvda

2
Rails 6'da, sözdizimi t.references :col_name, references: other_table_namefazladan mücevher yüklemeden çalışıyor gibi görünüyor .
Qqwy

51

Yabancı anahtar kullanmıyorsanız, diğer tablonun gerçek tablo adının ne olduğu önemli değildir.

add_reference :posts, :author

Rails 5'ten itibaren , yabancı anahtar kullanıyorsanız, yabancı anahtar seçeneklerinde diğer tablonun adını belirtebilirsiniz. ( tartışma için bkz https://github.com/rails/rails/issues/21563 )

add_reference :posts, :author, foreign_key: {to_table: :users}

Rails 5'ten önce yabancı anahtarı ayrı bir adım olarak eklemelisiniz:

add_foreign_key :posts, :users, column: :author_id

12
to_table çoğullaştırılmış biçimdir:{to_table: :users}
hoffmanc

-3

alias_attribute (yeni_adı, eski_adı) çok kullanışlıdır. Sadece modelinizi ve ilişkinizi oluşturun:

rails g model Post title user:references

daha sonra modeli düzenleyin ve bir özellik takma adı ekleyin

alias_attribute :author, :user

Bundan sonra aşağıdaki gibi şeyler çalıştırabileceksiniz

Post.new(title: 'My beautiful story', author: User.first)

1
başka bir modele birden çok referans tanımlamanız gerektiğinde bu işe yaramaz, örneğin gönderi (yazar, editör)
ultrajohn
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.