2017-10-19 62 views
0

我試圖從FTP服務器下載CSV文件,如果記錄存在,我想更新該記錄而不創建重複。爲了提供更多的上下文 - 我試圖從FTP文件夾上傳一組訂單到我的Rails應用程序中。每小時都會有一個新文件 - 有時,某個下拉菜單中的訂單包含前一個下拉菜單中的重複項,以防止人們滑過軌道,或者有時訂單已由客戶更新(更改數量,更改地址等)下一滴。所以我的問題是,如果訂單純粹是重複的,沒有改變,我怎麼能跳過這些訂單,如果記錄已經改變,我該如何更新該記錄?使用Ruby on Rails從FTP下載CSV文件並更新現有記錄

Ruby on Rails 5.1.4 - Ruby 2.4.1

謝謝!

下面的代碼是從我的模型:

class Geek < ApplicationRecord 
require 'csv' 

def self.download_walmart_orders(out) 
    out ||= "#{Rails.root}/test_orders.csv" 
     CSV.foreach(out, :headers => true, 
        :converters => :all, 
        :header_converters => lambda { |h| h.downcase.gsub(' ', '_') } 
       ) do |row| 
    geek = Geek.where(customer_order_id: row.to_h["customer_order_id"], 
            customer_name: row.to_h["customer_name"], 
            item_sku: row.to_h["item_sku"], 
            quantity_to_ship: row.to_h["quantity_to_ship"], 
            total_items_price: row.to_h["total_items_price"]).first_or_create 
    puts geek 
end  
end 

+1

聽起來很酷。你有問題嗎? – jvillian

+0

在Rails 5中你想使用['find_or_create_by'](http://api.rubyonrails.org/classes/ActiveRecord/Relation.html#method-i- find_or_create_by)。 – max

+0

嗨jvillian,我爲這個不好的措辭表示歉意,我剛剛編輯了這個問題,希望能夠提供一些我的問題更加清晰的問題。 Hi Max - 如果我沒有更新,它看起來會很好地將數據帶入。到現有的記錄。如果我確實需要更新現有記錄,應該如何使用? (問題被翻譯成頂部給出一個更好的例子) –

回答

2

我假設customer_order_id是獨一無二的。

你可以嘗試這樣的事情 -

def self.update_or_create(attributes) 
    assign_or_new(attributes).save 
    end 


    Geek.where(customer_order_id: row.to_h["customer_order_id"]).update_or_create.( 
           customer_name: row.to_h["customer_name"], 
           item_sku: row.to_h["item_sku"], 
           quantity_to_ship: row.to_h["quantity_to_ship"], 
           total_items_price: row.to_h["total_items_price"]) 

^^^謝謝你,邁克爾,對於上面的方向。我結束了使用這個代碼,它完美的工作。 (對於一個稍微不同的項目,但完全相同的用例)我最終確定模型代碼如下:

class Wheel < ApplicationRecord 
require 'csv' 

def self.update_or_create(attributes) 
    obj = first || new 
    obj.assign_attributes(attributes) 
    obj.save! 
end 

def self.import(out) 
    out ||= "#{Rails.root}/public/300-RRW Daily Inv Report.csv" 
     CSV.foreach(out, :headers => true, 
        :converters => :all, 
        :header_converters => lambda { |h| h.downcase.gsub(' ', '_') } 
       ) do |row| 
    Wheel.where(item: row.to_h["item"]).update_or_create(
            item_desc: row.to_h["item_desc"], 
            total_quantity: row.to_h["total_quantity"]) 
    end 
end 

+0

這絕對會讓我走向正確的方向。謝謝你,邁克爾,所有的幫助! –

+0

很高興能幫到你! :)請確認接受答案:D –