Join the social network of Tech Nerds, increase skill rank, get work, manage projects...
 
  • Import products from a CSV file in rails

    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 313
    Comment on it

    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)

Sign In
                           OR                           
                           OR                           
Register

Sign up using

                           OR                           
Forgot Password
Fill out the form below and instructions to reset your password will be emailed to you:
Reset Password
Fill out the form below and reset your password: