簡體   English   中英

使用Ruby on Rails導入CSV

[英]Import CSV with Ruby on Rails

我想導入Outlook CSV文件並理想地基於電子郵件(子)檢查重復項,然后再創建或保存任何模型(“聯系人”-“父”或“電子郵件-子”)

步驟( 當前工作方式,但有缺陷的解決方案

  1. 導入文件-我保存文件
  2. 將每個行解析為字段
  3. 執行檢查電子郵件地址的唯一性(在保存父記錄-聯系人之前,我正在保存電子郵件記錄以進行此操作)。

*問題:
4.因此,在我保存電子郵件地址記錄的那一刻,它丟失了聯系人ID /所有者-如果在創建聯系人之前該過程失敗,則可能會導致孤立情況發生,因為它在保存聯系人之前保存了子(電子郵件)(和我不認為或不想這樣做)

  1. 但是,如果僅根據姓名(例如David Smith)保存聯系人,則可能有:

    • 並根據姓名進行檢查-在某些情況下,我認識2個同名的人(例如David Smith,然后會將2個不同的人加在一起)
    • 如果我保存了所有聯系人(然后檢查電子郵件的唯一性),則將創建很多額外的聯系人。
  2. 由於當前有效,因此檢查重復的電子郵件在我的整個數據庫中,因為我沒有contact_id(要與user_id或owner_id關聯)

  3. 我嘗試先保存聯系人,但后來意識到這導致我有很多額外的記錄(非常混亂)。

這是我的代碼來初始化行


  def process_row(smart_row)
    new_contact, existing_records = smart_row.to_contact

    self.contact = ContactMergingService.new(csv_file.user, new_contact, existing_records).perform
    log_processed_contacts new_contact
    init_contact_info self.contact
    self.contact.required_salutations_to_set = true # will be used for envelope/letter saluation
    if contact.first_name || contact.last_name || contact.email_addresses.first || contact.phone_numbers.first
      self.contact.save!
      csv_file.increment!(:total_imported_records)
    end
  end

這是上面調用的第一種方法(在保存聯系人之前先保存電子郵件)


   def to_contact
      existing_emails = existing_phone_numbers = nil
      contact = Contact.new.tap do |contact|
        initiate_instance(contact, CONTACT_MAPPING)
        address = initiate_instance(Address.new, ADDRESS_MAPPING)
        contact.addresses << address if address
        email_addresses, existing_emails = initialize_emails(EMAIL_ADDRESS_FIELDS)
        contact.email_addresses << email_addresses
        phone_numbers, existing_phone_numbers = initialize_phone_numbers(PHONE_TYPE_MAPPINGS)
        contact.phone_numbers << phone_numbers
        contact
      end
      existing_records = []
      existing_records << existing_emails
      existing_records << existing_phone_numbers
      existing_records.flatten!
      existing_records.compact!
      [contact,  existing_records]
    end

這是我保存電子郵件地址時的代碼(此后我保存聯系人)


def initialize_emails email_fields
  email_addresses = []
  email_fields.each do |field|
    value = evaluate_value field
    if value.present?
      new_email = EmailAddress.find_or_create_by(email: value, primary: (primary_email_field?(field)))
      if new_email.save
        email_addresses << new_email
      end
    end
  end
  existing_emails = email_addresses.select{ |email_address| email_address.owner_id.present?}
  [email_addresses, existing_emails]
end

我有3種型號:

User (has many)
  has_many :contacts
  has_many :email_campaigns  has_many :email_messages

Contacts:  First Name and Last Name
  belongs_to :user, counter_cache: true
  has_many :addresses, as: :owner, dependent: :destroy
  has_many :phone_numbers, as: :owner, dependent: :destroy
  has_many :email_addresses, as: :owner, dependent: :destroy
  accepts_nested_attributes_for :email_addresses, allow_destroy: true
``
Email:  email_address - polymorphic
  belongs_to :owner, polymorphic: true, touch: true

所以我的問題是:

  • 我是否需要保存記錄(聯系人或電子郵件)才能檢查重復項?
  • 有沒有一種方法可以處理CSV文件,從而可以在創建聯系人記錄或電子郵件地址記錄之前基於email_address檢查重復項? 我想根據contact.first_name,contact.last_name,email.address對現有數據庫和文件中的其他記錄檢查重復項

有什么想法嗎? 非常感謝。 安妮

我是否需要保存記錄(聯系人或電子郵件)才能檢查重復項?

不,只需將它們存儲在變量中

有沒有一種方法可以處理CSV文件,從而可以在創建聯系人記錄或電子郵件地址記錄之前基於email_address檢查重復項? 我想根據contact.first_name,contact.last_name,email.address對現有數據庫和文件中的其他記錄檢查重復項

find_or_create_by專門用於執行此操作。 從文檔:

查找具有給定屬性的第一條記錄,或者如果找不到一條記錄,則創建具有屬性的記錄

也就是說,您可以傳遞一個電子郵件地址,該方法將找到具有該值的記錄或創建一個新記錄。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM