Rails 4 загрузка CSV в несколько моделей
Я пытаюсь загрузить csv-файл, содержащий данные, принадлежащие двум различным моделям: Project
и PurchaseOrder
. Я использую отношение has_many, :through
между моделями.
У меня возникли проблемы с загрузкой. Я внес в белый список общие атрибуты в обоих контроллерах и включил accepts_nested_attributes
в обе модели.
Вот мой код для чтения в csv.
def self.import(file)
CSV.foreach(file.path, headers: true) do |row|
project_hash = row.to_hash
project = Project.where(project_name: project_hash["project_number"]).first
if project.present?
project.first.update_attributes(project_hash)
else
Project.create! (project_hash)
end
purchase_order = PurchaseOrder.where(po_number: project_hash["po_number"]).first
if purchase_order.present?
PurchaseOrder.create!
end
У меня есть два вопроса/проблемы.
-
Я не могу читать в атрибуте
po_number
. Я получаю эту ошибкуunknown attribute 'po_number' for Project
. -
Я не знаю, как поместить созданный заказ на покупку в хэш проекта, чтобы он обновил вложенное значение атрибута.
Заранее спасибо всем, кто может помочь!
**** обновление С помощью этого метода данные сохраняются в правильные таблицы. Однако связь между покупкой заказа и проектом не сохраняется. Есть какие-нибудь мысли?
def self.import(file)
CSV.foreach(file.path, headers: true) do |row|
project_hash = row.to_hash
po_hash = {}
po = PurchaseOrder.new
project_hash.each { |k, v| po_hash[k] = project_hash.delete(k) if po.respond_to?(k) }
project = Project.where(project_name: project_hash["project_number"]).first
if project.present?
project.first.update_attributes(project_hash)
else
Project.create! (project_hash)
end
po = PurchaseOrder.where(po_number: po_hash["po_number"]).first
if po.present?
po.first.update_attributes(po_hash)
else
PurchaseOrder.create! (po_hash)
end
end
end
1 ответ:
Эти строки пытаются обновить / создать проект, используя все значения в хэше...
project.first.update_attributes(project_hash) ... Project.create! (project_hash)
Но очевидно, что некоторые хэш-элементы (такие как "po_number") не имеют столбцов в таблице проектов.
Вам нужно разделить элементы хэша csv на основе того, какие элементы принадлежат к какой модели...
Например
po_hash = {} po = PurchaseOrder.new project_hash.each { |k, v| po_hash[k] = project_hash.delete(k) if po.respond_to?(k) }
Это позволит удалить поля заказа на покупку из
project_hash
и добавить их вpo_hash
, чтобы вы могли использовать правильный хэш для обновления правильного стол.Для создания ассоциации...
Изменение
Project.create!(project_hash)
В
project = Project.create!(project_hash)
Таким образом, независимо от того, существует ли проект или создается заново, он хранится в переменной "project". Аналогично, сделайте
po = PurchaseOrder.create!(po_hash)
Затем, после того как вы создали или обновили заказ на покупку, вы можете просто назначить po проекту...
project.purchase_orders << po