Rails CSV 导入 first_or_create
Rails CSV IMPORT first_or_create
您好,我有一个非常基本的 csv 导入器,用户可以使用它来导入项目。项目 belong_to 个:part_number
当用户导入我要首先添加或创建的项目时,通过名称查找或创建部件号。
我想要的 CSV 文件列
name, part_number.name
架构
create_table "items", force: :cascade do |t|
t.bigint "project_id"
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "status", default: 0
t.bigint "part_number_id"
t.index ["part_number_id"], name: "index_items_on_part_number_id"
t.index ["project_id"], name: "index_items_on_project_id"
end
create_table "part_numbers", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
app/models/item.rb
class Item < ApplicationRecord
belongs_to :project
belongs_to :part_number
def self.import(file)
CSV.foreach(file.path, headers: true, header_converters: :symbol) do |row|
Item.create! row.to_hash
end
end
end
app/models/part_number.rb
class PartNumber < ApplicationRecord
has_many :items
end
app/controllers/projects/items_controller.rb
class Projects::ItemsController < ApplicationController
# GET /items/new
def new
@project = Project.find(params[:project_id])
@item = Item.new
end
def index
@project = Project.find(params[:project_id])
@items = @project.items.all
respond_to do |format|
format.html
format.csv { send_data @items.to_csv }
end
end
# GET /items/1/edit
def edit
end
# POST /items
# POST /items.json
def create
@project = Project.find(params[:project_id])
@item = Item.new(item_params)
@item.project_id = @project.id
respond_to do |format|
if @item.save
format.html { redirect_to @item.project, notice: 'Item was successfully created.' }
format.json { render :show, status: :created, location: @item.project }
else
format.html { render :new }
format.json { render json: @item.project.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /items/1
# PATCH/PUT /items/1.json
def update
@item = Item.find(params[:id])
@project = Project.find(params[:project_id])
respond_to do |format|
if @item.update(item_params)
format.html { redirect_to @item.project, notice: 'Item was successfully updated.' }
format.json { render :show, status: :ok, location: @item.project }
else
format.html { render :edit }
format.json { render json: @item.project.errors, status: :unprocessable_entity }
end
end
end
# DELETE /items/1
# DELETE /items/1.json
def destroy
@item = Item.find(params[:id])
@project = Project.find(params[:project_id])
title = @item.model
if @item.destroy
flash[:notice] = "One \'#{title}' was successfully destroyed."
redirect_to @project
else
flash[:notice] = "Error Yo"
render :show
end
end
def import
@project = Project.find(params[:project_id])
@project.items.import(params[:file])
redirect_to projects_path(@project), notice: "Sucessfully Imported Items!"
end
private
# Use callbacks to share common setup or constraints between actions.
# Never trust parameters from the scary internet, only allow the white list through.
def item_params
params.require(:item).permit(:model, :project_id, :name, :search, part_number: [:id, :name])
end
end
如果您的姓名参数作为每一行(行[0])的第一列出现,那么我认为这样的事情应该可行:
class Item < ApplicationRecord
belongs_to :project
belongs_to :part_number
def self.import(file)
CSV.foreach(file.path, headers: true, header_converters: :symbol) do |row|
Item.where(name: row[0]).find_or_create_by do |item|
item.update_attributes(row.to_hash)
end
end
end
end
导入 CSV 时使用 find_or_create_by 的不错教程:
https://www.driftingruby.com/episodes/importing-and-exporting-csv-data
您好,我有一个非常基本的 csv 导入器,用户可以使用它来导入项目。项目 belong_to 个:part_number
当用户导入我要首先添加或创建的项目时,通过名称查找或创建部件号。 我想要的 CSV 文件列
name, part_number.name
架构
create_table "items", force: :cascade do |t|
t.bigint "project_id"
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "status", default: 0
t.bigint "part_number_id"
t.index ["part_number_id"], name: "index_items_on_part_number_id"
t.index ["project_id"], name: "index_items_on_project_id"
end
create_table "part_numbers", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
app/models/item.rb
class Item < ApplicationRecord
belongs_to :project
belongs_to :part_number
def self.import(file)
CSV.foreach(file.path, headers: true, header_converters: :symbol) do |row|
Item.create! row.to_hash
end
end
end
app/models/part_number.rb
class PartNumber < ApplicationRecord
has_many :items
end
app/controllers/projects/items_controller.rb
class Projects::ItemsController < ApplicationController
# GET /items/new
def new
@project = Project.find(params[:project_id])
@item = Item.new
end
def index
@project = Project.find(params[:project_id])
@items = @project.items.all
respond_to do |format|
format.html
format.csv { send_data @items.to_csv }
end
end
# GET /items/1/edit
def edit
end
# POST /items
# POST /items.json
def create
@project = Project.find(params[:project_id])
@item = Item.new(item_params)
@item.project_id = @project.id
respond_to do |format|
if @item.save
format.html { redirect_to @item.project, notice: 'Item was successfully created.' }
format.json { render :show, status: :created, location: @item.project }
else
format.html { render :new }
format.json { render json: @item.project.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /items/1
# PATCH/PUT /items/1.json
def update
@item = Item.find(params[:id])
@project = Project.find(params[:project_id])
respond_to do |format|
if @item.update(item_params)
format.html { redirect_to @item.project, notice: 'Item was successfully updated.' }
format.json { render :show, status: :ok, location: @item.project }
else
format.html { render :edit }
format.json { render json: @item.project.errors, status: :unprocessable_entity }
end
end
end
# DELETE /items/1
# DELETE /items/1.json
def destroy
@item = Item.find(params[:id])
@project = Project.find(params[:project_id])
title = @item.model
if @item.destroy
flash[:notice] = "One \'#{title}' was successfully destroyed."
redirect_to @project
else
flash[:notice] = "Error Yo"
render :show
end
end
def import
@project = Project.find(params[:project_id])
@project.items.import(params[:file])
redirect_to projects_path(@project), notice: "Sucessfully Imported Items!"
end
private
# Use callbacks to share common setup or constraints between actions.
# Never trust parameters from the scary internet, only allow the white list through.
def item_params
params.require(:item).permit(:model, :project_id, :name, :search, part_number: [:id, :name])
end
end
如果您的姓名参数作为每一行(行[0])的第一列出现,那么我认为这样的事情应该可行:
class Item < ApplicationRecord
belongs_to :project
belongs_to :part_number
def self.import(file)
CSV.foreach(file.path, headers: true, header_converters: :symbol) do |row|
Item.where(name: row[0]).find_or_create_by do |item|
item.update_attributes(row.to_hash)
end
end
end
end
导入 CSV 时使用 find_or_create_by 的不错教程:
https://www.driftingruby.com/episodes/importing-and-exporting-csv-data