乐者为王

Do one thing, and do it well.

Rails 2.3和Paperclip实现无刷新异步上传文件

1
2
3
4
5
6
7
rails upload
cd upload
script/plugin install git://github.com/thoughtbot/paperclip.git
script/plugin install git://github.com/markcatley/responds_to_parent.git
script/generate scaffold user name:string
script/generate paperclip user avatar
rake db:migrate

在user.rb中增加:

1
2
3
4
5
  has_attached_file :avatar, :url => "/uploads/:basename.:extension"
  validates_attachment_presence :avatar
  validates_attachment_content_type :avatar,
    :content_type => ['image/jpeg', 'image/jpg', 'image/png']
  validates_attachment_size :avatar, :less_than => 1.megabytes

修改views/users/new.html.erb文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<% form_for(@user, :url => users_path(:format => 'js'),
      :html => { :id => 'upload_form', :multipart => true, :target => 'uframe' }) do |f| %>
  <%= f.error_messages %>

  <p>
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </p>
  <p>
    <%= f.label :avatar %><br />
    <%= f.file_field :avatar %>
    <div id="avatar">
    <% if @user.avatar.exists? %>
      <%= image_tag @user.avatar.url(:medium) %>
    <% end %>
    </div>
  </p>
  <p>
    <%= f.submit 'Create' %>
  </p>
<% end %>
<iframe id="uframe" name="uframe" style="display: none;"></iframe>

当点击submit按钮后,表单被提交到隐藏的iframe,相应的action被执行,执行结果会被返回给隐藏的iframe,我们需要上传后结果能返回到母窗口,这就是responds_to_parent插件提供的功能。

在views/layouts/user.html.erb中增加:

1
<%= javascript_include_tag :defaults %>

修改users_controller.rb中的create方法,增加:

1
2
3
4
5
6
7
8
9
format.js do
  flash[:notice] = 'avatar created'
  responds_to_parent do
    render :update do |page|
      page.replace_html :avatar, image_tag(@user.avatar.url(:medium))
      page['upload_form'].reset
    end
  end
end

Comments