Revisions for "Convert Rails spreadsheet upload to Angular"

Convert Rails spreadsheet upload to Angular

Build a Rails / Angular app with a spreadsheet upload, based on an existing Rails app (code below).

Requirements

1. Allow for single file (only) select or drag onto area (as on the demo page of angular-file-upload)

2. Data from a text field on the page (batch.assembly) is also passed to the controller and updates the batches table

3. Spreadsheet rows are written to batch_details table (code and table below)

4. Filename is written to the batches table (in existing code)
5. Deliver as a working rails app on github

6. Test file attached

7. Bonus for good error handling

Use the following technologies

Angular File Upload
https://github.com/danialfarid/angular-file-upload

Roo
https://github.com/Empact/roo

Sample File

I can't see how to attach a file, so create an Excel spreadsheet (.xlsx not csv), with the following test data

chrom       chrom_start     chrom_end
4               55593607    55593607
4               55593609    55593617
6              133105152    133105152

Existing code from a non-angular Rails app:

Upload Page

<div class="panel-group" id="accordion1">
  <div class="panel panel-default">
    <div class="panel-heading">
        <h4 class="panel-title">
          <a data-toggle="collapse" data-parent="#accordion1" href="#collapseOne">
            Spreadsheet Upload
          </a>
        </h4>
    </div>
    <div id="collapseOne" class="panel-collapse collapse">
      <div class="panel-body">
          <%= form_tag import_path, multipart: true do %>
            <%= file_field_tag :file, multiple: true %>
            <%= submit_tag "Import", :class => 'btn btn-small btn-info pull-right' %>
          <% end %>
      </div>
    </div>
  </div>
</div>

Controller

def import
    @batch = Batch.import(params[:file],current_user) 
end

app/models/batch.rb

def self.import(file,user)
    spreadsheet = open_spreadsheet(file)
    header = spreadsheet.row(1)
    batch = Batch.new
    batch.description = file.original_filename  <---- filename of uploaded xls .....
    batch.assembly =  <---- needs to come from angular .....
    batch.save!
    (2..spreadsheet.last_row).each do |i|
      batch_detail = BatchDetail.new
      row = Hash[[header, spreadsheet.row(i)].transpose]
      batch_detail.batch_id = batch.id
      batch_detail.chrom = row['chrom']
      batch_detail.chrom_start = row['chrom_start'].to_i
      batch_detail.chrom_end = row['chrom_end'].to_i
      batch_detail.save!
   end
  return batch
end


def self.open_spreadsheet(file)
  case File.extname(file.original_filename)
    when ".csv" then Roo::Csv.new(file.path, nil, :ignore)
    when ".xls" then Roo::Excel.new(file.path, nil, :ignore)
    when ".xlsx" then Roo::Excelx.new(file.path, nil, :ignore)
    else raise "Unknown file type: #{file.original_filename}"
  end
end

Database

create_table "batch_details", force: true do |t|
  t.integer  "batch_id"
  t.string   "chrom"
  t.integer  "chrom_start"
  t.integer  "chrom_end"
end

add_index "batch_details", ["batch_id"], name: "index_batch_details_on_batch_id", using: :btree

create_table "batches", force: true do |t|
  t.string   "status"
  t.datetime "created_at",         null: false
  t.datetime "updated_at",         null: false
  t.string   "description"
  t.string   "assembly"
end

add_index "batches", ["dataset_id"], name: "index_batches_on_dataset_id", using: :btree
Convert Rails spreadsheet upload to Angular
Build a Rails / Angular app with a spreadsheet upload, based on an existing Rails app (code below). **Requirements** 1. Allow for single file (only) select or drag onto area (as on the 'drop demofiles here' section on http://angular-file-upload.appspot.com/) 2. Data from a text field on the page of angular-file-upload) 2. Data from a text field on the page (batch.assembly) is also passed to the controller and updates the batches table 3. Spreadsheet rows are written to batch_details table (code and table below) 4. Filename is written to the batches table (in existing code) 5. Deliver as a working rails app on github 6. Test file attached 7. Bonus for good error handling **Use the following technologies** **Angular File Upload** https://github.com/danialfarid/angular-file-upload **Roo** https://github.com/Empact/roo **Sample File** I can't see how to attach a file, so create an Excel spreadsheet (.xlsx not csv), with the following test data chrom chrom_start chrom_end 4 55593607 55593607 4 55593609 55593617 6 133105152 133105152 Existing code from a non-angular Rails app: **Upload Page**
<%= form_tag import_path, multipart: true do %> <%= file_field_tag :file, multiple: true %> <%= submit_tag "Import", :class => 'btn btn-small btn-info pull-right' %> <% end %>
**Controller** def import @batch = Batch.import(params[:file],current_user) end app/models/batch.rb def self.import(file,user) spreadsheet = open_spreadsheet(file) header = spreadsheet.row(1) batch = Batch.new batch.description = file.original_filename <---- filename of uploaded xls ..... batch.assembly = <---- needs to come from angular ..... batch.save! (2..spreadsheet.last_row).each do |i| batch_detail = BatchDetail.new row = Hash[[header, spreadsheet.row(i)].transpose] batch_detail.batch_id = batch.id batch_detail.chrom = row['chrom'] batch_detail.chrom_start = row['chrom_start'].to_i batch_detail.chrom_end = row['chrom_end'].to_i batch_detail.save! end return batch end def self.open_spreadsheet(file) case File.extname(file.original_filename) when ".csv" then Roo::Csv.new(file.path, nil, :ignore) when ".xls" then Roo::Excel.new(file.path, nil, :ignore) when ".xlsx" then Roo::Excelx.new(file.path, nil, :ignore) else raise "Unknown file type: #{file.original_filename}" end end **Database** create_table "batch_details", force: true do |t| t.integer "batch_id" t.string "chrom" t.integer "chrom_start" t.integer "chrom_end" end add_index "batch_details", ["batch_id"], name: "index_batch_details_on_batch_id", using: :btree create_table "batches", force: true do |t| t.string "status" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.string "description" t.string "assembly" end add_index "batches", ["dataset_id"], name: "index_batches_on_dataset_id", using: :btree
Convert Rails spreadsheet upload to Angular
Build a Rails / Angular app with a spreadsheet upload, based on an existing Rails app (code below). **Requirements** 1. Allow for single file (only) select or drag onto area (as on the 'drop files here' section on http://angular-file-upload.appspot.com/) 2. Data from a text field on the page (batch.assembly) is also passed to the controller and updates the batches table 3. Spreadsheet rows are written to batch_details table (code and table below) 4. Filename is written to the batches table (in existing code) 5. Deliver as a working rails app on github 6. Test file attached 7. Bonus for good error handling **Use the following technologies** **Angular File Upload** https://github.com/danialfarid/angular-file-upload **Roo** https://github.com/Empact/roo **Sample File** I can't see how to attach a file, so create an Excel spreadsheet (.xlsx not csv), with the following test data below 7. Bonus for good error handling **Use the following technologies** **Angular File Upload** https://github.com/danialfarid/angular-file-upload **Roo** https://github.com/Empact/roo **Sample File** I can't see how to attach a file, so create an Excel spreadsheet (.xlsx not csv), with the following test data chrom chrom_start chrom_end 4 55593607 55593607 4 55593609 55593617 6 133105152 133105152 Existing code from a non-angular Rails app: **Upload Page**
<%= form_tag import_path, multipart: true do %> <%= file_field_tag :file, multiple: true %> <%= submit_tag "Import", :class => 'btn btn-small btn-info pull-right' %> <% end %>
**Controller** def import @batch = Batch.import(params[:file],current_user) end app/models/batch.rb def self.import(file,user) spreadsheet = open_spreadsheet(file) header = spreadsheet.row(1) batch = Batch.new batch.description = file.original_filename <---- filename of uploaded xls ..... batch.assembly = <---- needs to come from angular ..... batch.save! (2..spreadsheet.last_row).each do |i| batch_detail = BatchDetail.new row = Hash[[header, spreadsheet.row(i)].transpose] batch_detail.batch_id = batch.id batch_detail.chrom = row['chrom'] batch_detail.chrom_start = row['chrom_start'].to_i batch_detail.chrom_end = row['chrom_end'].to_i batch_detail.save! end return batch end def self.open_spreadsheet(file) case File.extname(file.original_filename) when ".csv" then Roo::Csv.new(file.path, nil, :ignore) when ".xls" then Roo::Excel.new(file.path, nil, :ignore) when ".xlsx" then Roo::Excelx.new(file.path, nil, :ignore) else raise "Unknown file type: #{file.original_filename}" end end **Database** create_table "batch_details", force: true do |t| t.integer "batch_id" t.string "chrom" t.integer "chrom_start" t.integer "chrom_end" end add_index "batch_details", ["batch_id"], name: "index_batch_details_on_batch_id", using: :btree create_table "batches", force: true do |t| t.string "status" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.string "description" t.string "assembly" end add_index "batches", ["dataset_id"], name: "index_batches_on_dataset_id", using: :btree
Convert Rails spreadsheet upload to Angular
Build a Rails / Angular app with a spreadsheet upload, based on an existing Rails app (code below). **Requirements** 1. Allow for single file (only) select or drag onto area (as on the 'drop files here' section on http://angular-file-upload.appspot.com/) 2. Data from a text field on the page (batch.assembly) is also passed to the controller and updates the batches table 3. Spreadsheet rows are written to batch_details table (code and table below) 4. Filename is written to the batches table (in existing code) 5. Deliver as a working rails app on github 6. Test data below 7. Bonus for good error handling **Use the following technologies** **Angular File Upload** https://github.com/danialfarid/angular-file-upload **Roo** https://github.com/Empact/roo **Sample File** I can't see how to attach a file, so create an Excel spreadsheet (.xlsx not csv), with the following test data chrom chrom_start chrom_end 4 55593607 55593607 4 55593609 55593617 6 133105152 133105152 Existing code from a non-angular Rails app: **Upload Page**
<%= form_tag import_path, multipart: true do %> <%= file_field_tag :file, multiple: true %> <%= submit_tag "Import", :class => 'btn btn-small btn-info pull-right' %> <% end %>
**Controller** def import @batch = Batch.import(params[:file],current_user) end app/models/batch.rb def self.import(file,user) spreadsheet = open_spreadsheet(file) header = spreadsheet.row(1) batch = Batch.new batch.description = file.original_filename <---- filename of uploaded xls ..... batch.assembly = <---- needs to come from angular ..... batch.save! (2..spreadsheet.last_row).each do |i| batch_detail = BatchDetail.new row = Hash[[header, spreadsheet.row(i)].transpose] batch_detail.batch_id = batch.id batch_detail.chrom = row['chrom'] batch_detail.chrom_start = row['chrom_start'].to_i batch_detail.chrom_end = row['chrom_end'].to_i batch_detail.save! end return batch end def self.open_spreadsheet(file) case File.extname(file.original_filename) when ".csv" then Roo::Csv.new(file.path, nil, :ignore) when ".xls" then Roo::Excel.new(file.path, nil, :ignore) when ".xlsx" then Roo::Excelx.new(file.path, nil, :ignore) else raise "Unknown file type: #{file.original_filename}" end end **Database** create_table "batch_details", force: true do |t| t.integer "batch_id" t.string "chrom" t.integer "chrom_start" t.integer "chrom_end" end add_index "batch_details", ["batch_id"], name: "index_batch_details_on_batch_id", using: :btree create_table "batches", force: true do |t| t.string "status" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.string "description" t.string "assembly" end add_index "batches", ["dataset_id"], name: "index_batches_on_dataset_id", using: :btree Angular table row selection / select all code updateSelected = (action, id) -> $scope.selected.push id if action is "add" & $scope.selected.indexOf(id) is -1 $scope.selected.splice $scope.selected.indexOf(id), 1 if action is "remove" and $scope.selected.indexOf(id) isnt -1 console.log("list of selections: #{$scope.selected}") $scope.updateSelection = ($event, id) -> checkbox = $event.target action = ((if checkbox.checked then "add" else "remove")) updateSelected action, id $scope.selectAll = ($event) -> checkbox = $event.target action = ((if checkbox.checked then "add" else "remove")) i = 0 while i < $scope.assays.length entity = $scope.assays[i] updateSelected action, entity.id i++ $scope.getSelectedClass = (entity) -> (if $scope.isSelected(entity.id) then "selected" else "") $scope.isSelected = (id) -> $scope.selected.indexOf(id) >= 0 In html view
Back to question