Model
> rails g model Picture comment:string name:string content_type:string data:binary
migration file : same as on the book
picture.rb :
class Picture < ActiveRecord::Base
validates :content_type,
format: {
with: %r{^image},
message: '--- you can only upload pictures'
}
def uploaded_picture=(picture_field)
self.name = base_part_of(picture_field.original_filename)
self.content_type = picture_field.content_type.chomp
self.data = picture_field.read
end
private
def base_part_of(file_name)
File.basename(file_name).gsub(/[^\w._-]/, '')
end
end
Controller
> rails g controller Upload get save show picture
Edit routes.rb like below:
get "upload" => 'upload#get', as: :uploading
get "upload/:id" => 'upload#show', as: :uploaded
get "upload/:id/picture" => 'upload#picture', as: :picture_uploaded
post "upload" => 'upload#save', as: :uploading
Edit the controller :
class UploadController < ApplicationController
def get
@picture = Picture.new
end
def save
@picture = Picture.new(params[:picture])
if @picture.save
redirect_to(uploaded_url(@picture))
else
render action: 'get'
end
end
def show
@picture = Picture.find(params[:id])
end
def picture
@picture = Picture.find(params[:id])
send_data(@picture.data, filename: @picture.name, type: @picture.content_type, disposition: 'inline')
end
end
View
You can delete save.html.erb and picture.html.erb
get.html.erb
There is no need to add {multipart: true} since Rails 3.1 :
<% @picture.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
<%= form_for(@picture, url: uploading_path) do |form| %>
<%= form.label :comment %>: <%= form.text_field :comment %><br/>
<%= form.label :uploaded_picture, 'Upload your picture' %>: <%= form.file_field :uploaded_picture %><br/>
<%= form.submit 'Upload file' %>
<% end %>
show.html.erb :
<h3><%= @picture.comment %></h3>
<%= image_tag(picture_uploaded_path(@picture)) %>
No comments:
Post a Comment