Upload File parameter does not reach controller
I am new to Rails and am constantly progressing through a mobile web application I am working on at our local high school, but ran into a problem I ran into. I hope the collective knowledge here will point me in the right direction.
I have a model for high school athletes (first name, last name, height, weight, graduation year, standard material) that works (CRUD via standard Eskimo generation) and now I want to add the ability to import records via CSV upload.
To avoid reinventing the wheel, I am following this example from Rich on Rails . To get familiar with it, I created a separate Rail project and followed the example and everything works as expected. Fine. Now to integrate into my existing project.
Everything seems to integrate nicely with one exception: the CSV file is never passed to my model in parameters, I can't figure out why. I'm sure this is something obvious, but I've stared at this issue for hours and can't figure out what I'm doing wrong.
Here is a portion of my Athletes controller:
class AthletesController < ApplicationController
before_action :set_athlete, only: [:show, :edit, :update, :destroy]
# GET /athletes
# GET /athletes.json
def index
@athletes = Athlete.all.order(:lastname, :firstname)
end
# POST /athletes/import
# POST /athletes/import.json
def import
logger.info(params.to_yaml)
begin
Athlete.import(params[:file])
redirect_to page_path('admin'), notice: "Athletes imported."
rescue
redirect_to page_path('admin'), notice: "Invalid CSV file format."
end
end
# GET /athletes/1
# GET /athletes/1.json
def show
end
# GET /athletes/new
def new
@athlete = Athlete.new
end
# GET /athletes/1/edit
def edit
end
My model looks like this:
class Athlete < ActiveRecord::Base
# an athlete can be on more than one team
has_and_belongs_to_many :teams, through: :athletes
require 'csv'
## CSV import
def self.import(file)
CSV.foreach(file.path, headers: true) do |row|
athlete_hash = row.to_hash # exclude the ? field
athlete = Athlete.where(id: athlete_hash["id"])
if athlete.count == 1
athlete.first.update_attributes
else
Athlete.create!(athlete_hash)
end # end if !athlete.nil?
end # end CSV.foreach
end # end self.import(file)
I added this to my index view for testing, it will be in the admin area later:
<div>
<h3>Import a CSV File</h3>
<%= form_tag import_athletes_path, multipart: true do %>
<%= file_field_tag :file %>
<%= submit_tag "Import CSV" %>
<% end %>
</div>
No matter what I do, I never get the file_field_tag ββvalue to access the controller. If I add other fields using text_field_tag, they go through as expected, but the file_field_tag ββvalue never gets executed.
--- !ruby/hash:ActionController::Parameters
utf8: "β"
authenticity_token: it3yBxBnzA4UQ/NILP5GNoYJeO5dyg+Z+VfhE/C6p7k=
commit: Import CSV
action: import
controller: athletes
Redirected to http://localhost:3000/
Completed 302 Found in 8ms (ActiveRecord: 0.0ms)
I'm stumped - if anyone has any ideas as to what I might be doing wrong, I would be grateful. I have about 300 athletes that I want to import and don't want to introduce.
source to share
It turns out because I am using jQuery Mobile for my framework, I need to add "data-ajax = false" to my form tag. This change in my form allowed the file parameter to be visible in the controller:
<h3>Import a CSV File</h3>
<%= form_tag(import_athletes_path, { :multipart => true, :'data-ajax' => false }) do %>
<%= file_field_tag :file %>
<%= submit_tag "Import CSV" %>
<% end %>
</div>
I remembered a while ago that I read something about uploading files and jQuery Mobile doesn't work by default. This is due to the standard AJAX navigation used by jQM.
source to share