Raylar üzerinde yakut. Active Record .build yöntemini a: ilişkiye aittir?


129

Rails'de .build yöntemiyle ilgili herhangi bir belge bulamadım (şu anda 2.0.2 kullanıyorum).

Deneme yoluyla, has_manyher iki kayıt da kaydedilmeden önce bir ilişkiye kayıt eklemek için inşa yöntemini kullanabileceğiniz görülüyor .

Örneğin:

class Dog < ActiveRecord::Base
  has_many :tags
  belongs_to :person
end

class Person < ActiveRecord::Base
  has_many :dogs
end

# rails c
d = Dog.new
d.tags.build(:number => "123456")
d.save # => true

Bu, hem köpeği hem de etiketi yabancı anahtarlarla doğru şekilde kaydedecektir. Bu bir belongs_toilişkide işe yaramıyor gibi görünüyor .

d = Dog.new
d.person.build # => nil object on nil.build

Ben de denedim

d = Dog.new
d.person = Person.new
d.save # => true

Yabancı anahtar Dog, kaydedildiği anda yeni kişinin henüz kaydedilmediğinden bir kimliği olmadığı için bu durumda ayarlanmamıştır.

Sorularım:

  1. Rails'in kayıtların doğru sırayla nasıl kaydedileceğini anlayacak kadar akıllı olması için nasıl inşa edilir?

  2. Bir belongs_toilişkide aynı şeyi nasıl yapabilirim ?

  3. Bu yöntemle ilgili herhangi bir belgeyi nerede bulabilirim?

teşekkür ederim


Belgeleri ile ilgili olarak, Raylar Kılavuzları bkz "tarafından eklenen Yöntemler belongs_to" ve "tarafından Yöntemleri Eklendi has_one" . API belgelerinde daha fazla teknik belge bulunabilir: belongs_tove has_one.
Dennis

Yanıtlar:


148

Belgelendiği yer:

" Module ActiveRecord :: Associations :: ClassMethods " içindeki has_many ilişkilendirmesi altındaki API belgelerinden

collection.build (attributes = {},…) Özniteliklerle somutlaştırılmış ve bu nesneye bir yabancı anahtar aracılığıyla bağlanmış, ancak henüz kaydedilmemiş olan koleksiyon türünde bir veya daha fazla yeni nesne döndürür. Not: Bu yalnızca ilişkili bir nesne zaten mevcutsa çalışır, sıfırsa değil!

Ters yönde inşa etmenin cevabı biraz değiştirilmiş bir sözdizimidir. Köpeklerle olan örneğinizde,

Class Dog
   has_many :tags
   belongs_to :person
end

Class Person
  has_many :dogs
end

d = Dog.new
d.build_person(:attributes => "go", :here => "like normal")

ya da

t = Tag.new
t.build_dog(:name => "Rover", :breed => "Maltese")

Ayrıca, anında kaydettirmek için create_dog'u da kullanabilirsiniz (koleksiyonda çağırabileceğiniz karşılık gelen "oluştur" yöntemine çok benzer)

Raylar nasıl yeterince akıllı? Bu sihir (veya daha doğrusu, bilmiyorum, öğrenmek isterim!)


4
@BushyMark: define_method ile bu yöntemleri eklemek için method_missing veya metaporgramming kullanır.
Federico

@Federico eksik yöntem nerede tanımlanmıştır?
awilkening

1
@ alock27 ActiveRecord'un sizin find_by_emailve find_by_column_nameyöntemleriniz için eksik olan yöntemi kullandığı ile aynı . Aktardığınız yöntemi bir dizeye dönüştürür ve parçalara ayırır ve tablonuzun sütun adlarıyla eşleştirmeye çalışır.
bigpotato

@edmund Yorumunuz için teşekkürler. Açık olmak gerekirse, method_missing'in nasıl çalıştığını anlıyorum. Bu belirli yöntemi tanımlayan dosyanın gerçek konumunu bulmaya çalışıyordum.
2013

@ alock27 eğer soruyorsanız, çünkü nasıl tanımlandığına bakmak istiyorsanız Metaprogramming Ruby'ye göz atmalısınız. Ancak, gerçek konumu gerçekten arıyorsanız, muhtemelen kaynak kodu için Google'da arama yapabilirsiniz.
MCB

48
@article = user.articles.build(:title => "MainTitle")
@article.save

>> d.tags.build (: number => "123456") >> d.save # => true Aynı değil mi?
antiqe
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.