2012-01-13 28 views
22

Tôi đã cố gắng thu hút sự chú ý của mình về các liên kết ActiveRecord nhưng tôi đã đánh một chút tường gạch và không có vấn đề bao nhiêu tôi xem xét tài liệu ActiveRecord. làm thế nào để giải quyết vấn đề của tôi.Tạo hoặc cập nhật liên kết ActiveRecord has_one

Tôi có hai lớp:

Property -> has_one :contract 
Contract -> belongs_to :property 

Trong lớp hợp đồng của tôi, tôi có một phương pháp để create_or_update_from_xml

Trước tiên tôi kiểm tra để đảm bảo tài sản trong câu hỏi tồn tại.

property_unique_id = xml_node.css('property_id').text 
     property = Property.find_by_unique_id(property_unique_id) 
     next unless property 

Và đây là nơi tôi gặp khó khăn, tôi có một hash của thuộc tính cho các hợp đồng, và những gì tôi muốn làm là một cái gì đó như:

if property.contract.nil? 
    # create a new one and populate it with attributes 
else 
    # use the existing one and update it with attributes 

tôi biết làm thế nào tôi sẽ đi về nó nếu nó là SQL thô, nhưng tôi không thể có được đầu của tôi xung quanh cách tiếp cận ActiveRecord hte.

Bất kỳ gợi ý nào qua khối đường này sẽ được đánh giá cao.

Xin cảm ơn trước.

Trả lời

33
if property.contract.nil? 
    property.create_contract(some_attributes) 
else 
    property.contract.update_attributes(some_attributes) 
end 

Nên thực hiện thủ thuật. Khi bạn có liên kết has_one hoặc belongs_to thì bạn sẽ nhận được các phương thức build_foocreate_foo (giống như Foo.new và Foo.create). Nếu hiệp hội đã tồn tại thì property.contract về cơ bản chỉ là một đối tượng bản ghi hoạt động bình thường.

+0

Nhờ đó, các công trình hoàn hảo. –

+0

có thể sử dụng trống không? – Dan

7
Property.all.each do |f| 
    c = Contract.find_or_initialize_by(property_id: f.id) 
    c.update(some_attributes) 
end 

Tôi không biết liệu đây là giải pháp tốt nhất, nhưng đối với tôi nó ngắn gọn hơn

9

Chỉ cần một cách khác để làm việc đó bằng ruby ​​OR-Equal lừa

property.contract ||= property.build_contract 
property.contract.update_attributes(some_attributes) 
+2

Khi bạn gán một đối tượng cho một liên kết has_one, đối tượng đó được lưu tự động, có thể phá vỡ các xác nhận hợp lệ. http://guides.rubyonrails.org/association_basics.html#has-one-association-reference sử dụng property.build_contract trừ khi property.contract thay thế. –

+0

Đây là câu trả lời hay nhất, nên được chấp nhận. – ZedTuX

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