9:18 PM
Since I want full CRUD for City, I decided to run the scaffold generator to generate the controller, views, model, functional and unit tests. So I droped down to a terminal window and ran the following commands:
$ rails new cityupload $ cd cityupload $ rails g scaffold city name:string zipCode:string $ rake db:migrate
This sets up a rails project named cityupload, generates a CityController, City model and views CRUD'ing a city. I also ran rake to generate the city table with the corresponding fields for the city model
9:19 PM
Since I want a separate controller for handling the uploading of the file I decided to use the controller generator. The following creates a UploadCitiesController class with two actions (index and uploadfile) and corresponding views that matches the action methods (index.html.erb and uploadfile.html.erb). My index action will actually post the file to the server and the uploadfile action will parse the file and persist the data to the database
$ rails g controller UploadCities index uploadfile
9:20 PM
Before opening the project in NetBeans I decided to run irb to test whether or not I can CRUD cities from the command line. $ represents my cursor
$ rails console $ city = City.create(:name => 'Atlanta', :zipcode => '30349') => #$ city.new_record? => false $ City.all => [#<city id: 1, name: "Atlanta", zipcode: "30349", created_at: "2010-12-08 02:41:20", updated_at: "2010-12-08 02:41:20">] $ City.count => 1
The above verifies that all is well with saving objects to the database with ActiveRecord. NOTE: My default database is MySql. Now let's implement the UploadController. A friend suggested I use the FastCSV, however Ruby 1.9.2 already redesigned the CSV class to make FastCSV obsolete. In fact, I get a warning to use CSV instead of FastCSV when starting WEBrick.
11:45 PM
The uploadfile action takes a file and uses CSV to iterate all the rows in the file and creates and saves a new City instance to the database, then I display all the cities in the uploadfile.html.erb template file. It actually took me a while to figure out how to use CSV, but once I figured out the correct method to use and arguments to pass it was a breeze.
upload_cities_controller.rb
require 'csv' class UploadCitiesController < ApplicationController def uploadfile cities_upload_file = params[:upload] @cities = Array.new if cities_upload_file == nil @notice = "Please select a file!" return end #note: There's no exception logic for now. If CSV fail here an #error is thrown to the client values = CSV.open(cities_upload_file.tempfile.path, "r").read index = 0 values.each do |row| city = City.new(:name => row[0], :zipcode => row[1]) city.save #add city to cities array @cities[index] = city index += 1 end cityCount = @cities.count @notice = "'#{cityCount}' Cities/Zipcodes successfully uploaded to server" respond_to do |format| format.html end end end
1:45 AM
I've been pulling my hair out trying to figure out why my routes aren't working. It turns out I needed to update the routes.rb file in my Configuration folder. I needed to add a match route for my uploadfile action:
match "upload_cities/uploadfile" => "upload_cities#uploadfile"
Here's my index.html.erb file for submitting the file to the server
index.html.erb
<h1>Upload Zipcodes to server</h1> <p id="notice"><%= notice %></p> <%= form_tag 'upload_cities/uploadfile', :multipart => true do %> <p><label for="upload">Select File</label> : <%= file_field_tag "upload" %></p> <%= submit_tag "Upload File" %> <% end %> <%= link_to 'Back', cities_path %>
And here's my uploadfile.html.erb that displays a confirmation message if the upload and save was successful and all of the cities that were saved to the database
uploadfile.html.erb
<h1>City/Zipcodes status</h1> <p id="notice"><%= @notice %></p> <% if @cities.count %> <table> <tr> <th>Id</th> <th>Name</th> <th>Zipcode</th> <th>Date Created</th> </tr> <% @cities.each do |city| %> <tr> <td><%= city.id %></td> <td><%= city.name %></td> <td><%= city.zipcode %></td> <td><%= city.created_at %></td> </tr> <% end %> </table> <% end %> <%= link_to 'Back', cities_path %>
It took me about 5 hours to do this simple task in RoR but I expect that with learning a new language. I will say using the built-in generators saved me an immeasurable amount of time since I didn't have to worry about the database scripts, controller and view skeletons. So far I'm digging Rails...
No comments:
Post a Comment