Kindeditor是一款国产的所见即所得的javascript富文本编辑器, 访问http://www.kindsoft.net获取更多信息rails_kindeditor可以帮助你的rails程序集成kindeditor,包括了图片和附件上传功能,文件按照类型、日期进行存储。
paperclip是一个简单的Active Record文件附件库,旨在尽可能的保持设置的简单性和对待文件就像对待其的属性一样简单,这意味着他们不能被保存到他们所在磁盘的最终位置上,并且如果设置为空的话他们也不能被删除,除非AcitveRecord::Base#save被取消。他管理着基于文件尺寸和存在,如果需要的话他能转化他的图像为缩略图,先决条件是和安装ImageMagick(他的大多数modern是基于Unix系统,是非常容易安装到正确的包)一样简单,附件被保存到文件系统并且在浏览器中能够很容易的理解,这是合理的并且是有用的。想要了解更多关于has_attached_file的文档请查看Paperclip::ClassMethods
原文:
1. 继续使用上一个项目,在gemfile文件中
#富文本编辑器 gem 'rails_kindeditor' #文件上传 gem 'paperclip'
2.执行bundle install
class CreateBooks < ActiveRecord::Migration def change create_table :books do |t| t.string :name t.string :author t.text :content t.timestamps end end end
rails generate rails_kindeditor:install
<%= simple_form_for(@book, html: {class: 'form-horizontal',id: 'book_form' }) do |f| %> <%= f.error_notification %> <div class="form-inputs"> <%= f.input :name %> <%= f.input :author %> <%= f.input :content, required: true, input_html: {required: true, class: 'span12'} %> </div> <div class="form-actions"> <%= f.button :submit %> </div> <% end %> <%= javascript_include_tag "books" %>
$ -> KindEditor.create '#book_content', "width":"80%", "height":300, "allowFileManager":true, "uploadJson":"/kindeditor/upload", "fileManagerJson":"/kindeditor/filemanager", "items":["fontname","fontsize","|","forecolor","hilitecolor","bold","italic","underline", "removeformat","|","justifyleft","justifycenter","justifyright","insertorderedlist", "insertunorderedlist","|","emoticons","image","link"]
//= require kindeditor/kindeditor
class CreateAttachments < ActiveRecord::Migration def change create_table :attachments do |t| t.integer :owner_id t.string :owner_type t.references :asset, index: true t.timestamps end end end
class CreateAssets < ActiveRecord::Migration def change create_table :assets do |t| t.string :asset_file_name t.integer :asset_file_size t.string :asset_content_type t.datetime :asset_updated_at t.timestamps end end end
class Attachment < ActiveRecord::Base belongs_to :owner, polymorphic: true belongs_to :asset, autosave: true end
class Asset < ActiveRecord::Base before_save :before_save_handler has_attached_file :asset, url: '/attachment/:attachment/:id/:style/:filename', path: ':rails_root/public/attachment/:attachment/:id/:style/:basename.:extension' private def before_save_handler file_name = self.asset_file_name.gsub!('.', '_') file_name[file_name.rindex('_')] = '.' self.asset_file_name = file_name end end
class Book < ActiveRecord::Base #附件 has_many :attachments, as: :owner, dependent: :delete_all, autosave: true has_many :assets, through: :attachments accepts_nested_attributes_for :assets, allow_destroy: true accepts_nested_attributes_for :attachments, allow_destroy: true end
show.html.erb:
<p id="notice"><%= notice %></p> <p> <strong>Name:</strong> <%= @book.name %> </p> <p> <strong>Author:</strong> <%= @book.author %> </p> <p> <strong>Content:</strong> <%= @book.content %> </p> <% if @book.assets.present? %> <div class="control-group"> <label class="control-label"><%= t 'simple_form.labels.defaults.attachment' %></label> <div class="controls"> <% @book.assets.each do |asset_field| %> <%= link_to asset_field.asset.url, target: '_blank' do %> <i class="icon-file"></i> <%= asset_field.asset.original_filename %> <% end %> <span style="display:inline-block;"><%= I18n.l(asset_field.created_at, format: :long) %></span> <br> <% end %> </div> </div> <% end %> <%= link_to 'Edit', edit_book_path(@book) %> | <%= link_to 'Back', books_path %>
<h1 style="margin-left: 50px">New book</h1> <%= simple_form_for(@book, html: {class: 'form-horizontal',id: 'book_form', multipart: true }) do |f| %> <%= f.error_notification %> <div class="form-inputs" style="margin-left: 50px"> <%= f.input :name %> <%= f.input :author %> <%= f.input :content, required: true, input_html: {required: true, class: 'span12'} %> <br> <div class="control-group text required book_content"> <label for="book_content" class="text required control-label"> <%= t 'simple_form.labels.defaults.attachment' %> </label> <div class="controls"> <input type="file" name="book[assets_attributes][][asset]" autocomplete="off" class="attachment"> </div> </div> </div> <div class="form-actions"> <%= f.button :submit %> </div> <% end %> <%= link_to 'Back', books_path %>
<%= javascript_include_tag "books" %> <%= javascript_include_tag "jquery.MultiFile" %> <%= javascript_include_tag "common/attachment" %>
在这里使用多个附件上传的页面必须要有 multipart: true,不然会报错。
# Never trust parameters from the scary internet, only allow the white list through. def book_params params.require(:book).permit(:name, :author, :content, assets_attributes: [:asset, :id]) end
12.下载jquery.MultiFile.js文件,复制到public/javascripts/jquery.MultiFile.js。新建assets/javascripts/common/attachment.coffee文件
$ -> $(':file.attachment').MultiFile({ STRING: remove: "<i class='icon-remove'></i>" selected:'选择文件: $file' denied:'不允许上传 $ext类型的文件,请重新选择' duplicate:'该文件已经选择了:\n$file' accept: 'gif|jpg|png|bmp|swf|doc|docx|xls|xlsx|ppt|pptx|mp3|mp4|rar|zip|txt|tif|pdf|rb' onFileSelect: (element, value, master_element) -> return true })
13.在config/locales/下新建zh-CN.yml文件
zh-CN: views: pagination: first: "«" last: "»" previous: "‹ " next: "›" truncate: "..." datetime: distance_in_words: half_a_minute: "半分钟" less_than_x_seconds: one: "一秒内" other: "少于 %{count} 秒" x_seconds: one: "一秒" other: "%{count} 秒" less_than_x_minutes: one: "一分钟内" other: "少于 %{count} 分钟" x_minutes: one: "一分钟" other: "%{count} 分钟" about_x_hours: one: "大约一小时" other: "大约 %{count} 小时" x_hours: one: "1 小时" other: "%{count} 小时" x_days: one: "一天" other: "%{count} 天" about_x_months: one: "大约一个月" other: "大约 %{count} 个月" x_months: one: "一个月" other: "%{count} 个月" about_x_years: one: "大约一年" other: "大约 %{count} 年" over_x_years: one: "超过一年" other: "超过 %{count} 年" almost_x_years: one: "将近 1 年" other: "将近 %{count} 年" date: formats: # Use the strftime parameters for formats. # When no format has been given, it uses default. # You can provide other formats here if you like! default: "%Y-%m-%d" short: "%b%d日" long: "%Y年%b%d日" day_names: [星期天, 星期一, 星期二, 星期三, 星期四, 星期五, 星期六] abbr_day_names: [日, 一, 二, 三, 四, 五, 六] # Don't forget the nil at the beginning; there's no such thing as a 0th month month_names: [~, 一月, 二月, 三月, 四月, 五月, 六月, 七月, 八月, 九月, 十月, 十一月, 十二月] abbr_month_names: [~, 1月, 2月, 3月, 4月, 5月, 6月, 7月, 8月, 9月, 10月, 11月, 12月] # Used in date_select and datime_select. order: - :year - :month - :day time: formats: default: "%Y年%b%d日 %H:%M:%S %A" time: "%H:%M" short: "%b%d日 %H:%M" long: "%Y年%b%d日 %H:%M:%S" day: "%Y年%b%d日" am: "上午" pm: "下午" label_added_time_by: "由 %{author} 在 %{age} 之前添加" label_updated_time: " 更新于 %{value} 之前" label_updated_time_by: "由 %{author} 更新于 %{age} 之前" label_submited_time_by: "由 %{author} 提交于 %{age} 之前"
get 'attachment/:attachment/:id/:style/:filename' => 'assets#download'
新建book
查看book
16.查看更多信息请参考
17.项目文档将在后面的文章中给出。