Hello,
I need some help trying to figure out how to add the ability for a
user to upload a text file, and then have the application parse that
text file, and add each record as instance of a model object. I've
found a lot of helpful articles out there, but I'm stuck trying to
bring it all together since I'm still very new to all of this.
Here's my view code:
# index.html.erb
<% form_for :upload, :url => { :action => :upload }, :html =>
{ :multipart => true } do |f| %>
<p>Please select a file to upload:</p>
<%= f.file_field :file %>
<%= f.submit 'Upload', :disable_with => "Uploading..." %>
<% end %>
In my controller, I've been able to write something like this to work
with the data in my upload view:
# mailing_lists_controller.rb
def upload
file = params[:upload][:file]
@data = file.read
end
so then the view looks like this:
# upload.html.erb
<% @data.split("\r\n").each do |row| %>
<%= row.split("\t").join(" | ") %>
<% end %>
So, where I'm stuck is translating that into saving each row as a
record in the database. I've tried several different things in the
model (like creating a "process" method or using "before_save"), but
nothing has been successful thus far (probably because I'm not
implementing it correctly).
Any help would be appreciated.
Thanks,
Spencer
--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To post to this group, send email to rubyonra...@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-ta...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Besides it's other awesome features, you want to use Paperclip
Processors to play with a file after upload.
http://mdeering.com/posts/018-paperclip-processors-doing-so-much-more-with-your-attachment
To read file lines you can go for
File.readlines(@file.path).collect(&:chomp).each do |line|
... (create your models here)
end
to collect all lines.
`chomp` will cut end-of-line symbols, and @file it's an object which
is given by Paperclip.
Or if you have troubles with this one, here's another option
IO.foreach("path/to/file.txt") do |line|
... (create your models here)
end
I recommend you to use Paperclip for files uploading.
http://railscasts.com/episodes/134-paperclip
> The only thing if I recall, that kept me from using paperclip for my
> purposes, is the file essentially attached to the model but does not
> allow for modification and re-saving the file --- am I mistaken?
> Unless things have changed recently, it would be super-cool if
> Paperclip would handle file mods just as a mod to any attribute of
> the model... although I guess this gets away from the basic intent
> of Paperclip, which for what it does do does it very nicely.
You are mistaken, and although I came late to the Paperclip party, I
can't recall a time when it was true. You can edit the model without
modifying the image (just don't upload another image) and everything
stays the same in the image, or you can upload a new image and it will
overwrite the previous version. It's all managed when you save the
model that the image is attached to.
Walter
Walter
> You are mistaken, and although I came late to the Paperclip party, I
> can't recall a time when it was true. You can edit the model without
> modifying the image (just don't upload another image) and everything
> stays the same in the image, or you can upload a new image and it
> will overwrite the previous version. It's all managed when you save
> the model that the image is attached to.
>
> Right, but what I wanted was to be able to load a model instance,
> change the file (say I encrypt a portion of the text) and have
> Paperclip update that file on its own when I call model#save. I am
> pretty sure Paperclip does not do this. Right, you can re-save the
> file but it requires manual action beyond calling model#save.
If you code your transformation within a Paperclip Processor, you can
have any number of different transformed versions. Here's one that
extracts the text from an uploaded PDF:
#lib/paperclip_processors/text.rb
module Paperclip
# Handles extracting plain text from PDF file attachments
class Text < Processor
attr_accessor :whiny
# Creates a Text extract from PDF
def make
src = @file
dst = Tempfile.new([@basename, 'txt'].compact.join("."))
command = <<-end_command
"#{ File.expand_path(src.path) }"
"#{ File.expand_path(dst.path) }"
end_command
begin
success = Paperclip.run("/usr/bin/pdftotext -nopgbrk",
command.gsub(/\s+/, " "))
Rails.logger.info "Processing #{src.path} to #{dst.path} in
the text processor."
rescue PaperclipCommandLineError
raise PaperclipError, "There was an error processing the text
for #{@basename}" if @whiny
end
dst
end
end
end
You call it from your model, like this:
#app/models/document.rb
...
has_attached_file :pdf,:styles => { :text => { :fake =>
'variable' } }, :processors => [:text]
...
The :fake => 'variable' part is just in there to get the offset
correct for the processors variable. I am not sure if it's still
needed, but I have been doing it this way since early this summer.
Later, you can access that version of the file as you would any other
paperclip-attached model attribute. In this example, this might look
like document.pdf.url(:text). Your untouched original will always be
at document.pdf.url(:original).
Walter