简体   繁体   中英

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 object.

<% 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM