Lets suppose we want to import a products CSV file in rails i.e. reading rows from CSV file and inserting its into a table. There are the following steps which we will use to import CSV file.
Create an application using command
rails new csv_import
cd csv_import
Modify Gemfile to using MYSQL RDBMS
Path: csv_import/Gemfile
gem 'mysql2'
#and run
bundle install
Now configure your app for database
Path: csv_import/config/database.yml
default: &default
adapter: mysql2
encoding: utf8
host: localhost
template: template0
database: csv_import
pool: 5
username: xxxx
password: xxxx
development:
<<: *default
database: csv_import
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
<<: *default
database: test_csv_import
production:
<<: *default
database: prod_csv_import
Here , I've chosen adapter: mysql2 , because of using of gem ' mysql2' and create db by command
rake db:create
This command create db named csv_import .
Now, modify application.rb to add csv class
Path: csv_import/config/application.rb
require File.expand_path('../boot', __FILE__)
require 'rails/all'
require 'csv'
Bundler.require(*Rails.groups)
module CsvImport
class Application < Rails::Application
config.active_record.raise_in_transactional_callbacks = true
end
end
Now we'll create a model to import/upload and display the products data
rails g model Product prod_name:string quantity:integer price:float
It'll generate the file like..
Running via Spring preloader in process 18795
invoke active_record
create db/migrate/20160704061419_create_products.rb
create app/models/product.rb
invoke test_unit
create test/models/product_test.rb
create test/fixtures/products.yml
And run command to create table
rake db:migrate
Its give the output like...
== 20160704061419 CreateProducts: migrating ===================================
-- create_table(:products)
-> 0.0633s
== 20160704061419 CreateProducts: migrated (0.0634s) ==========================
Here we'll generate interface to to upload a CSV file
rails g controller Products index import
The ouput look likes
Running via Spring preloader in process 19253
create app/controllers/products_controller.rb
route get 'products/import'
route get 'products/index'
invoke erb
create app/views/products
create app/views/products/index.html.erb
create app/views/products/import.html.erb
invoke test_unit
create test/controllers/products_controller_test.rb
invoke helper
create app/helpers/products_helper.rb
invoke test_unit
invoke assets
invoke coffee
create app/assets/javascripts/products.coffee
invoke scss
create app/assets/stylesheets/products.scss
This command creates views and routes for index and import.
Now modify routes file like
Path: csv_import/config/routes.rb
Rails.application.routes.draw do
resources :products do
collection { post :import }
end
root to: "products#index"
end
Now, lets we modify product model to accept the CSV and perform import functionality and modify it to like...
path: csv_import/app/models/product.rb
class Product < ActiveRecord::Base
require 'csv'
def self.import(file)
CSV.foreach(file.path, headers: true) do |row|
product_hash = row.to_hash
product = Product.where(id: product_hash["id"])
if product.count == 1
product.first.update_attributes(product_hash.except("price"))
else
Product.create!(product_hash)
end
end
end
end
The above code reads the row from browsed csv file and inserting it to table products if record not in table, if the record exist then it'll update.
Now we will edit product controller and add the import & index action to call this function.
class ProductsController < ApplicationController
def index
@products = Product.all
end
def import
begin
Product.import(params[:file])
redirect_to root_url, notice: "Products successfully imported."
rescue
redirect_to root_url, notice: "Invalid CSV file format."
end
end
end
When we will hit url "http://localhost:3000/"
The index page open with product list and a form by which user can upload new products to db.
0 Comment(s)