2009-04-23 27 views
122

Tôi không thể tìm thấy bất kỳ tài liệu nào về phương thức .build trong Rails (tôi hiện đang sử dụng 2.0.2).Ruby on Rails. Làm thế nào để sử dụng phương thức Active Record .build trong một: thuộc về mối quan hệ?

Thông qua thử nghiệm có vẻ như bạn có thể sử dụng phương pháp xây dựng để thêm bản ghi vào mối quan hệ has_many trước khi bản ghi đã được lưu.

Ví dụ:

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 

này sẽ tiết kiệm được cả hai con chó và thẻ với các phím nước ngoài đúng cách. Điều này dường như không hoạt động trong mối quan hệ belongs_to.

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

Tôi cũng đã cố gắng

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

Chìa khóa nước ngoài tại Dog không được thiết lập trong trường hợp này là do thực tế là vào thời điểm đó nó được lưu lại, người mới không có một id vì nó chưa được lưu.

Câu hỏi của tôi là:

  1. Làm thế nào để xây dựng công trình để Rails là đủ thông minh để tìm ra cách để lưu hồ sơ theo thứ tự đúng?

  2. Tôi có thể làm điều tương tự như thế nào trong mối quan hệ belongs_to?

  3. Tôi có thể tìm thấy bất kỳ tài liệu nào về phương pháp này?

Cảm ơn bạn

+0

Về tài liệu, xem Rails Hướng dẫn [_ "Các phương pháp bổ sung bởi' belongs_to'" _] (http://guides.rubyonrails.org/association_basics.html#methods-added-by-belongs-to) và [_ "Phương thức được thêm bởi' has_one' "_] (http://guides.rubyonrails.org/association_basics.html#methods-added-by-has-one). Bạn có thể tìm thấy tài liệu kỹ thuật khác trong tài liệu API: ['attribute_to'] (http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-belongs_to) và [' has_one'] (http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_one). – Dennis

Trả lời

140

đâu nó được ghi chép lại:

Từ tài liệu API thuộc hiệp hội has_many trong "Module ActiveRecord::Associations::ClassMethods"

collection.build (thuộc tính = {}, ...) Trả lại một hoặc nhiều đối tượng mới của loại bộ sưu tập đã được khởi tạo với các thuộc tính và được liên kết với đối tượng này thông qua khóa ngoài , nhưng chưa được lưu . Lưu ý: Điều này chỉ hoạt động nếu một đối tượng liên quan đã tồn tại, không phải là nếu nó không đúng!

Câu trả lời để xây dựng theo hướng ngược lại là cú pháp hơi bị thay đổi. Trong ví dụ của bạn với những con chó,

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") 

hoặc thậm chí

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

Bạn cũng có thể sử dụng create_dog để có nó lưu ngay lập tức (giống như tương ứng "tạo ra" phương pháp bạn có thể gọi vào bộ sưu tập)

Đường ray đủ thông minh như thế nào? Đó là ma thuật (hoặc chính xác hơn, tôi không biết, rất thích tìm hiểu!)

+4

@BushyMark: nó sử dụng method_missing hoặc metaporgramming để thêm các phương thức đó với define_method. – Federico

+0

@ Federico là phương pháp thiếu định nghĩa? – efoo

+1

@ alock27 Giống như cách ActiveRecord sử dụng phương thức thiếu cho phương thức 'find_by_email' và' find_by_column_name' của bạn. Nó chuyển đổi phương thức bạn chuyển sang một chuỗi và phân tách nó và cố gắng kết hợp nó với tên cột của bảng. – Edmund

40
@article = user.articles.build(:title => "MainTitle") 
@article.save 
+0

>> d.tags.build (: number => "123456") >> d.save # => true Không phải tương tự? – antiqe

Các vấn đề liên quan