Rails проталкивает в массив сохраняет объект

У меня есть интересная проблема. Я использую Ruby 1.9.2 и Rails 3.1.3.

У меня есть две модели, для упрощения скажем, покупатели и магазины. У магазинов много покупателей, а покупатель принадлежит к магазину. Я пытаюсь собрать всех покупателей для магазина и создать место для еще нескольких, чтобы потом заполнить их значениями. Вместо этого вызывается customer.save, когда я этого не ожидаю.

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

По какой-то причине, когда клиент помещается в массив, вызывается customer.save. Этого не произойдет, если вы передадите массиву простой массив, а не отношение.

Я нашел обходной путь, но мне все еще интересно, почему это происходит. Обходной путь:

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
 blu09 сент. 2014 г., 19:07
Для тех, кто ищет решение, а не почему: используйтеbuild в коллекции для создания модели без ее сохранения:api.rubyonrails.org/classes/ActiveRecord/Associations/…
 CJBrew01 нояб. 2015 г., 19:03
У меня была противоположная проблема. С помощьюbuild в спецификации модели добавление элементов в коллекцию с помощью & lt; & lt; не работал. Ответы на этот вопрос объясняют, почему нет.

Ответы на вопрос(2)

<< это псевдоним дляpush

http://apidock.com/rails/ActiveRecord/Associations/CollectionProxy/%3C%3C http://apidock.com/rails/ActiveRecord/Associations/CollectionProxy/push

который вActiveRecord::Associations::CollectionProxy звонкиconcat

http://apidock.com/rails/ActiveRecord/Associations/CollectionAssociation/concat (view the source of the method) https://github.com/rails/rails/blob/master/activerecord/lib/active_record/associations/collection_proxy.rb#L283

какие звонкиconcat_records

http://apidock.com/rails/v3.2.3/ActiveRecord/Associations/CollectionAssociation/concat_records

где вы можете увидеть вставку происходит.

Итак, с существующей записью(persisted into the database), Бег<< или же.push вставит записи в коллекцию, сохранив их при необходимости в базе данных. призвание<< в массиве, а не в коллекции записей, как вы это делаете в

random_array << customer

вызывает Руби<< Метод массива, а не эквивалент AR(as you found, no save takes place in this case).

Edit: Чтобы было ясно, обходной путь, который вы нашли, заключается в том, как я обычно справляюсь с ситуацией, с которой вы сталкиваетесь; мой ответ больше фокусируется наwhy << имеет такое поведение.

(вашего исходного кода) на:

customers_array = store.customers.to_a

Это приводит к активному связыванию записей с реальным объектом массива, поэтому<< Метод будет обычным методом Array # push.

Ваш ответ на вопрос