zoukankan      html  css  js  c++  java
  • rails 上传附件

      今天做了个上传附件的功能,记录一下

           用的gem

    gem 'carrierwave'
    gem 'rmagick', '2.13.2'
    gem 'mime-types'

          关于这些gem都是什么作用这里就不做解释了,github中有介绍。执行bundle,期间会出现一些问题,install rmagick的时候会报错,原因貌似版本的问题。我的系统是ubuntu 12.0.4,解决方法

    1、sudo apt-get install libmagickwand-dev
    2、sudo gem install rmagick

          直接上代码吧,其实上传附件的情景有很多,image、pdf等等,这里我以imag为例。

    rails generate uploader Attachment

         有了carrierwave的gem包,创建一个uploader,这个uploader会跟普通的model有所区分。会生成一个attachment_uploader.rb的文件

    # encoding: utf-8
    
    class AttachmentUploader < CarrierWave::Uploader::Base
    
       include CarrierWave::RMagick
       include CarrierWave::MimeTypes
       #默认使用file系统
      storage :file
      #文件保持路径,这里就是用默认的
      def store_dir
        "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
      end
      #定依set_conditent_type的process
      process :set_content_type
      #定义thumb格式的style,可以通过rmagick来将上传的图片进行处理
      version :thumb, :if => :image? do 
        process :resize_to_fit => [50,50]
      end
      #同时定义一中thumb
      version :preview, :if => :image? do 
         process :resize_to_fit => [80,80]
      end
      #为了避免处理一些非image的附件
      def image?(file)
        file.content_type.include? 'image'
      end
    end      

       创建一个attachment的model

    rails g model attachment

             修改migration

    class CreateAttachments < ActiveRecord::Migration
      def change
        create_table :attachments do |t|
          t.string :file_name
          t.string :content_type
          t.string :attachmentable_type
          t.string :file_size
          t.integer :attachmentable_id
          t.string :attachment
    
          t.timestamps
        end
      end
    end

            需要指出的是这里用到了association中的多态方法,考虑到并不值一种model会有attachment,用多态最好了

    class Attachment < ActiveRecord::Base
      mount_uploader :attachment, AttachmentUploader
      attr_accessible :attachment, :attachmentable
      #多态 ==>attachmentable表示多种实体
      belongs_to :attachmentable, :polymorphic => true
      validates :attachmentable, :presence => true
      validates :attachment ,:presence => true
    
      before_save :set_attachment_attributes
    
    
      protected
      #设置附件的属性
      def set_attachment_attributes
          if attachment.present?  && attachment_changed?
              self.content_type = attachment.file.content_type
              self.file_size = attachment.file.size 
              self.file_name = attachment.file.original_filename
          end
      end
    end

             对应view中的_form.html.erb的局部模板

    <!--关键地方设置:html => {:multipart => true } -->
    <%= form_for(@base_info, :html => {:multipart => true}) do |f| %>
      <% if @base_info.errors.any? %>
        <div id="error_explanation">
          <h2><%= pluralize(@base_info.errors.count, "error") %> prohibited this base_info from being saved:</h2>
    
          <ul>
          <% @base_info.errors.full_messages.each do |msg| %>
            <li><%= msg %></li>
          <% end %>
          </ul>
        </div>
      <% end %>
    
      <div class="field">
        <%= f.label :name %><br />
        <%= f.text_field :name %>
      </div>
      <div class="field">
        <%= f.label :description %><br />
        <%= f.text_area :description %>
      </div>
      <!-- 添加一个<input type="file"> -->
      <div class="field">
        <label>logo</label>
        <%= file_field_tag :attachment %>
      </div>
      <div class="actions">
        <%= f.submit %>
      </div>
    <% end %>

      在对应的controller的create的方法中

    def create
        @base_info = BaseInfo.new(params[:base_info])
    
        respond_to do |format|
          if @base_info.save
            Attachment.create(:attachment => params[:attachment],
              :attachmentable => @base_info) if params[:attachment]
            format.html { redirect_to @base_info, notice: 'Base info was successfully created.' }
            format.json { render json: @base_info, status: :created, location: @base_info }
          else
            format.html { render action: "new" }
            format.json { render json: @base_info.errors, status: :unprocessable_entity }
          end
        end
      end

           在显示中就可以得到上传的图片了

    <% @base_info.attachments.each do |attachment| %>
          <%= image_tag attachment.attachment.thumb %>
          <%= image_tag attachment.attachment.url %>
          <%= image_tag attachment.attachment.preview %>
      <% end %>

          查看public就可以看到上传的图片,需要说明的是会有3套图片,因为使用了rmagick的gem。

    还可以用

  • 相关阅读:
    管道通信
    进程间的八种通信方式----共享内存是最快的 IPC 方式
    归并排序时间复杂度
    vector中的push_back函数的意思是什么
    如何实现android和服务器长连接
    android中实现service动态更新UI界面
    android中如何实现UI的实时更新---需要考虑电量和流量
    Map集合排序
    (二十一)自定义Tabbar
    (二十)首页内容详细【详细页】+ 评论 + 回复
  • 原文地址:https://www.cnblogs.com/itmangelihai/p/3065283.html
Copyright © 2011-2022 走看看