Hello dear Programmers,
I'm trying to develop a web application with the ebook "Praxiswissen - Ruby on Rails". My problem is that I want to save Images through a form to my project directory. The database just saves the name of the pictures with the saving time:
def unique_and_proper_filename(filename)
Time.now.to_i.to_s + '_' + File.basename(filename)
end
My problem is that my pictures dont get saved after submitting my form. I dont get some exceptions, thats why I dont know where my issue is.
Controller:
class PostsController < ApplicationController
require 'will_paginate'
def new
@post = Post.new
end
# information about saving the picture
def create
@post = Post.new(params[:post].permit(:title, :description, :date, :image_file, :thumbnail_file))
# Form isn't correctly filled message
if [email protected]?
flash.now[:notice] = "Bitte füllen Sie alle Felder aus und überprüfen Sie Ihre Angaben."
render(:action => :new)
# Files weren't saved message
elsif [email protected]_files
flash.now[:notice] = "Es trat ein Fehler beim Hochladen der Dateien auf."
render(:action => :new)
# Files saved correctly message
else
@post.save
flash[:notice] = "Dateien wurden hochgeladen und die Daten wurden gespeichert."
redirect_to(:action => :list)
end
end
# list action for listing my pictures
def list
@posts = Post.paginate(:page => params[:page], :order => "date DESC", :per_page => 15)
@post_pages = Post.paginate(:page => params[:page], :order => "date DESC", :per_page => 15)
end
end
HTML Form:
<h2>Neues Foto anlegen</h2>
<%= form_tag({:action => :create}, :multipart => true) %>
<h3>Bilddaten</h3>
<p>
Titel<br/>
<%= text_field(:post, :title) %>
</p>
<p>
Beschreibungen<br/>
<%= text_field(:post, :description) %>
</p>
<p>
Datum und Uhrzeit<br/>
<%= datetime_select(:post, :date, :order => [:day, :month, :year, :hour]) %>
</p>
<p>
<h3>Datei-Upload</h3>
<p>
Bilddatei:<br/>
<%= file_field(:post, :image_file) %>
</p>
<p>
Thumbnail:<br/>
<%= file_field(:post, :thumbnail_file) %>
</p>
<%= submit_tag("Speichern") %>
</p>
</form>
Model:
class Post < ActiveRecord::Base
validates_presence_of(:title, :description, :date, :image, :thumbnail)
I18n.enforce_available_locales = false
def image_file= (fileobj)
if fileobj.size > 0
@image_file = fileobj
self.image = unique_and_proper_filename(fileobj.original_filename)
end
end
def thumbnail_file= (fileobj)
if fileobj.size > 0
@thumbnail_file = fileobj
self.thumbnail = unique_and_proper_filename(fileobj.original_filename)
end
end
def save_files
# Bilddatei save
if !save_uploaded_file(@image_file, IMAGE_DIR, self.image)
return false
end
# Thumbnail save
if !save_uploaded_file(@thumbnail_file, THUMBNAIL_DIR, self.thumbnail)
return false
end
end
private
def unique_and_proper_filename(filename)
Time.now.to_i.to_s + "_" + File.basename(filename)
end
private
def save_uploaded_file(fileobj, filepath, filename)
# Complete Path
complete_path = Rails.root + "/public/" + filepath
# if neccessary, create directory
FileUtils.mkdir_p(complete_path) unless File.exists?(complete_path)
# save data
begin
f = File.open(complete_path + "/" + filename, "wb")
f.write(fileobj.read)
rescue
return false
ensure
f.close unless f.nil?
end
end
end
I'm only getting the message that there went something wrong with saving the files when i fill the form correctly but it should return a message that says that my file were saved.
I'm sorry for that massive length of my question but I really dont know where my issue is... If there's a need for more information or code, I will add it as fast as I can.
Thank you very much in advance!
Paperclip has since been deprecated, it is recommended you use Rails' own Active Storage.
I'm sorry but I'll only be able to recommend what we use:
Paperclip
I appreciate you're using a tutorial, but I'd highly recommend using the Paperclip gem for this
This handles ALL the heavy lifting for you:
#GemFile
gem "paperclip", "~> 4.1.1"
Model
#app/models/post.rb
Class Post < ActiveRecord::Base
has_attached_file :image
end
#migration
add_attachment :posts, :image
Controller
#app/controllers/posts_controller.rb
def new
@post = Post.new
end
def create
@post = Post.new(post_params)
end
private
def post_params
params.require(:post).permit(:image, :other, :params)
end
View
#app/views/posts/new.html.erb
<%= form_for @post do |f| %>
<%= f.file_field :image %>
<% end %>
I'm lucky to tell that I found my issue. My save_files
method in my Post
model doesn't returned true
..
I post this answer because maybe someone could use this question as an answer for his own problem. Here's where I added my return true
:
def save_files
# Bilddatei save
if !save_uploaded_file(@image_file, IMAGE_DIR, self.image)
return false
end
# Thumbnail save
if !save_uploaded_file(@thumbnail_file, THUMBNAIL_DIR, self.thumbnail)
return false
end
return true # <--------- Need to be added!
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With