2017-02-27 40 views
3

我试图导入一些CSV文件到我的Rails应用程序。我学习并设法将表格导入到模型中而无需关联。CSV数据导入到Rails应用程序,使用其他协议“ID”

现在我已经设法将数据导入到具有关联的表格中,但只能在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文件中添加示例表。

enter image description here

enter image description here

enter image description here

+0

不完全遵循你所要问的是什么?你可以尝试在你的问题上更具体吗?您的问题是否自动输入外键? – mahatmanich

+0

我认为一个数据样本应该就足够了! – mahatmanich

+0

对不起,这是我的第一篇文章。掌握这个评论部分。 所以我有一个包含以下几列CSV文件较大: -name(机场名) -port_code(机场代码例如:JFK,LAX) - shipment_type(空运或海运),目前相关的Shipment_Type表 -country_code(例如:美国,德国,中国)目前与国家表相关联。 – vinicomelo

回答

1

一个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_namecountry_country_code属性。

你会做类似于其他关系的东西。

+0

这开始变得更有意义。该代码是否会添加到我的端口控制器或端口模型中? – vinicomelo

+0

到端口模型。是的,您可以通过将它们作为表单中的属性发送来触发方法。该方法可能更复杂,处理案例问题等。您还需要确保它们的属性在批量分配中是允许的。 – Swards

+0

它工作!现在,如果以后我会包含country_id和其他属性,那么“.first_or_create”会与所有这些属性一起使用,还是只包含一个属性。不知道它是否重叠或类似的东西。 再次感谢,这真棒。 – vinicomelo

0

谢谢大家的帮助。下面是结束了为我工作。我得到的最大问题是Origin和Destination。只有一个端口表,其中包含端口列表。端口用于来源和目的地。

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 
相关问题