how to store image in file system Ruby on Rails
Two models.
Assets - used to upload files with paperclip.
class AddAttachmentsPhotoToAsset < ActiveRecord::Migration
def self.up
add_column :assets, :photo_file_name, :string
add_column :assets, :photo_content_type, :string
add_column :assets, :photo_file_size, :integer
add_column :assets, :photo_updated_at, :datetime
end
Boards - a blog
class CreateBoards < ActiveRecord::Migration
def self.up
create_table :boards, :options => "AUTO_INCREMENT = 1000" do |t|
t.column :deliver_on, :datetime
t.column :time_zone, :string
t.column :header_text, :text
t.column :name, :string
t.column :age, :int, :default => "0"
t.column :template_id, :int, :default => "1", :null => false
t.column :photo, :string
t.timestamps
end
end
new.html.erb
There is an ajax iframe work around at the bottom of this form. The user can upload a picture and view it on the form before submitting it. Therefore there is no board that can be saved to upload the picture with. So I had to create the asset obje开发者_JAVA百科ct.
<% form_tag(action, :id => "form") do %>
<%=image_tag board_image, :width => 140, :height => 166, :id => 'user_image' %><%= hidden_field :board, :photo, :id => 'image_name'%>
<%= error_messages_for :user,:board, :header_message => "" %>
<%= label_tag :name, "Friend's Name:", :class => "large"%>
<%= text_field :board, "name", :class => "large", :style => Board::NAME_WIDTH %>
.
.
.
<%=submit_tag "#{button_text}", :id => "board_submit"%>
<% end %>
This has to be outside of the other form or it won't work so I have it here at the bottom after the <% end %> tag of the other form.
iframe ajax style file upload of a picture.
<% remote_form_for(:asset, :url => { :controller => "asset", :action => "upload", :id => @tmp_id }, :html => { :method => :post, :id => 'uploadForm', :multipart => true }) do |f| %>
<%= f.file_field :photo, :class => 'file' %>
<% end %>
upload.js
//ajax file upload
$(function() {
$("#uploadForm input").change(function(){
$("#uploadForm").ajaxSubmit({
beforeSubmit: function(a,f,o) {
o.dataType = "json";
},
complete: function(XMLHttpRequest, textStatus) {
$('#user_image').attr('src', XMLHttpRequest.responseText +'?'+ new Date().getTime());
$('#image_name').attr('value', XMLHttpRequest.responseText);
return; false;
},
});
});
});
In assets_controller.rb
def upload
if params_posted?(:asset) #check that the form was submitted with a post action
@asset = Asset.new(params[:asset]) #create new paperclip object to upload item
@asset.save #upload the photo
render :text => @asset.photo.url #put the name on the form.
end
end
In board_controller
def create
...
@board.new(params[:board])
...
end
File gets uploaded with assets object. File is stored in assets table in database photo url is stored in the hidden field on the form. Board is created and photo url is stored in the Boards table.
Thus I have stored photo data in two tables which does not seem correct.
I am a newbie, green as there ever was.
Is it better to store the asset.id of the Asset instance used to upload the images instead of the image url into the Board table?
To be clearer:
Should I have a field in my Boards table
t.column asset_id
and then access the assets photo data someway?
Thanks immensley in advance for your expertise.
Actually, why not just connect the attachments to your board model instead of having two separate models for them? are you using the assets for your other models? If not, it is better to just put the has_attachment in your board.rb model
I found the answer here
When I transfer the information from the @asset object to the board object.
In Board.rb I do as corroded suggested and add the paperclip item
has_attached_file :photo #I can also add styles, where I want to save the photo etc
So I don't think I need the boards photo from params. I create it from the url of the @asset.photo.url.
@board.photo = @asset.photo
When I do @board.save it will trigger all of the paperclip methods as if the file was being uploaded because they get triggered when the items are saved. So they will be copied from the temp location to where I want them to reside when I have a board. I then have to delete out the temp directories and the assest in the assets table as its done its job.
Update: It is all working perfectly now. I have corrected the code above.
important note!!!!!
you must do the following after you save the new model or the url and path values will be wrong.
model.photo.reprocess!
(replace model with your model.In my case it was @board.photo.reprocess!)
That is my final answer
精彩评论