将CSV数据导入Rails应用程序,使用 "id "关联以外的东西[英] Importing CSV data into Rails app, using something other then the association "id"

本文是小编为大家收集整理的关于将CSV数据导入Rails应用程序,使用 "id "关联以外的东西的处理方法,想解了将CSV数据导入Rails应用程序,使用 "id "关联以外的东西的问题怎么解决?将CSV数据导入Rails应用程序,使用 "id "关联以外的东西问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

我正在尝试将一些CSV文件导入我的Rails应用程序.我学会了并设法将桌子导入到没有关联的情况下.

现在,我设法将数据导入到具有关联的表中,但仅通过在CSV列上输入实际的" ID"号码.尽管功能很强,但这并不是真正的选择,因为我有很多具有数千个ID的桌子.

我的主要目标是能够在CSV中使用列并输入实际值(与其他模型相关联),而不是ID号.

我有一个国家模型和端口模型.端口模型与country_id

关联

端口模型

class Port < ApplicationRecord
  def self.import(file)
    #code
    CSV.foreach(file.path, headers: true) do |row|
      port = find_by_id(row["id"])
      Port.create! row.to_hash
    end
  end

  belongs_to :shipment_type
  belongs_to :country
  has_many :origins, :class_name => 'Rate'
  has_many :destinations, :class_name => 'Rate'
end

国家模型

class Country < ApplicationRecord
  def self.import(file)
    #code
    CSV.foreach(file.path, headers: true) do |row|
      Country.create! row.to_hash
    end
  end

  has_many :ports, dependent: :destroy
end

schema.db

  create_table "ports", force: :cascade do |t|
    t.string   "name"
    t.string   "port_code"
    t.integer  "shipment_type_id"
    t.datetime "created_at",       null: false
    t.datetime "updated_at",       null: false
    t.integer  "country_id"
    t.index ["country_id"], name: "index_ports_on_country_id", using: :btree
    t.index ["shipment_type_id"], name: "index_ports_on_shipment_type_id", using: :btree
  end

  create_table "countries", force: :cascade do |t|
    t.string   "name"
    t.string   "country_code"
    t.datetime "created_at",   null: false
    t.datetime "updated_at",   null: false
  end

  create_table "shipment_types", force: :cascade do |t|
    t.string   "name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

关联起作用,因为我能够手动添加它们查看我的表格,我创建的很好.

<%= form_for(port) do |f| %>
  <% if port.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(port.errors.count, "error") %> prohibited this port from being saved:</h2>

      <ul>
      <% port.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :name %>
    <%= f.text_field :name %>
  </div>

  <div class="field">
    <%= f.label :port_code %>
    <%= f.text_field :port_code %>
  </div>

  <div class="field">
    <%= f.label :shipment_type_id %>
    <%= f.collection_select :shipment_type_id, ShipmentType.all, :id, :name %>
  </div>

  <div class="field">
    <%= f.label :country_code %>
    <%= f.collection_select :country_id, Country.all, :id, :country_code %>
  </div>



  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

任何指导或帮助将不胜感激.我已经盘旋了几天.

从CSV文件中添加示例表.

在此处输入图像说明

在此处输入图像说明

在此处输入图像说明

推荐答案

shipment_type是一个红宝石对象,您要发送一个字符串.

如果您需要导入关系,请在Port模型上添加方法

class Port < ApplicationRecord

  def shipment_type_name
    shipment_type.try(:name)
  end

  def shipment_type_name=(name)
    self.shipment_type = ShipmentType.where(:name => name).first_or_create
  end

  def country_country_code
    country.try(:country_code)
  end

  def country_country_code=(code)
    self.country = Country.where(:country_code => code).first
  end


end

然后在CSV中您发送shipment_type_name和country_country_code属性.

您会做类似于其他关系的事情.

其他推荐答案

您可能需要使用此GEM导入CSV: https://github.com/michaelub.com/michaelnera/michaelnera/active_record_record_importer

这很容易使用.

其他推荐答案

谢谢大家的帮助.以下是最终为我工作的原因.我遇到的最大问题是原产地和目的地.只有一个端口表,其中包括端口列表.端口用于原点和目的地.

class Rate < ApplicationRecord

  def self.import(file)
    CSV.foreach(file.path, headers: true) do |row|
      rate = find_by_id(row["id"])
      Rate.create! row.to_hash
    end
  end

  belongs_to :origin, :class_name => 'Port'
  belongs_to :destination, :class_name => 'Port'
  belongs_to :carrier
  belongs_to :shipment_category
  belongs_to :unit_of_measure
  has_many :additional_items

# associatiing Origin and Destination Port Code
def origin_port_code
  origin.try(:port_code)
end

def origin_port_code=(port_code)
  self.origin = Port.where(:port_code => port_code).first
end

def destination_port_code
  destination.try(:port_code)
end

def destination_port_code=(port_code)
  self.destination = Port.where(:port_code => port_code).first
end

# associating carrier name
  def carrier_name
    carrier_name.try(:name)
    #code
  end
  def carrier_name=(name)
    self.carrier = Carrier.where(:name => name).first
    #code
  end


# associating Shipment Category Name
  def shipment_category_name
    shipment_category.try(:name)
  end

  def shipment_category_name=(name)
    self.shipment_category = ShipmentCategory.where(:name => name).first
  end



  # associating unit_of_measure name
  def unit_of_measure_name
    unit_of_measure.try(:name)
    #code
  end
  def unit_of_measure_name=(name)
    self.unit_of_measure = UnitOfMeasure.where(:name => name).first
    #code
  end


end

本文地址:https://www.itbaoku.cn/post/1763967.html