2006 - Klein, Michael Patrick
2005-Jun-14  02:20 UTC
Uploading Files - The classic problem once again
To all those feeling very charitable today, please read ahead - I need some
help!
Later this week I am receiving a digital camera and I would love to have a up
and running photoblog when it arrives. I''m sure this seems rather
self-centered/unimportant/"why should i care?" but never the less I
request your help.
For months I have struggled with file uploading and have avoided it in any way
possible in other simple Rails applications I have written. Now there is no real
way to avoid it other than uploading images via an ftp and just submitting the
link to this uploaded image for the image_url and embedding that in each view
with <img src="<%= @photo.image_url" > or something like
that. This seems to completely rebuke my effort in making a dynamic web
application.
	
Right now I am at the beginning just trying to upload the file and save it on
the filesystem. I know many people favor blobs and the database, but I am very
reluctant to store anything but text inside a database. So right now I have a
form that uploads the text parts of each photo and the image. I have tried to
make a method in the model Photo to save the actual photo file onto the
filesystem, then save the text information and its location in the database. I
am guessing there is a better way but I am struggling to find one. This is what
I have so far. Right now it gives me an error that
''save_photo'' is an undefined method in Photo#create. It
seriously isn''t complicated at all, because I am an amateur at Ruby and
Rails, but please take a look.
I would seriously appreciate anything that you can offer, I am losing my mind
over this problem. Right now it looks to me as if I have some serious problems
with self.save in photo.rb and there must be something wrong with
self.save_photo in photo.rb. If you could help in any way I would appreciate it.
I will be frantically checking for updates so I will definitely get back to any
answers.
photoblog.sql:
CREATE TABLE photos (
  id int not null auto_increment primary key,
  title tinytext not null,
  description text not null,
  image_url tinytext not null,
  date_available datetime not null
);
photo.rb:
class Photo < ActiveRecord::Base
  def self.save_photo(photo)
    photo[''image_url''] =
sanitize_filename(photo[''image''])
    File.open( (File.expand_path(RAILS_ROOT) +
"/public/images/#{photo[''image_url'']}"),
"wb")  { |f| f.write(photo[''image''].read) }
  end
  
  def self.save
    photo[''image_url''] =
sanitize_filename(photo[''image''])
    photo.save
  end
  
  private
    def sanitize_filename(value)
      #get only the filename, not the whole path
      just_filename = File.basename(value)
      #replace all erroneous junk
      filename = just_filename.gsub(/[^\w\.\-]/,''_'')
    end
end
  
photo_controller.rb:
  
class PhotoController < ApplicationController
  model :photo
  
  def index
  end
  
  def new
    @photo = Photo.new
  end
  
  def create
   
@photo.save_photo(@params[''photo''][''image''])
    if @photo.save
      redirect_to :action => ''show'', :id => Photo
    end
  end
end
    
and finally -
new.rhtml:
<%= form_tag({:action => ''create''}, :multipart =>
''true'') %>
  Title: <%= text_field("photo", "title") %><br
/>
  Description: <%= text_area("photo", "description")
%><br />
  Image: <%= file_field("photo", "image") %><br
/>
  Date/Time to publish: <%= select_datetime(Time.now, :include_blank =>
true, :add_month_numbers => 1) %><br />
  <%= submit_tag("Upload file") %>
<%= end_form_tag %>
You have save_photo defined as a class method (self.save_photo), when
you call it, you call it as an instance method (@photo = Photo.new;
@photo.save_photo)
Get rid of ''self.'' at the beginning of your method definition
to make it
an instance method. As for you overloading of the save instance method -
this will not work -> you need to rename the current save method, write
over it, and then call the overridden method.
e.g.
alias :old_save, :save
def save
	photo[''image_url''] =
sanitize_filename(photo[''image''])
	old_save
end
-----Original Message-----
From: rails-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
[mailto:rails-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org] On
Behalf Of 2006 - Klein,
Michael Patrick
Sent: Tuesday, 14 June 2005 12:20 PM
To: rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
Subject: [Rails] Uploading Files - The classic problem once again
To all those feeling very charitable today, please read ahead - I need
some help!
Later this week I am receiving a digital camera and I would love to have
a up and running photoblog when it arrives. I''m sure this seems rather
self-centered/unimportant/"why should i care?" but never the less I
request your help.
For months I have struggled with file uploading and have avoided it in
any way possible in other simple Rails applications I have written. Now
there is no real way to avoid it other than uploading images via an ftp
and just submitting the link to this uploaded image for the image_url
and embedding that in each view with <img src="<%=
@photo.image_url" >
or something like that. This seems to completely rebuke my effort in
making a dynamic web application.
	
Right now I am at the beginning just trying to upload the file and save
it on the filesystem. I know many people favor blobs and the database,
but I am very reluctant to store anything but text inside a database. So
right now I have a form that uploads the text parts of each photo and
the image. I have tried to make a method in the model Photo to save the
actual photo file onto the filesystem, then save the text information
and its location in the database. I am guessing there is a better way
but I am struggling to find one. This is what I have so far. Right now
it gives me an error that ''save_photo'' is an undefined method
in
Photo#create. It seriously isn''t complicated at all, because I am an
amateur at Ruby and Rails, but please take a look.
I would seriously appreciate anything that you can offer, I am losing my
mind over this problem. Right now it looks to me as if I have some
serious problems with self.save in photo.rb and there must be something
wrong with self.save_photo in photo.rb. If you could help in any way I
would appreciate it. I will be frantically checking for updates so I
will definitely get back to any answers.
photoblog.sql:
CREATE TABLE photos (
  id int not null auto_increment primary key,
  title tinytext not null,
  description text not null,
  image_url tinytext not null,
  date_available datetime not null
);
photo.rb:
class Photo < ActiveRecord::Base
  def self.save_photo(photo)
    photo[''image_url''] =
sanitize_filename(photo[''image''])
    File.open( (File.expand_path(RAILS_ROOT) +
"/public/images/#{photo[''image_url'']}"),
"wb")  { |f|
f.write(photo[''image''].read) }
  end
  
  def self.save
    photo[''image_url''] =
sanitize_filename(photo[''image''])
    photo.save
  end
  
  private
    def sanitize_filename(value)
      #get only the filename, not the whole path
      just_filename = File.basename(value)
      #replace all erroneous junk
      filename = just_filename.gsub(/[^\w\.\-]/,''_'')
    end
end
  
photo_controller.rb:
  
class PhotoController < ApplicationController
  model :photo
  
  def index
  end
  
  def new
    @photo = Photo.new
  end
  
  def create
   
@photo.save_photo(@params[''photo''][''image''])
    if @photo.save
      redirect_to :action => ''show'', :id => Photo
    end
  end
end
    
and finally -
new.rhtml:
<%= form_tag({:action => ''create''}, :multipart =>
''true'') %>
  Title: <%= text_field("photo", "title") %><br
/>
  Description: <%= text_area("photo", "description")
%><br />
  Image: <%= file_field("photo", "image") %><br
/>
  Date/Time to publish: <%= select_datetime(Time.now, :include_blank =>
true, :add_month_numbers => 1) %><br />
  <%= submit_tag("Upload file") %>
<%= end_form_tag %>
  
_______________________________________________
Rails mailing list
Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
http://lists.rubyonrails.org/mailman/listinfo/rails
2006 - Klein, Michael Patrick
2005-Jun-14  03:37 UTC
RE: Uploading Files - The classic problem once again
Wayne Robinson <wayner@...> writes:> > You have save_photo defined as a class method (self.save_photo), when > you call it, you call it as an instance method ( <at> photo = Photo.new; > <at> photo.save_photo) > > Get rid of ''self.'' at the beginning of your method definition to make it > an instance method. As for you overloading of the save instance method - > this will not work -> you need to rename the current save method, write > over it, and then call the overridden method. > > e.g. > > alias :old_save, :save > def save > photo[''image_url''] = sanitize_filename(photo[''image'']) > old_save > end >Thank you for your help. That makes sense to me why I wouldn''t want self.save there, I checked back up with my Rails Beta Book and now I understand the problem with that. I have changed my photo.rb to look like this: class Photo < ActiveRecord::Base def save_photo(photo) photo[''image_url''] = sanitize_filename(photo[''image'']) File.open( (File.expand_path(RAILS_ROOT) + "/public/images/#{photo[''image_url'']}"), "wb") { |f| f.write(photo[''image''].read) } end alias :old_save :save def save photo[''image_url''] = sanitize_filename(photo[''image'']) old_save end private def sanitize_filename(value) #get only the filename, not the whole path just_filename = File.basename(value) #replace all erroneous junk filename = just_filename.gsub(/[^\w\.\-]/,''_'') end end Now that this change has been made I still do not write the file to the hard drive. There continues to be a " NoMethodError in Photo#create" for the "undefined method `save_photo'' for nil:NilClass". I''m still not understanding why this is not able to be found. I added "@photo = Photo.new" into Photo#create but this gives me what looks like a very similar error with the message: "undefined method `[]'' for #<File:C:/DOCUME~1/Michael/LOCALS~1/Temp/CGI3976.2>". I am still trying to work things out and struggle to understand the problem. Testing around some more I commented out the save_photo method call in the photo_controller.rb and it still gave me an error, but this time on the "save" method. It stumbles on the undefined local variable of photo, which I was worried about earlier. I''m not sure what kind of variable to use here, or what to use at all. If I make it an instance variable it gives me the "undefined method `[]'' for nil:NilClass" error again. Using "@params([''photo''][''image_url'']) sanitize_filename(@params([''photo''][''image'']))" gives even worse errors. Thanks for your help so far!
> Now that this change has been made I still do not write the file to the hard > drive. There continues to be a " NoMethodError in Photo#create" for the > "undefined method `save_photo'' for nil:NilClass". I''m still not understanding > why this is not able to be found. I added "@photo = Photo.new" into Photo#create > but this gives me what looks like a very similar error with the message: > "undefined method `[]'' for #<File:C:/DOCUME~1/Michael/LOCALS~1/Temp/CGI3976.2>". > I am still trying to work things out and struggle to understand the problem.You were headed in the right direction with the @photo = Photo.new; you definitely need that in there. The weird error you got there was caused by this: in the controller: @photo.save_photo(@params[''photo''][''image'']) in save_photo: photo[''image_url''] = sanitize_filename(photo[''image'']) You need to change the save_photo call to @photo.save_photo(@params[''photo'']) Tyler
Julian ''Julik'' Tarkhanov
2005-Jun-18  17:51 UTC
Re: Uploading Files - The classic problem once again
On 14-jun-2005, at 16:00, Tyler Kiley wrote:>> Now that this change has been made I still do not write the file >> to the hard >> drive. There continues to be a " NoMethodError in Photo#create" >> for the >> "undefined method `save_photo'' for nil:NilClass". I''m still not >> understanding >> why this is not able to be found. I added "@photo = Photo.new" >> into Photo#create >> but this gives me what looks like a very similar error with the >> message: >> "undefined method `[]'' for #<File:C:/DOCUME~1/Michael/LOCALS~1/ >> Temp/CGI3976.2>". >> I am still trying to work things out and struggle to understand >> the problem. >>The(yet unfinished) aproach I''ve taken for this problem for now - http://rafb.net/paste/results/U6xfGG50.html but you will need to refine it well -- Julian "Julik" Tarkhanov