2012-06-15 41 views
11

Tôi có một vấn đề thú vị. Tôi đang sử dụng Ruby 1.9.2 và Rails 3.1.3.Đường ray đẩy vào mảng lưu đối tượng

Tôi có 2 mô hình, để đơn giản hóa giả sử khách hàng và cửa hàng. Các cửa hàng có nhiều khách hàng và khách hàng thuộc về một cửa hàng. Tôi đang cố gắng thu thập tất cả các khách hàng cho một cửa hàng và tạo một địa điểm cho một vài thứ nữa để tôi có thể điền các giá trị sau này. Thay vào đó, customer.save được gọi khi tôi không mong đợi nó.

store = Store.find(1) 
customers_array = store.customers 
random_array = Array.new 
customers_count = customers_array.count + 1 

(customers_count..2).each do |i| 
    customer = Customer.new 
    c.id = "#{i}000000000000" 
    random_array << customer # this line doesn't call customer.save 
    customers_array << customer # this line calls customer.save when store has customers 
end 

Vì lý do nào đó khi khách hàng được đưa vào mảng, customer.save được gọi. Nó không xảy ra nếu bạn đẩy vào một mảng là một mảng đơn giản và không phải là một mối quan hệ.

Tôi đã tìm được cách giải quyết, nhưng tôi vẫn tự hỏi tại sao điều đó lại xảy ra. Cách giải quyết:

store = Store.find(1) 
initial_customers_array = store.customers 
additional_customers_array = Array.new 
customers_count = initial_customers_array.count + 1 

(customers_count..2).each do |i| 
    customer = Customer.new 
    c.id = "#{i}000000000000" 
    additional_customers_array << customer 
end 
customers_array = initial_customers_array + additional_customers_array 
+1

Đối với những người tìm kiếm giải pháp chứ không phải lý do: sử dụng '' 'build''' trên bộ sưu tập để tạo mô hình mà không lưu nó: http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods .html # module-ActiveRecord :: Hiệp hội :: ClassMethods-label-Collections – blu

+0

Tôi đã có vấn đề ngược lại. Sử dụng 'build' trong các thông số kỹ thuật mô hình, sau đó thêm các mục vào một bộ sưu tập bằng cách sử dụng << không hoạt động. Câu trả lời cho câu hỏi này giải thích tại sao không. – CJBrew

Trả lời

21

<< là một bí danh cho push

mà trong ActiveRecord::Associations::CollectionProxy cuộc gọi concat

trong đó kêu gọi concat_records

nơi bạn sẽ nhìn thấy chèn diễn ra.

Như vậy, với một kỷ lục hiện (vẫn kiên trì vào cơ sở dữ liệu), chạy << hoặc .push sẽ chèn các bản ghi vào bộ sưu tập, sự bền bỉ họ đến cơ sở dữ liệu nếu cần thiết. Gọi << trên một mảng, không phải là bộ sưu tập kỷ lục, như bạn đang làm trong

random_array << customer 

gọi phương thức << Mảng Ruby, không phải là AR tương đương (như bạn thấy, không tiết kiệm diễn ra trong trường hợp này).

Chỉnh sửa: Để rõ ràng, cách khắc phục bạn tìm thấy ít nhiều là cách tôi thường xử lý tình huống bạn đang xử lý; câu trả lời của tôi tập trung nhiều hơn vào số lý do tại sao<< có hành vi này.

3

Một khoảng cách này sẽ được thay đổi dòng thứ hai của bạn (mã ban đầu của bạn) tới:

customers_array = store.customers.to_a 

Đó phôi Hiệp hội kỷ lục hoạt động đến một đối tượng mảng thực, vì vậy phương pháp << sẽ là bình thường Phương pháp đẩy # mảng.

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